diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 7ae4e2d56..8c7ce1943 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,24 +1,17 @@ Contributing to the Joomla Component Builder (JCB) =============== -You are welcome to submit a contribution for review and possible inclusion in the Joomla Component Builder but, before it will be accepted, we ask that you follow these simple steps: +If you wish to submit a contribution for review and potential inclusion in the Joomla Component Builder (JCB), please follow these simple steps: -1) Please watch [these tutorials][Tutorials] +1) Open an issue on GitHub, and if possible, provide a fix and create a pull request (PR). Creating a PR automatically generates an issue so that you do not need to create one separately. -2) Open an issue on GitHub. If you can, please provide a fix and create a pull request (PR) instead; this will automatically create an issue for you so you do not have to create an issue if you are creating a pull request. +2) Adhere to the [Joomla! Coding Standards](https://developer.joomla.org/coding-standards.html). -3) Follow the [Joomla! Coding Standards][Standards]. +3) When filing an issue or opening a PR, provide a clear and concise title and description. The title should include a brief summary of the issue and reference to an open issue if possible. For example, Invalid Query in com_admin (Ref #1234) is sufficient. Additionally, provide a detailed description of the issue or PR, including what the problem is, what the PR is addressing, testing instructions, and environmental information such as PHP version and database driver and version, in case the issue is specific to certain environments. -4) When filing an issue or opening a PR, please include a clear title and description. The title should be a short summary of an issue and, if possible, should include a reference to an open issue. For example, `Invalid Query in com_admin (Ref #1234)` would be sufficient. All issues and PRs should include a description with as much detail as possible. -If it is a PR, include what the issue is, what the PR is addressing, testing instructions and environmental information (PHP version, database driver and version, and other data you can retrieve from your site's system information view) in case the issue is specific to certain environments. If additional information is needed, please be prepared to provide it as our community members review your submission. +4) Report security issues to the JCB! Core Team using the [Report security issues contact form](https://www.vdm.io/report-security-issues) instead of using public forums. -5) Report security issues to the JCB! Core Team using the [Report security issues contact form][Security]. Please do not use the public forums for security issues. - -Please be patient as not all items will be tested immediately (remember, all bug testing for the JCB is done by volunteers) and be receptive to feedback about your code. +Please be patient, as not all items will be immediately tested since all bug testing for the JCB is performed by volunteers. Additionally, be open to feedback regarding your code. #### Branches -PRs should usually be made to the `staging` branch as this contains the most recent version of the code. - -[Tutorials]: https://www.youtube.com/watch?v=lLOfx9YA7VQ&list=PLQRGFI8XZ_wsfz3NdKawCiYsALuZ-GhwJ -[Standards]: https://developer.joomla.org/coding-standards.html\ -[Security]: http://joomlacomponentbuilder.com/report-security-issues +For PRs, submit to the staging branch as it contains the most up-to-date version of the code. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index 905f46fc1..1d8b13a8f 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -1,27 +1,22 @@ Where can you get support and help? ==================== -+ [The JCB Tutorials][Tutorials] -+ [Hello World Tutorial][HelloWorld] -+ [The JCB! Wiki][Wiki] -+ [JCB Forum][forum] -+ [Report a Security Issue][Security] -+ [Community Complaint][Complaint] -+ [Open Issue On Github][Issue] ^^ +- [Package](https://git.vdm.dev/joomla/pkg-component-builder). +- [Download](https://git.vdm.dev/joomla/pkg-component-builder/archive/master.zip). +- [Tutorials](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE). +- [German](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7). +- [Hello World](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45). +- [Discussions](https://github.com/vdm-io/Joomla-Component-Builder/discussions). +- [Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki). +- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). ^^ +- [Issues Stream](https://t.me/jcb_issues). +- [Updates](https://t.me/jcb_updates). +- [User Group](https://t.me/jcb_group). +- [Announcement](https://t.me/Joomla_component_builder). +- [Beta](https://git.vdm.dev/joomla-beta/pkg-component-builder). +- [Nightly Build](https://git.vdm.dev/joomla-beta/pkg-component-builder/archive/master.zip). +- [Community Complaint](https://www.joomlacomponentbuilder.com/community-complaint). +- [Security](https://www.vdm.io/report-security-issues). -Since JCB has become a community project [VDM.io][VDM] is **no longer solely responsible** for support. - -We have started a [**JCB forum**][forum] where you can post questions, about how things work, or if you need some kind of help in relation to your development of your components. - -^^ Then if you run into any issues, related to the JCB code, like bugs, **start by searching** the (*open & closed*) [issues][Issue] over on Github, and if the issue has not been mentioned before, **then only** open a new issue, following the [community guidelines][guidelines]. - -[Tutorials]: https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE -[HelloWorld]: https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45 -[Wiki]: https://git.vdm.dev/joomla/Component-Builder/wiki -[forum]: https://vdm.bz/jcb-forum -[Security]: http://joomlacomponentbuilder.com/report-security-issues -[Complaint]: http://joomlacomponentbuilder.com/community-complaint -[Issue]: https://git.vdm.dev/joomla/Component-Builder/issues -[VDM]: https://www.vdm.io/joomla-component-builder -[guidelines]: https://git.vdm.dev/joomla/Component-Builder/src/branch/master/.github/CONTRIBUTING.md +^^ Then if you run into any issues, related to the [JCB](https://git.vdm.dev/joomla/Component-Builder/issues) code, like bugs, **start by searching** the (*open & closed*) issues over on [Gitea](https://git.vdm.dev/joomla/Component-Builder/issues), and if the issue has not been mentioned before, **then only** open a new issue, following the [community guidelines](https://git.vdm.dev/joomla/Component-Builder/src/branch/master/.github/CONTRIBUTING.md). diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..1bcc73892 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,61 @@ +# v3.1.28 + +- Updates PHPSecLib. +- Fixed connection failure to remote server. +- Adds overriding of back-folder and git-folder on component level. + +# v3.1.27 + +- Adds better remote repository management for the super power features. +- Fixes #1014 so that powers are added to components. + +# v3.1.26 + +- Fixed changelog direction so newest changes is listed at top of the file. +- Finished the init function of super powers. +- Adds rest function inside super power. +- Adds super powers to all templates. +- Updates many helper class methods to now use the utility classes. +- Adds the `spl_autoload_register` method to the component entry file (as-well). +- Moved most methods from the compiler fields class to powers. #955 +- Refactored many new builder classes from the registry class. +- Converted the Content class to two builder classes. +- Adds option to add additional templates to a module. +- Resolves #1002 by adding STRING instead of WORD. +- Ported the FOF encryption class into Powers. https://git.vdm.dev/joomla/fof +- Changed all CSS and JS to use `JHtml::_(` instead of `$this->document->` in compiler code. +- Adds option to turn jQuery off if UIKIT 3 is added. +- Adds option to auto write injection boilerplate code in Powers area. +- Adds option to auto write service provider boilerplate code in the Powers area. +- Improved the `getDynamicContent` method and all banner locations to fetch from https://git.vdm.dev/joomla/jcb-external/ instead. +- Major stability improvements all over the new powers complier classes. +- New [base Registry class](https://git.vdm.dev/joomla/super-powers/src/branch/master/src/7e822c03-1b20-41d1-9427-f5b8d5836af7) has been created specially for JCB. +- Remember to update all plug-ins with this version update (use the package). + +# v3.1.24 + +- Fix the update server #978 issue. +- Fixed the change log to load all entries, not just the last one. +- Fixed #983 so that database updates are created when adding a new adminview +- Moved a few builder arrays to the Compiler Registry +- Adds super powers to JCB +- Adds Gitea API library +- Improves Power filters +- Fix #991 to add the Utilities service class +- Adds Superpower Key (SPK) replacement feature +- Adds Superpower search (GREP) feature +- Adds Power Insert/Update Classes +- Fix #995 that all update sites are using the correct URL + +# v3.1.19 + +- We fixed #972 so that custom code (in the header) will be added after the power namespaces +- We added a message to show when a server move failed +- We fixed the BaseConfig to not use '_' as separator +- We fixed the footable loading issue +- We removed the need for passing placeholders by reference +- We added the option to generate a CHANGELOG +- We fixed the server class to load new client if server details changed. +- We fixed the readme placeholder issue #978. +- We fixed the empty server url issue #978. +- Fixed Package import to now use the phplibsec version 3 \ No newline at end of file diff --git a/README.md b/README.md index 8d145a9f3..1ec22857e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Joomla Component Builder ([JCB](http://joomlacomponentbuilder.com)) +# Joomla Component Builder ([JCB](https://www.joomlacomponentbuilder.com)) This is a [Joomla 3.x](https://extensions.joomla.org/extension/component-builder/) component. [__See In Action__](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.4) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.28) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -23,8 +23,8 @@ Some of the Features + Add you [own dashboard](https://www.youtube.com/watch?v=tU7TeYn1Djo&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=60) in the back-end. + [Dynamic File and Folder](https://www.youtube.com/watch?v=_c7wzW075lA&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=56) Inclusion concept. + [Easy Translation](https://www.youtube.com/watch?v=q5NwKGnOHoQ&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=51) via excel. -+ Adding your [own rule validation](https://www.youtube.com/watch?v=Z6-ggKtX35o&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=46) to a field in [JCB](http://joomlacomponentbuilder.com) -+ [Automated backup system](https://www.youtube.com/watch?v=GUWZaODo_IM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=40) in [JCB](http://joomlacomponentbuilder.com). ++ Adding your [own rule validation](https://www.youtube.com/watch?v=Z6-ggKtX35o&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=46) to a field in [JCB](https://www.joomlacomponentbuilder.com) ++ [Automated backup system](https://www.youtube.com/watch?v=GUWZaODo_IM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=40) in [JCB](https://www.joomlacomponentbuilder.com). + Adding mySQL Dump to any View/Table. + Grab existing Table data and build a dynamic dump. + Unlimited [Joomla](https://extensions.joomla.org/extension/component-builder/) Components. @@ -83,13 +83,13 @@ You are in Control + You can dynamically add internal help structures to all component. + There is no limitations on how big or how much you want to build (server limitation only). + This is a complete factory kind of component that functions like a deployment hub. -+ Export any component completely mapped in [JCB](http://joomlacomponentbuilder.com) and import into another [JCB](http://joomlacomponentbuilder.com). ++ Export any component completely mapped in [JCB](https://www.joomlacomponentbuilder.com) and import into another [JCB](https://www.joomlacomponentbuilder.com). + This and much much more are all possible with this component builder! Get More Demo Content ==================== -> You can now get access to the WOW factor, [JCB](http://joomlacomponentbuilder.com) fully mapped can now be yours! Including many other [JCB](http://joomlacomponentbuilder.com) mapped components. +> You can now get access to the WOW factor, [JCB](https://www.joomlacomponentbuilder.com) fully mapped can now be yours! Including many other [JCB](https://www.joomlacomponentbuilder.com) mapped components. ### All you need to do is [explained here](https://vdm.bz/how-to-get-free-vdm-package-keys)! @@ -99,18 +99,22 @@ To install these packages [watch this tutorial](https://vdm.bz/how-to-install-jc Where can you get support and help? ==================== -+ [The JCB Tutorials](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [German Basic Introduction](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7) -+ [Hello World Tutorial](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) -+ [The JCB! Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki) -+ [Forum](https://vdm.bz/jcb-forum) -+ [Report a Security Issue](http://joomlacomponentbuilder.com/report-security-issues) -+ [Community Complaint](http://joomlacomponentbuilder.com/community-complaint) -+ [Open Issue On Gitea](https://git.vdm.dev/joomla/Component-Builder/issues) ^^ - -Since [JCB](http://joomlacomponentbuilder.com) has [become a community](https://git.vdm.dev/joomla/Component-Builder/src/branch/master/.github/SUPPORT.md) project [VDM.io](https://www.vdm.io/) is **no longer solely responsible** for support. - -We have started a [**JCB forum**](https://vdm.bz/jcb-forum) where you can post questions, about how things work, or if you need some kind of help in relation to your development of your components. +- [Package](https://git.vdm.dev/joomla/pkg-component-builder). +- [Download](https://git.vdm.dev/joomla/pkg-component-builder/archive/master.zip). +- [Tutorials](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE). +- [German](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7). +- [Hello World](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45). +- [Discussions](https://github.com/vdm-io/Joomla-Component-Builder/discussions). +- [Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki). +- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). ^^ +- [Issues Stream](https://t.me/jcb_issues). +- [Updates](https://t.me/jcb_updates). +- [User Group](https://t.me/jcb_group). +- [Announcement](https://t.me/Joomla_component_builder). +- [Beta](https://git.vdm.dev/joomla-beta/pkg-component-builder). +- [Nightly Build](https://git.vdm.dev/joomla-beta/pkg-component-builder/archive/master.zip). +- [Community Complaint](https://www.joomlacomponentbuilder.com/community-complaint). +- [Security](https://www.vdm.io/report-security-issues). ^^ Then if you run into any issues, related to the [JCB](https://git.vdm.dev/joomla/Component-Builder/issues) code, like bugs, **start by searching** the (*open & closed*) issues over on [Gitea](https://git.vdm.dev/joomla/Component-Builder/issues), and if the issue has not been mentioned before, **then only** open a new issue, following the [community guidelines](https://git.vdm.dev/joomla/Component-Builder/src/branch/master/.github/CONTRIBUTING.md). @@ -125,14 +129,14 @@ Our idea was to almost let this tool serve as a cheat sheet to how things can be MAKING IT BETTER! ==================== -Get involved on the forums, and the Gitea issues, and you can even help us develop/improve the pipeline of [JCB](http://joomlacomponentbuilder.com) for continues delivery. We really want to see [JCB](http://joomlacomponentbuilder.com) remain the tool of choice for all [Joomla Component Development](https://extensions.joomla.org/extension/component-builder/) needs and ideas. +Get involved on the forums, and the Gitea issues, and you can even help us develop/improve the pipeline of [JCB](https://www.joomlacomponentbuilder.com) for continues delivery. We really want to see [JCB](https://www.joomlacomponentbuilder.com) remain the tool of choice for all [Joomla Component Development](https://extensions.joomla.org/extension/component-builder/) needs and ideas. TODO ====== -- Add automatic unit testing. To nurture pipeline integration for all components build with [JCB](http://joomlacomponentbuilder.com). -- Team collaborative development across [JCB](http://joomlacomponentbuilder.com) installations offline and online. -- Documentation (maintained by the community) for [JCB](http://joomlacomponentbuilder.com). (help us select the best system for this) +- Add automatic unit testing. To nurture pipeline integration for all components build with [JCB](https://www.joomlacomponentbuilder.com). +- Team collaborative development across [JCB](https://www.joomlacomponentbuilder.com) installations offline and online. +- Documentation (maintained by the community) for [JCB](https://www.joomlacomponentbuilder.com). (help us select the best system for this) # Build Details @@ -140,17 +144,17 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io) + *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 9th July, 2022 -+ *Version*: 3.1.4 ++ *Last Build*: 24th October, 2023 ++ *Version*: 3.1.28 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **311349** -+ *Field count*: **2002** -+ *File count*: **2050** -+ *Folder count*: **349** ++ *Line count*: **635155** ++ *Field count*: **2047** ++ *File count*: **4731** ++ *Folder count*: **436** -> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). -> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) +> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com). +> Developed by [Llewellyn van der Merwe](mailto:joomla@vdm.io) ## Contributors diff --git a/admin/README.txt b/admin/README.txt index 8d145a9f3..1ec22857e 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -1,5 +1,5 @@ -# Joomla Component Builder ([JCB](http://joomlacomponentbuilder.com)) +# Joomla Component Builder ([JCB](https://www.joomlacomponentbuilder.com)) This is a [Joomla 3.x](https://extensions.joomla.org/extension/component-builder/) component. [__See In Action__](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.4) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.28) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -23,8 +23,8 @@ Some of the Features + Add you [own dashboard](https://www.youtube.com/watch?v=tU7TeYn1Djo&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=60) in the back-end. + [Dynamic File and Folder](https://www.youtube.com/watch?v=_c7wzW075lA&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=56) Inclusion concept. + [Easy Translation](https://www.youtube.com/watch?v=q5NwKGnOHoQ&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=51) via excel. -+ Adding your [own rule validation](https://www.youtube.com/watch?v=Z6-ggKtX35o&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=46) to a field in [JCB](http://joomlacomponentbuilder.com) -+ [Automated backup system](https://www.youtube.com/watch?v=GUWZaODo_IM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=40) in [JCB](http://joomlacomponentbuilder.com). ++ Adding your [own rule validation](https://www.youtube.com/watch?v=Z6-ggKtX35o&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=46) to a field in [JCB](https://www.joomlacomponentbuilder.com) ++ [Automated backup system](https://www.youtube.com/watch?v=GUWZaODo_IM&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=0s&index=40) in [JCB](https://www.joomlacomponentbuilder.com). + Adding mySQL Dump to any View/Table. + Grab existing Table data and build a dynamic dump. + Unlimited [Joomla](https://extensions.joomla.org/extension/component-builder/) Components. @@ -83,13 +83,13 @@ You are in Control + You can dynamically add internal help structures to all component. + There is no limitations on how big or how much you want to build (server limitation only). + This is a complete factory kind of component that functions like a deployment hub. -+ Export any component completely mapped in [JCB](http://joomlacomponentbuilder.com) and import into another [JCB](http://joomlacomponentbuilder.com). ++ Export any component completely mapped in [JCB](https://www.joomlacomponentbuilder.com) and import into another [JCB](https://www.joomlacomponentbuilder.com). + This and much much more are all possible with this component builder! Get More Demo Content ==================== -> You can now get access to the WOW factor, [JCB](http://joomlacomponentbuilder.com) fully mapped can now be yours! Including many other [JCB](http://joomlacomponentbuilder.com) mapped components. +> You can now get access to the WOW factor, [JCB](https://www.joomlacomponentbuilder.com) fully mapped can now be yours! Including many other [JCB](https://www.joomlacomponentbuilder.com) mapped components. ### All you need to do is [explained here](https://vdm.bz/how-to-get-free-vdm-package-keys)! @@ -99,18 +99,22 @@ To install these packages [watch this tutorial](https://vdm.bz/how-to-install-jc Where can you get support and help? ==================== -+ [The JCB Tutorials](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [German Basic Introduction](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7) -+ [Hello World Tutorial](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) -+ [The JCB! Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki) -+ [Forum](https://vdm.bz/jcb-forum) -+ [Report a Security Issue](http://joomlacomponentbuilder.com/report-security-issues) -+ [Community Complaint](http://joomlacomponentbuilder.com/community-complaint) -+ [Open Issue On Gitea](https://git.vdm.dev/joomla/Component-Builder/issues) ^^ - -Since [JCB](http://joomlacomponentbuilder.com) has [become a community](https://git.vdm.dev/joomla/Component-Builder/src/branch/master/.github/SUPPORT.md) project [VDM.io](https://www.vdm.io/) is **no longer solely responsible** for support. - -We have started a [**JCB forum**](https://vdm.bz/jcb-forum) where you can post questions, about how things work, or if you need some kind of help in relation to your development of your components. +- [Package](https://git.vdm.dev/joomla/pkg-component-builder). +- [Download](https://git.vdm.dev/joomla/pkg-component-builder/archive/master.zip). +- [Tutorials](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE). +- [German](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wu0tDFxJtZFwW7AxA4JHQV7). +- [Hello World](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45). +- [Discussions](https://github.com/vdm-io/Joomla-Component-Builder/discussions). +- [Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki). +- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). ^^ +- [Issues Stream](https://t.me/jcb_issues). +- [Updates](https://t.me/jcb_updates). +- [User Group](https://t.me/jcb_group). +- [Announcement](https://t.me/Joomla_component_builder). +- [Beta](https://git.vdm.dev/joomla-beta/pkg-component-builder). +- [Nightly Build](https://git.vdm.dev/joomla-beta/pkg-component-builder/archive/master.zip). +- [Community Complaint](https://www.joomlacomponentbuilder.com/community-complaint). +- [Security](https://www.vdm.io/report-security-issues). ^^ Then if you run into any issues, related to the [JCB](https://git.vdm.dev/joomla/Component-Builder/issues) code, like bugs, **start by searching** the (*open & closed*) issues over on [Gitea](https://git.vdm.dev/joomla/Component-Builder/issues), and if the issue has not been mentioned before, **then only** open a new issue, following the [community guidelines](https://git.vdm.dev/joomla/Component-Builder/src/branch/master/.github/CONTRIBUTING.md). @@ -125,14 +129,14 @@ Our idea was to almost let this tool serve as a cheat sheet to how things can be MAKING IT BETTER! ==================== -Get involved on the forums, and the Gitea issues, and you can even help us develop/improve the pipeline of [JCB](http://joomlacomponentbuilder.com) for continues delivery. We really want to see [JCB](http://joomlacomponentbuilder.com) remain the tool of choice for all [Joomla Component Development](https://extensions.joomla.org/extension/component-builder/) needs and ideas. +Get involved on the forums, and the Gitea issues, and you can even help us develop/improve the pipeline of [JCB](https://www.joomlacomponentbuilder.com) for continues delivery. We really want to see [JCB](https://www.joomlacomponentbuilder.com) remain the tool of choice for all [Joomla Component Development](https://extensions.joomla.org/extension/component-builder/) needs and ideas. TODO ====== -- Add automatic unit testing. To nurture pipeline integration for all components build with [JCB](http://joomlacomponentbuilder.com). -- Team collaborative development across [JCB](http://joomlacomponentbuilder.com) installations offline and online. -- Documentation (maintained by the community) for [JCB](http://joomlacomponentbuilder.com). (help us select the best system for this) +- Add automatic unit testing. To nurture pipeline integration for all components build with [JCB](https://www.joomlacomponentbuilder.com). +- Team collaborative development across [JCB](https://www.joomlacomponentbuilder.com) installations offline and online. +- Documentation (maintained by the community) for [JCB](https://www.joomlacomponentbuilder.com). (help us select the best system for this) # Build Details @@ -140,17 +144,17 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io) + *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 9th July, 2022 -+ *Version*: 3.1.4 ++ *Last Build*: 24th October, 2023 ++ *Version*: 3.1.28 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **311349** -+ *Field count*: **2002** -+ *File count*: **2050** -+ *Folder count*: **349** ++ *Line count*: **635155** ++ *Field count*: **2047** ++ *File count*: **4731** ++ *Folder count*: **436** -> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). -> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) +> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com). +> Developed by [Llewellyn van der Merwe](mailto:joomla@vdm.io) ## Contributors diff --git a/admin/access.xml b/admin/access.xml index 1e51d294b..37dfadbef 100644 --- a/admin/access.xml +++ b/admin/access.xml @@ -19,7 +19,6 @@ - @@ -235,7 +234,6 @@ - @@ -485,6 +483,8 @@ + + @@ -498,6 +498,10 @@ + + + + @@ -515,7 +519,6 @@ - diff --git a/admin/assets/css/search.css b/admin/assets/css/search.css new file mode 100644 index 000000000..56b77adcf --- /dev/null +++ b/admin/assets/css/search.css @@ -0,0 +1,40 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* CSS Document */ + +.selected { + background-color:#d7d8db !important +} +tr.selected td { + background-color:#d7d8db !important +} +#search_settings_block .controls { + margin-left: 1px !important; +} +tr { + cursor:pointer +} +.found_code { + color: #46a546; + font-weight: bolder; +} +.search_details_title { + font-size: large; + font-weight: bolder; +} +.small_column { + padding: 2px; + text-align: center; +} +th.small_column { + padding: 2px !important; + text-align: center !important; +} diff --git a/admin/assets/images/icons/admin_view_add.png b/admin/assets/images/icons/admin_view_add.png deleted file mode 100644 index 38b7209f5..000000000 Binary files a/admin/assets/images/icons/admin_view_add.png and /dev/null differ diff --git a/admin/assets/images/icons/custom_admin_view_add.png b/admin/assets/images/icons/custom_admin_view_add.png deleted file mode 100644 index cb35345f6..000000000 Binary files a/admin/assets/images/icons/custom_admin_view_add.png and /dev/null differ diff --git a/admin/assets/images/icons/placeholders.png b/admin/assets/images/icons/placeholders.png index dae19113e..e05f4a723 100644 Binary files a/admin/assets/images/icons/placeholders.png and b/admin/assets/images/icons/placeholders.png differ diff --git a/admin/assets/images/icons/search.png b/admin/assets/images/icons/search.png new file mode 100644 index 000000000..dae19113e Binary files /dev/null and b/admin/assets/images/icons/search.png differ diff --git a/admin/assets/images/icons/site_view_add.png b/admin/assets/images/icons/site_view_add.png deleted file mode 100644 index 97a8ce39e..000000000 Binary files a/admin/assets/images/icons/site_view_add.png and /dev/null differ diff --git a/admin/assets/js/search.js b/admin/assets/js/search.js new file mode 100644 index 000000000..1433d72ed --- /dev/null +++ b/admin/assets/js/search.js @@ -0,0 +1,956 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* JS Document */ +/** + * JS Function to execute the search + */ +const doSearch = async (signal, tables) => { + try { + // build form + const formData = new FormData(); + + // load the result table + const resultsTable = new DataTable('#search_results_table'); + + // get the search mode + let typeSearch = modeObject.querySelector('input[type=\'radio\']:checked').value; + + // set some search values + let searchValue = searchObject.value; + let replaceValue = replaceObject.value; + let matchValue = matchObject.checked ? 1 : 0; + let wholeValue = wholeObject.checked ? 1 : 0; + let regexValue = regexObject.checked ? 1 : 0; + + // add the form data + formData.append('table_name', ''); + formData.append('type_search', typeSearch); + formData.append('search_value', searchValue); + formData.append('replace_value', replaceValue); + formData.append('match_case', matchValue); + formData.append('whole_word', wholeValue); + formData.append('regex_search', regexValue); + + // update the URL + updateUrlQuery(searchValue, replaceValue, matchValue, wholeValue, regexValue, typeSearch); + + let abort_this_search_values = false; + + // reset the progress bar + searchProgressBarObject.style.width = '0%'; + searchProgressBarObject.innerHTML = '0%'; + + // show the progress bar + searchProgressObject.style.display = ''; + + // hidde the search button + startSearchButton.style.display = 'none'; + + // show the stop search button + stopSearchButton.style.display = ''; + + // start search timer + startSearchTimer(); + + // reset our global counters + fieldCount = 0; + lineCount = 0; + + // set our local counters + let total = 0; + let progress = tables.length; + let index; + + for (index = 0; index < progress; index++) { + + let tableName = tables[index]; + + // add the table name + formData.set('table_name', tableName); + + let options = { + signal: signal, + method: 'POST', // *GET, POST, PUT, DELETE, etc. + body: formData + } + + if (abort_this_search_values) { + break; + } + const response = await fetch(UrlAjax + 'doSearch', options).then(response => { + total++; + // return the json response + if (response.ok) { + return response.json(); + } else { + UIkit.notify(Joomla.JText._('COM_COMPONENTBUILDER_THE_SEARCH_PROCESS_HAD_AN_ERROR_WITH_TABLE') + ' ' + tableName, {pos:'top-right', status:'danger'}); + } + }).then((data) => { + if (typeof data.success !== 'undefined') { + UIkit.notify(data.success, {pos:'top-right', timeout : 200, status:'success'}); + //} else if (typeof data.not_found !== 'undefined') { + // UIkit.notify(data.not_found, {pos:'bottom-right', timeout : 200}); + } + if (typeof data.items !== 'undefined') { + addTableItems(resultsTable, data.items, typeSearch); + } + if (typeof data.fields_count !== 'undefined') { + fieldCount += data.fields_count; + } + if (typeof data.line_count !== 'undefined') { + lineCount += data.line_count; + } + // calculate the percent + let percent = 100.0 * (total / progress); + // update the progress bar + searchProgressObject.style.display = ''; // always make sure it still shows... + searchProgressBarObject.style.width = percent.toFixed(2) + '%'; + searchProgressBarObject.innerHTML = percent.toFixed(2) + '%'; + // when complete hide the progress bar + if (progress == total) { + let total_field_line = ' ' + fieldCount + ' ' + Joomla.JText._('COM_COMPONENTBUILDER_FIELDS_THAT_HAD') + ' ' + lineCount + ' ' + Joomla.JText._('COM_COMPONENTBUILDER_LINES') + ' '; + if (progress == 1) { + searchProgressBarObject.innerHTML = Joomla.JText._('COM_COMPONENTBUILDER_SEARCHING') + ' ' + tableName + total_field_line + Joomla.JText._('COM_COMPONENTBUILDER_AND_FINISHED_THE_SEARCH_IN') + ' ' + getSearchLenght() + ' ' + Joomla.JText._('COM_COMPONENTBUILDER_SECONDS'); + } else { + searchProgressBarObject.innerHTML = Joomla.JText._('COM_COMPONENTBUILDER_SEARCHING') + ' ' + progress + ' ' + Joomla.JText._('COM_COMPONENTBUILDER_TABLES_WITH') + total_field_line + Joomla.JText._('COM_COMPONENTBUILDER_AND_FINISHED_THE_SEARCH_IN') + ' ' + getSearchLenght() + ' ' + Joomla.JText._('COM_COMPONENTBUILDER_SECONDS'); + } + // show the search button + startSearchButton.style.display = ''; + // hidde the stop search button + stopSearchButton.style.display = 'none'; + setTimeout(function () { + // hide the progress bar again + searchProgressObject.style.display = 'none'; + }, 13000); + } + }).catch(error => { + console.log(error); + if (error.name === "AbortError") { + abort_this_search_values = true; + } + }); + } + } catch (error) { + console.log(error); + } finally { + // Executed regardless if we caught the error + } +}; + + +/** + * JS Function to start search timer + */ +const startSearchTimer = () => { + startSearchTime = new Date(); +}; + +/** + * JS Function to get search lenght + */ +const getSearchLenght = () => { + // set ending time + endSearchTime = new Date(); + + // get diff in ms + var timeDiff = endSearchTime - startSearchTime; + + // strip the ms + timeDiff /= 1000; + + // get seconds + return Math.round(timeDiff); +}; + +/** + * JS Function to fetch selected item + */ +const getSelectedItem = async (table, row, field, line) => { + try { + // get the search mode + let mode = modeObject.querySelector('input[type=\'radio\']:checked').value; + + // build form + const formData = new FormData(); + + formData.append('field_name', field); + formData.append('row_id', row); + formData.append('table_name', table); + formData.append('search_value', searchObject.value); + formData.append('replace_value', replaceObject.value); + formData.append('match_case', matchObject.checked ? 1 : 0); + formData.append('whole_word', wholeObject.checked ? 1 : 0); + formData.append('regex_search', regexObject.checked ? 1 : 0); + + // get search value + if (mode == 2) { + // add the line value + formData.append('line_nr', line); + // calling URL + postURL = UrlAjax + 'getReplaceValue'; + } else { + // calling URL + postURL = UrlAjax + 'getSearchValue'; + } + + let options = { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + body: formData + } + + const response = await fetch(postURL, options).then(response => { + if (response.ok) { + return response.json(); + } + }).then((data) => { + if (typeof data.success !== 'undefined') { + UIkit.notify(data.success, {pos:'top-right', status:'success'}); + } + if (typeof data.value !== 'undefined') { + addSelectedItem(data.value, table, row, field, line); + } + }).catch(error => { + console.log(error); + }); + } catch (error) { + console.log(error); + } finally { + // Executed regardless if we caught the error + } +}; + +/** + * JS Function to check if we should save/update the all current found items + */ +const replaceAllCheck = () => { + // get the current searc and replace values + let searchValue = searchObject.value; + let replaceValue = replaceObject.value; + // load question + let question = Joomla.JText._('COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_BALLB_VALUES_THAT_CAN_BE_FOUND_IN_THE_DATABASE') + '
' + + Joomla.JText._('COM_COMPONENTBUILDER_YOU_WILL_REPLACE') + ': [' + htmlentities(searchValue) + '] ' + + Joomla.JText._('COM_COMPONENTBUILDER_WITH') + ': [' + htmlentities(replaceValue) + ']
' + + Joomla.JText._('COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_BYOU_HAVE_BEEN_WARNEDB') + '

' + + Joomla.JText._('COM_COMPONENTBUILDER_ARE_YOU_THEREFORE_ABSOLUTELY_SURE_YOU_WANT_TO_CONTINUE'); + // do check + UIkit.modal.confirm(question, function () { + + // show the search settings again + showSearch(); + + // Create new controller and issue new request + controller_replace = new AbortController(); + + // check if any specific table was set + let tables = []; + let table = tableObject.value; + if (table != -1) { + tables.push(table); + replaceAll(controller_replace.signal, tables); + } else { + replaceAll(controller_replace.signal, searchTables); + } + }, {labels: { Ok: Joomla.JText._('COM_COMPONENTBUILDER_YES_UPDATE_ALL'), Cancel: Joomla.JText._('COM_COMPONENTBUILDER_NO') }}); +}; + +/** + * JS Function to execute the search + */ +const replaceAll = async (signal, tables) => { + try { + // build form + const formData = new FormData(); + + // get the search mode + let typeSearch = modeObject.querySelector('input[type=\'radio\']:checked').value; + + // set some search values + let searchValue = searchObject.value; + let replaceValue = replaceObject.value; + let matchValue = matchObject.checked ? 1 : 0; + let wholeValue = wholeObject.checked ? 1 : 0; + let regexValue = regexObject.checked ? 1 : 0; + + // add the form data + formData.append('table_name', ''); + formData.append('type_search', typeSearch); + formData.append('search_value', searchValue); + formData.append('replace_value', replaceValue); + formData.append('match_case', matchValue); + formData.append('whole_word', wholeValue); + formData.append('regex_search', regexValue); + + // reset the progress bar + replaceProgressBarObject.style.width = '0%'; + + // show the progress bar + replaceProgressObject.style.display = ''; + + let abort_this_replace_values = false; + + let total = 0; + let progress = tables.length; + let index; + + for (index = 0; index < progress; index++) { + + let tableName = tables[index]; + + // add the table name + formData.set('table_name', tableName); + + let options = { + signal: signal, + method: 'POST', // *GET, POST, PUT, DELETE, etc. + body: formData + } + + if (abort_this_replace_values) { + break; + } + const response = await fetch(UrlAjax + 'replaceAll', options).then(response => { + total++; + if (response.ok) { + return response.json(); + } else { + UIkit.notify(Joomla.JText._('COM_COMPONENTBUILDER_THE_REPLACE_PROCESS_HAD_AN_ERROR_WITH_TABLE') + ' ' + tableName, {pos:'top-right', status:'danger'}); + } + }).then((data) => { + if (typeof data.success !== 'undefined') { + UIkit.notify(data.success, {pos:'top-right', timeout : 200, status:'success'}); + } else if (typeof data.error !== 'undefined') { + UIkit.notify(data.error, {pos:'bottom-right', timeout : 200}); + } + // calculate the percent + let percent = 100.0 * (total / progress); + // update the progress bar + replaceProgressBarObject.style.width = percent.toFixed(2) + '%'; + // when complete hide the progress bar + if (progress == total) { + setTimeout(function () { + // hide the progress bar again + replaceProgressObject.style.display = 'none'; + // we clear the table again + clearAll(); + // if not reqex we reverse the search for you so you can see the update was a success + if (regexValue == 0) { + // set the replace value as the search value + UIkit.modal.confirm(Joomla.JText._('COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_DO_A_REVERSE_SEARCH'), function(){ + startNewSearch(replaceValue, searchValue, matchValue, wholeValue, regexValue, 2); + }, function () { + UIkit.modal.confirm(Joomla.JText._('COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_REPEAT_THE_SAME_SEARCH'), function(){ + startSearch(); + }, function () { + clearSearch(); + }, {labels: { Ok: Joomla.JText._('COM_COMPONENTBUILDER_YES'), Cancel: Joomla.JText._('COM_COMPONENTBUILDER_NO') }}); + }, {labels: { Ok: Joomla.JText._('COM_COMPONENTBUILDER_YES'), Cancel: Joomla.JText._('COM_COMPONENTBUILDER_NO') }}); + } else { + // else we search it again just to prove its changed + UIkit.modal.confirm(Joomla.JText._('COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_REPEAT_THE_SAME_SEARCH'), function(){ + startSearch(); + }, function () { + clearSearch(); + }, {labels: { Ok: Joomla.JText._('COM_COMPONENTBUILDER_YES'), Cancel: Joomla.JText._('COM_COMPONENTBUILDER_NO') }}); + } + }, 3000); + } + }).catch(error => { + console.log(error); + if (error.name === "AbortError") { + abort_this_replace_values = true; + } + }); + } + } catch (error) { + console.log(error); + } finally { + // Executed regardless if we caught the error + } +}; + +/** + * JS Function to check if we should save/update the current selected item + */ +const setValueCheck = (row, field, table) => { + // load question + let question = Joomla.JText._('COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_ROW') + ' (' + row + ') -> (' + field + ') ' + + Joomla.JText._('COM_COMPONENTBUILDER_FIELD_IN_THE') + ' (' + table + ') ' + Joomla.JText._('COM_COMPONENTBUILDER_TABLE') + '.

' + + Joomla.JText._('COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE'); + // do check + UIkit.modal.confirm(question, function () { + setValue(row, field, table); + }, {labels: { Ok: Joomla.JText._('COM_COMPONENTBUILDER_YES'), Cancel: Joomla.JText._('COM_COMPONENTBUILDER_NO') }}); +}; + +/** + * JS Function to set the current selected item + */ +const setValue = async (row, field, table) => { + try { + // get the value from the editor + let value = editorObject.getValue(); + + // build form + const formData = new FormData(); + + formData.append('value', value); + formData.append('row_id', row); + formData.append('field_name', field); + formData.append('table_name', table); + + let options = { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + body: formData + } + + const response = await fetch(UrlAjax + 'setValue', options).then(response => { + if (response.ok) { + return response.json(); + } + }).then((data) => { + if (typeof data.success !== 'undefined') { + UIkit.notify(data.success, {pos:'top-right', status:'success'}); + clearSelectedItem(); + tableActiveObject.remove().draw(); + } + }).catch(error => { + console.log(error); + }); + } catch (error) { + console.log(error); + } finally { + // Executed regardless if we caught the error + } +}; + +/** + * JS Function to add item to the editor + */ +const addSelectedItem = async (value, table, row, field, line) => { + // display area + if (value.length > 1) + { + // add value to editor + editorObject.setValue(value); + + // set item details notice area + itemNoticeObject.style.display = ''; + itemEditButtonObject.innerHTML = editButtonSelected; + itemTableNameObject.innerHTML = table; + itemRowIdObject.innerHTML = row; + itemFieldNameObject.innerHTML = field; + itemLineNumberObject.innerHTML = line; + // set button and editor line if we have a line number + if (typeof line == 'number') { + // show and set the save button + buttonUpdateItemObject.style.display = ''; + buttonUpdateItemObject.setAttribute('onclick',"setValueCheck(" + row + ", '" + field + "', '" + table + "');"); + + // get top of the code line + let top = editorObject.charCoords({line: line, ch: 0}, "local").top; + // scroll to the line + editorObject.scrollTo(null, top - 12); + // select the line + editorObject.setCursor(line - 1); + } else { + // no line so no data we can't save this data + buttonUpdateItemObject.setAttribute('onclick', ""); + buttonUpdateItemObject.style.display = 'none'; + } + } +}; + +/** + * JS Function to clear item from the editor and hide it + */ +const clearSelectedItem = async () => { + // display area + editorObject.setValue(''); + // clear notice area + itemNoticeObject.style.display = 'none'; + itemEditButtonObject.innerHTML = '...'; + itemTableNameObject.innerHTML = '...'; + itemRowIdObject.innerHTML = '...'; + itemFieldNameObject.innerHTML = '...'; + itemLineNumberObject.innerHTML = '...'; + // clear update button + buttonUpdateItemObject.setAttribute('onclick', ''); +}; + +/** + * JS Function to clear table items + */ +const clearTableItems = async () => { + let table = new DataTable('#search_results_table'); + // clear search + table.search('').columns().search( '' ); + // clear items + table.clear().draw( true ); + + // hide the update all items + buttonUpdateAllStyleDisplay('none'); +}; + +/** + * JS Function to clear all details of the search + */ +const clearAll = async () => { + // clear all details + clearTableItems(); + clearSelectedItem(); + searchedObject.innerHTML = '....'; +}; + +/** + * JS Function to clear the search and replace values + */ +const clearSearch = async () => { + // clear the search and replace values + searchObject.value = ''; + replaceObject.value = ''; +}; + +/** + * JS Function to set the search and replace values + */ +const startNewSearch = async (search, replace = '', match = 0, whole = 0, regex = 0, mode = 1) => { + // redirect to a new search + window.location.href = getSearchURL(search, replace, match, whole, regex, mode); +}; + +/** + * JS Function to update the URL of the browser with the search query + */ +const updateUrlQuery = async (search, replace = '', match = 0, whole = 0, regex = 0, mode = 1) => { + // update the url query + window.history.pushState({}, '', getSearchURL(search, replace, match, whole, regex, mode)); +}; + +/** + * JS Function to get the current search URL + */ +const getSearchURL = (search, replace = '', match = 0, whole = 0, regex = 0, mode = 1) => { + // check if its a single table search + let table = tableObject.value; + let table_name = ''; + if (table != -1) { + table_name = '&table_name=' + urlencode(table); + } + // update the type of search + if (mode == 1) { + return UrlSearch + table_name + + '&search_value=' + urlencode(search) + + '&type_search=1&match_case=' + match + + '&whole_word=' + whole + + '®ex_search=' + regex; + } else if (mode == 2) { + return UrlSearch + table_name + + '&search_value=' + urlencode(search) + + '&replace_value=' + urlencode(replace) + + '&type_search=2&match_case=' + match + + '&whole_word=' + whole + + '®ex_search=' + regex; + } + return UrlSearch + table_name; +}; + +/** + * JS Function to check if a element has a class + */ + const hasClass = (elementObject, classNaam) => { + return !!elementObject.className.match(new RegExp('(\\s|^)' + classNaam + '(\\s|$)')); +}; + +/** + * JS Function add a class from an element + */ +const addClass = (elementObject, classNaam) => { + if (!hasClass(elementObject, classNaam)) { + elementObject.className += " " + classNaam; + } +}; + +/** + * JS Function remove a class from an element + */ +const removeClass = (elementObject, classNaam) => { + if (hasClass(elementObject, classNaam)) { + var reg = new RegExp('(\\s|^)' + classNaam + '(\\s|$)'); + elementObject.className = elementObject.className.replace(reg, ' '); + } +}; + +/** + * JS Function to add items to the table + */ +const addTableItems = async (table, items, typeSearch) => { + table.rows.add(items).draw( false ); + if (typeSearch == 2) { + buttonUpdateAllStyleDisplay(''); // TODO should only show once all items are loaded + } else { + buttonUpdateAllStyleDisplay('none'); // TODO should only show once all items are loaded + } +}; + +/** + * JS Function to update the update all button + */ +const buttonUpdateAllStyleDisplay = async (value) => { + buttonUpdateAllObject.forEach((buttonObject) => { + buttonObject.style.display = value; + }); +}; + +/** + * JS Function to execute (A) on search/replace text change , (B) on search options changes + */ +const startSearch = (field, forced = false) => { + // check mode + let mode = modeObject.querySelector('input[type=\'radio\']:checked').value; + if (mode == 0) { + // reset the search area + window.location.href = UrlSearch; + } + // check if we have an Enter click + if (field && typeof field.code !== 'undefined' && field.code === "Enter") { + forced = true; + } + // get replace value if set + const replaceValue = replaceObject.value; + if (replaceValue.length > 0) { + // set the searched value + replacedObject.innerHTML = htmlentities(replaceValue); + } else { + replacedObject.innerHTML = ''; + } + // get search value + const searchValue = searchObject.value; + if (searchValue.length > 2 || (searchValue.length > 0 && forced)) { + // Cancel any ongoing requests + if (controller) controller.abort(); + + // we clear the table again + clearAll(); + + // set the searched value + searchedObject.innerHTML = htmlentities(searchValue); + + // Create new controller and issue new request + controller = new AbortController(); + + // check if any specific table was set + let tables = []; + let table = tableObject.value; + if (table != -1) { + tables.push(table); + doSearch(controller.signal, tables); + } else { + doSearch(controller.signal, searchTables); + } + } else { + // Clear the table + clearAll(); + } +}; + +/** + * JS Function to stop a search + */ +const stopSearch = () => { + // Cancel any ongoing requests + if (controller) controller.abort(); + // show the search button + startSearchButton.style.display = ''; + // hidde the stop search button + stopSearchButton.style.display = 'none'; + // remove the progress bar at some point + setTimeout(function () { + // hide the progress bar again + searchProgressObject.style.display = 'none'; + }, 13000); +} + +/** + * JS Function to hide search settings and show table search + */ +const showSearch = () => { + searchSettingsObject.style.display = ''; + searchDetailsObject.style.display = 'none'; + replaceDetailsObject.style.display = 'none'; + tableSearchObject.style.display = 'none'; + tableLengthObject.style.display = 'none'; +}; + +/** + * JS Function to show search settings and hide table search + */ +const hideSearch = () => { + searchSettingsObject.style.display = 'none'; + searchDetailsObject.style.display = ''; + tableSearchObject.style.display = ''; + tableLengthObject.style.display = ''; + // check if we are in replace mode + let mode = modeObject.querySelector('input[type=\'radio\']:checked').value; + if (mode == 2) { + replaceDetailsObject.style.display = ''; + } +}; + + +function htmlentities(string, quoteStyle, charset, doubleEncode) { + // discuss at: https://locutus.io/php/htmlentities/ + // original by: Kevin van Zonneveld (https://kvz.io) + // revised by: Kevin van Zonneveld (https://kvz.io) + // revised by: Kevin van Zonneveld (https://kvz.io) + // improved by: nobbler + // improved by: Jack + // improved by: RafaƂ Kukawski (https://blog.kukawski.pl) + // improved by: Dj (https://locutus.io/php/htmlentities:425#comment_134018) + // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman) + // bugfixed by: Brett Zamir (https://brett-zamir.me) + // input by: Ratheous + // note 1: function is compatible with PHP 5.2 and older + // example 1: htmlentities('Kevin & van Zonneveld') + // returns 1: 'Kevin & van Zonneveld' + // example 2: htmlentities("foo'bar","ENT_QUOTES") + // returns 2: 'foo'bar' + const hashMap = getHtmlTranslationTable('HTML_ENTITIES', quoteStyle) + string = string === null ? '' : string + '' + if (!hashMap) { + return false + } + if (quoteStyle && quoteStyle === 'ENT_QUOTES') { + hashMap["'"] = ''' + } + doubleEncode = doubleEncode === null || !!doubleEncode + const regex = new RegExp('&(?:#\\d+|#x[\\da-f]+|[a-zA-Z][\\da-z]*);|[' + + Object.keys(hashMap) + .join('') + // replace regexp special chars + .replace(/([()[\]{}\-.*+?^$|/\\])/g, '\\$1') + ']', + 'g') + return string.replace(regex, function (ent) { + if (ent.length > 1) { + return doubleEncode ? hashMap['&'] + ent.substr(1) : ent + } + return hashMap[ent] + }) +} + +function getHtmlTranslationTable(table, quoteStyle) { // eslint-disable-line camelcase + // discuss at: https://locutus.io/php/get_html_translation_table/ + // original by: Philip Peterson + // revised by: Kevin van Zonneveld (https://kvz.io) + // bugfixed by: noname + // bugfixed by: Alex + // bugfixed by: Marco + // bugfixed by: madipta + // bugfixed by: Brett Zamir (https://brett-zamir.me) + // bugfixed by: T.Wild + // improved by: KELAN + // improved by: Brett Zamir (https://brett-zamir.me) + // input by: Frank Forte + // input by: Ratheous + // note 1: It has been decided that we're not going to add global + // note 1: dependencies to Locutus, meaning the constants are not + // note 1: real constants, but strings instead. Integers are also supported if someone + // note 1: chooses to create the constants themselves. + // example 1: get_html_translation_table('HTML_SPECIALCHARS') + // returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'} + + const entities = {} + const hashMap = {} + let decimal + const constMappingTable = {} + const constMappingQuoteStyle = {} + let useTable = {} + let useQuoteStyle = {} + + // Translate arguments + constMappingTable[0] = 'HTML_SPECIALCHARS' + constMappingTable[1] = 'HTML_ENTITIES' + constMappingQuoteStyle[0] = 'ENT_NOQUOTES' + constMappingQuoteStyle[2] = 'ENT_COMPAT' + constMappingQuoteStyle[3] = 'ENT_QUOTES' + + useTable = !isNaN(table) + ? constMappingTable[table] + : table + ? table.toUpperCase() + : 'HTML_SPECIALCHARS' + + useQuoteStyle = !isNaN(quoteStyle) + ? constMappingQuoteStyle[quoteStyle] + : quoteStyle + ? quoteStyle.toUpperCase() + : 'ENT_COMPAT' + + if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') { + throw new Error('Table: ' + useTable + ' not supported') + } + + entities['38'] = '&' + if (useTable === 'HTML_ENTITIES') { + entities['160'] = ' ' + entities['161'] = '¡' + entities['162'] = '¢' + entities['163'] = '£' + entities['164'] = '¤' + entities['165'] = '¥' + entities['166'] = '¦' + entities['167'] = '§' + entities['168'] = '¨' + entities['169'] = '©' + entities['170'] = 'ª' + entities['171'] = '«' + entities['172'] = '¬' + entities['173'] = '­' + entities['174'] = '®' + entities['175'] = '¯' + entities['176'] = '°' + entities['177'] = '±' + entities['178'] = '²' + entities['179'] = '³' + entities['180'] = '´' + entities['181'] = 'µ' + entities['182'] = '¶' + entities['183'] = '·' + entities['184'] = '¸' + entities['185'] = '¹' + entities['186'] = 'º' + entities['187'] = '»' + entities['188'] = '¼' + entities['189'] = '½' + entities['190'] = '¾' + entities['191'] = '¿' + entities['192'] = 'À' + entities['193'] = 'Á' + entities['194'] = 'Â' + entities['195'] = 'Ã' + entities['196'] = 'Ä' + entities['197'] = 'Å' + entities['198'] = 'Æ' + entities['199'] = 'Ç' + entities['200'] = 'È' + entities['201'] = 'É' + entities['202'] = 'Ê' + entities['203'] = 'Ë' + entities['204'] = 'Ì' + entities['205'] = 'Í' + entities['206'] = 'Î' + entities['207'] = 'Ï' + entities['208'] = 'Ð' + entities['209'] = 'Ñ' + entities['210'] = 'Ò' + entities['211'] = 'Ó' + entities['212'] = 'Ô' + entities['213'] = 'Õ' + entities['214'] = 'Ö' + entities['215'] = '×' + entities['216'] = 'Ø' + entities['217'] = 'Ù' + entities['218'] = 'Ú' + entities['219'] = 'Û' + entities['220'] = 'Ü' + entities['221'] = 'Ý' + entities['222'] = 'Þ' + entities['223'] = 'ß' + entities['224'] = 'à' + entities['225'] = 'á' + entities['226'] = 'â' + entities['227'] = 'ã' + entities['228'] = 'ä' + entities['229'] = 'å' + entities['230'] = 'æ' + entities['231'] = 'ç' + entities['232'] = 'è' + entities['233'] = 'é' + entities['234'] = 'ê' + entities['235'] = 'ë' + entities['236'] = 'ì' + entities['237'] = 'í' + entities['238'] = 'î' + entities['239'] = 'ï' + entities['240'] = 'ð' + entities['241'] = 'ñ' + entities['242'] = 'ò' + entities['243'] = 'ó' + entities['244'] = 'ô' + entities['245'] = 'õ' + entities['246'] = 'ö' + entities['247'] = '÷' + entities['248'] = 'ø' + entities['249'] = 'ù' + entities['250'] = 'ú' + entities['251'] = 'û' + entities['252'] = 'ü' + entities['253'] = 'ý' + entities['254'] = 'þ' + entities['255'] = 'ÿ' + } + + if (useQuoteStyle !== 'ENT_NOQUOTES') { + entities['34'] = '"' + } + if (useQuoteStyle === 'ENT_QUOTES') { + entities['39'] = ''' + } + entities['60'] = '<' + entities['62'] = '>' + + // ascii decimals to real symbols + for (decimal in entities) { + if (entities.hasOwnProperty(decimal)) { + hashMap[String.fromCharCode(decimal)] = entities[decimal] + } + } + + return hashMap +} + + +function urlencode (str) { + // discuss at: https://locutus.io/php/urlencode/ + // original by: Philip Peterson + // improved by: Kevin van Zonneveld (https://kvz.io) + // improved by: Kevin van Zonneveld (https://kvz.io) + // improved by: Brett Zamir (https://brett-zamir.me) + // improved by: Lars Fischer + // improved by: Waldo Malqui Silva (https://fayr.us/waldo/) + // input by: AJ + // input by: travc + // input by: Brett Zamir (https://brett-zamir.me) + // input by: Ratheous + // bugfixed by: Kevin van Zonneveld (https://kvz.io) + // bugfixed by: Kevin van Zonneveld (https://kvz.io) + // bugfixed by: Joris + // reimplemented by: Brett Zamir (https://brett-zamir.me) + // reimplemented by: Brett Zamir (https://brett-zamir.me) + // note 1: This reflects PHP 5.3/6.0+ behavior + // note 1: Please be aware that this function + // note 1: expects to encode into UTF-8 encoded strings, as found on + // note 1: pages served as UTF-8 + // example 1: urlencode('Kevin van Zonneveld!') + // returns 1: 'Kevin+van+Zonneveld%21' + // example 2: urlencode('https://kvz.io/') + // returns 2: 'https%3A%2F%2Fkvz.io%2F' + // example 3: urlencode('https://www.google.nl/search?q=Locutus&ie=utf-8') + // returns 3: 'https%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3DLocutus%26ie%3Dutf-8' + str = (str + '') + return encodeURIComponent(str) + .replace(/!/g, '%21') + .replace(/'/g, '%27') + .replace(/\(/g, '%28') + .replace(/\)/g, '%29') + .replace(/\*/g, '%2A') + .replace(/~/g, '%7E') + .replace(/%20/g, '+') +} \ No newline at end of file diff --git a/admin/compiler/joomla_3/AdminController.php b/admin/compiler/joomla_3/AdminController.php index 34a6d3228..98c6d9aeb 100644 --- a/admin/compiler/joomla_3/AdminController.php +++ b/admin/compiler/joomla_3/AdminController.php @@ -47,4 +47,4 @@ class ###Component###Controller###Views### extends AdminController { return parent::getModel($name, $prefix, $config); }###CONTROLLEREXIMPORTMETHOD######CUSTOM_ADMIN_DYNAMIC_BUTTONS_CONTROLLER######ADMIN_CUSTOM_BUTTONS_CONTROLLER_LIST### -} +} \ No newline at end of file diff --git a/admin/compiler/joomla_3/BaseController_import.php b/admin/compiler/joomla_3/BaseController_import.php index 9a13dbd18..504c266f2 100644 --- a/admin/compiler/joomla_3/BaseController_import.php +++ b/admin/compiler/joomla_3/BaseController_import.php @@ -17,8 +17,7 @@ defined('_JEXEC') or die('Restricted access'); // No direct access to this file defined('_JEXEC') or die('Restricted access'); -use Joomla\CMS\MVC\Controller\BaseController; -use Joomla\Utilities\ArrayHelper; +###IMPORT_CONTROLLER_HEADER### /** * ###Component### Import Base Controller diff --git a/admin/compiler/joomla_3/BaseController_import_custom.php b/admin/compiler/joomla_3/BaseController_import_custom.php index a4474ba5e..dbe424603 100644 --- a/admin/compiler/joomla_3/BaseController_import_custom.php +++ b/admin/compiler/joomla_3/BaseController_import_custom.php @@ -17,8 +17,7 @@ defined('_JEXEC') or die('Restricted access'); // No direct access to this file defined('_JEXEC') or die('Restricted access'); -use Joomla\CMS\MVC\Controller\BaseController; -use Joomla\Utilities\ArrayHelper; +###IMPORT_CUSTOM_CONTROLLER_HEADER### /** * ###Component### ###View### Base Controller diff --git a/admin/compiler/joomla_3/BaseDatabaseModel_import.php b/admin/compiler/joomla_3/BaseDatabaseModel_import.php index 7d7b21a68..f7501c7ec 100644 --- a/admin/compiler/joomla_3/BaseDatabaseModel_import.php +++ b/admin/compiler/joomla_3/BaseDatabaseModel_import.php @@ -17,13 +17,9 @@ defined('_JEXEC') or die('Restricted access'); // No direct access to this file defined('_JEXEC') or die('Restricted access'); -use Joomla\CMS\MVC\Model\BaseDatabaseModel; -use Joomla\CMS\Filesystem\File; -use Joomla\CMS\Filesystem\Folder; -use Joomla\Utilities\ArrayHelper; -use PhpOffice\PhpSpreadsheet\IOFactory; +###IMPORT_MODEL_HEADER### -/** +/*** * ###Component### Import Base Database Model */ class ###Component###ModelImport extends BaseDatabaseModel diff --git a/admin/compiler/joomla_3/BaseDatabaseModel_import_custom.php b/admin/compiler/joomla_3/BaseDatabaseModel_import_custom.php index 43d0c526f..19be712eb 100644 --- a/admin/compiler/joomla_3/BaseDatabaseModel_import_custom.php +++ b/admin/compiler/joomla_3/BaseDatabaseModel_import_custom.php @@ -17,11 +17,7 @@ defined('_JEXEC') or die('Restricted access'); // No direct access to this file defined('_JEXEC') or die('Restricted access'); -use Joomla\CMS\MVC\Model\BaseDatabaseModel; -use Joomla\CMS\Filesystem\File; -use Joomla\CMS\Filesystem\Folder; -use Joomla\Utilities\ArrayHelper; -use PhpOffice\PhpSpreadsheet\IOFactory; +###IMPORT_CUSTOM_MODEL_HEADER### /** * ###Component### ###View### Base Database Model diff --git a/admin/compiler/joomla_3/CHANGELOG.md b/admin/compiler/joomla_3/CHANGELOG.md new file mode 100644 index 000000000..def8704dd --- /dev/null +++ b/admin/compiler/joomla_3/CHANGELOG.md @@ -0,0 +1 @@ +###CHANGELOG### \ No newline at end of file diff --git a/admin/compiler/joomla_3/Helper.php b/admin/compiler/joomla_3/Helper.php index 12ed53087..ded32f2d4 100644 --- a/admin/compiler/joomla_3/Helper.php +++ b/admin/compiler/joomla_3/Helper.php @@ -26,14 +26,14 @@ abstract class ###Component###Helper { /** * Composer Switch - * + * * @var array */ protected static $composer = array(); /** * The Main Active Language - * + * * @var string */ public static $langTag;###ADMIN_GLOBAL_EVENT_HELPER######CUSTOM_HELPER_SCRIPT######BOTH_CUSTOM_HELPER_SCRIPT### @@ -47,7 +47,7 @@ abstract class ###Component###Helper if (!isset(self::$composer[$target])) { // get the function name - $functionName = self::safeString('compose' . $target); + $functionName = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe('compose' . $target); // check if method exist if (method_exists(__CLASS__, $functionName)) { @@ -69,7 +69,7 @@ abstract class ###Component###Helper /** * Joomla version object - */ + */ protected static $JVersion; /** @@ -78,7 +78,7 @@ abstract class ###Component###Helper public static function jVersion() { // check if set - if (!self::checkObject(self::$JVersion)) + if (!Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check(self::$JVersion)) { self::$JVersion = new JVersion(); } @@ -116,8 +116,8 @@ abstract class ###Component###Helper $link_front = ''; $link_back = ''; } - $contributors[$nr]['title'] = self::htmlEscape($params->get("titleContributor".$nr)); - $contributors[$nr]['name'] = $link_front.self::htmlEscape($params->get("nameContributor".$nr)).$link_back; + $contributors[$nr]['title'] = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($params->get("titleContributor".$nr)); + $contributors[$nr]['name'] = $link_front.Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($params->get("nameContributor".$nr)).$link_back; } } return $contributors; @@ -135,7 +135,7 @@ abstract class ###Component###Helper }###HELPER_CREATEUSER######HELPER_UIKIT######HELPER_EXEL### /** - * Get a Variable + * Get a Variable * * @param string $table The table from which to get the variable * @param string $where The value where @@ -145,46 +145,18 @@ abstract class ###Component###Helper * @param string $main The component in which the table is found * * @return mix string/int/float - * + * @deprecated 3.3 Use Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::var(...); */ public static function getVar($table, $where = null, $whereString = 'user', $what = 'id', $operator = '=', $main = '###component###') { - if(!$where) - { - $where = JFactory::getUser()->id; - } - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array($what))); - if (empty($table)) - { - $query->from($db->quoteName('#__'.$main)); - } - else - { - $query->from($db->quoteName('#__'.$main.'_'.$table)); - } - if (is_numeric($where)) - { - $query->where($db->quoteName($whereString) . ' '.$operator.' '.(int) $where); - } - elseif (is_string($where)) - { - $query->where($db->quoteName($whereString) . ' '.$operator.' '. $db->quote((string)$where)); - } - else - { - return false; - } - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadResult(); - } - return false; + return Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::var( + $table, + $where, + $whereString, + $what, + $operator, + $main + ); } /** @@ -199,110 +171,38 @@ abstract class ###Component###Helper * @param bool $unique The switch to return a unique array * * @return array - * + * @deprecated 3.3 Use Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::vars(...); */ public static function getVars($table, $where = null, $whereString = 'user', $what = 'id', $operator = 'IN', $main = '###component###', $unique = true) { - if(!$where) - { - $where = JFactory::getUser()->id; - } - - if (!self::checkArray($where) && $where > 0) - { - $where = array($where); - } - - if (self::checkArray($where)) - { - // prep main <-- why? well if $main='' is empty then $table can be categories or users - if (self::checkString($main)) - { - $main = '_'.ltrim($main, '_'); - } - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - - $query->select($db->quoteName(array($what))); - if (empty($table)) - { - $query->from($db->quoteName('#__'.$main)); - } - else - { - $query->from($db->quoteName('#_'.$main.'_'.$table)); - } - // add strings to array search - if ('IN_STRINGS' === $operator || 'NOT IN_STRINGS' === $operator) - { - $query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","',$where) . '")'); - } - else - { - $query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',',$where) . ')'); - } - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - if ($unique) - { - return array_unique($db->loadColumn()); - } - return $db->loadColumn(); - } - } - return false; + return Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::vars( + $table, + $where, + $whereString, + $what, + $operator, + $main, + $unique + ); } + /** + * Convert a json object to a string + * + * @input string $value The json string to convert + * + * @returns a string + * @deprecated 3.3 Use Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::string(...); + */ public static function jsonToString($value, $sperator = ", ", $table = null, $id = 'id', $name = 'name') { - // do some table foot work - $external = false; - if (strpos($table, '#__') !== false) - { - $external = true; - $table = str_replace('#__', '', $table); - } - // check if string is JSON - $result = json_decode($value, true); - if (json_last_error() === JSON_ERROR_NONE) - { - // is JSON - if (self::checkArray($result)) - { - if (self::checkString($table)) - { - $names = array(); - foreach ($result as $val) - { - if ($external) - { - if ($_name = self::getVar(null, $val, $id, $name, '=', $table)) - { - $names[] = $_name; - } - } - else - { - if ($_name = self::getVar($table, $val, $id, $name)) - { - $names[] = $_name; - } - } - } - if (self::checkArray($names)) - { - return (string) implode($sperator,$names); - } - } - return (string) implode($sperator,$result); - } - return (string) json_decode($value); - } - return $value; + return Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::string( + $value, + $sperator, + $table, + $id, + $name + ); } public static function isPublished($id,$type) @@ -355,12 +255,12 @@ abstract class ###Component###Helper * @param object $user The user whose permissions we are loading * * @return object The JObject of permission/authorised actions - * + * */ public static function getActions($view, &$record = null, $views = null, $target = null, $component = '###component###', $user = 'null') { // load the user if not given - if (!self::checkObject($user)) + if (!Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($user)) { // get the user object $user = JFactory::getUser(); @@ -368,10 +268,10 @@ abstract class ###Component###Helper // load the JObject $result = new JObject; // make view name safe (just incase) - $view = self::safeString($view); - if (self::checkString($views)) + $view = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe($view); + if (Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($views)) { - $views = self::safeString($views); + $views = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe($views); } // get all actions from component $actions = JAccess::getActionsFromFile( @@ -384,9 +284,9 @@ abstract class ###Component###Helper return $result; } // get created by if not found - if (self::checkObject($record) && !isset($record->created_by) && isset($record->id)) + if (Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($record) && !isset($record->created_by) && isset($record->id)) { - $record->created_by = self::getVar($view, $record->id, 'id', 'created_by', '=', $component); + $record->created_by = Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::var($view, $record->id, 'id', 'created_by', '=', $component); } // set actions only set in component settings $componentActions = array('core.admin', 'core.manage', 'core.options', 'core.export'); @@ -395,12 +295,12 @@ abstract class ###Component###Helper if ($target) { // convert to an array - if (self::checkString($target)) + if (Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($target)) { $target = array($target); } // check if we are good to go - if (self::checkArray($target)) + if (Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($target)) { $checkTarget = true; } @@ -421,7 +321,7 @@ abstract class ###Component###Helper // set area $area = 'comp'; // check if the record has an ID and the action is item related (not a component action) - if (self::checkObject($record) && isset($record->id) && $record->id > 0 && !in_array($action->name, $componentActions) && + if (Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($record) && isset($record->id) && $record->id > 0 && !in_array($action->name, $componentActions) && (strpos($action->name, 'core.') !== false || strpos($action->name, $view . '.') !== false)) { // we are in item @@ -454,7 +354,7 @@ abstract class ###Component###Helper } } } - elseif (self::checkString($views) && isset($record->catid) && $record->catid > 0) + elseif (Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($views) && isset($record->catid) && $record->catid > 0) { // we are in item $area = 'category'; @@ -526,7 +426,7 @@ abstract class ###Component###Helper * @param array $targets The array of target actions * * @return boolean true if action should be filtered out - * + * */ protected static function filterActions(&$view, &$action, &$targets) { @@ -548,13 +448,13 @@ abstract class ###Component###Helper public static function getModel($name, $path = JPATH_COMPONENT_ADMINISTRATOR, $Component = '###Component###', $config = array()) { // fix the name - $name = self::safeString($name); + $name = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe($name); // full path to models $fullPathModels = $path . '/models'; // load the model file JModelLegacy::addIncludePath($fullPathModels, $Component . 'Model'); // make sure the table path is loaded - if (!isset($config['table_path']) || !self::checkString($config['table_path'])) + if (!isset($config['table_path']) || !Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($config['table_path'])) { // This is the JCB default path to tables in Joomla 3.x $config['table_path'] = JPATH_ADMINISTRATOR . '/components/com_' . strtolower($Component) . '/tables'; @@ -597,7 +497,7 @@ abstract class ###Component###Helper { $parent = JTable::getInstance('Asset'); $parent->loadByName('com_###component###'); - + $parentId = $parent->id; $name = 'com_###component###.'.$table.'.'.$id; $title = ''; @@ -717,35 +617,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param mixed $node A SimpleXMLElement node to append to the XML element reference, or a stdClass object containing a comment attribute to be injected before the XML node and a fieldXML attribute containing a SimpleXMLElement * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); */ public static function xmlAppend(&$xml, $node) { - if (!$node) - { - // element was not returned - return; - } - switch (get_class($node)) - { - case 'stdClass': - if (property_exists($node, 'comment')) - { - self::xmlComment($xml, $node->comment); - } - if (property_exists($node, 'fieldXML')) - { - self::xmlAppend($xml, $node->fieldXML); - } - break; - case 'SimpleXMLElement': - $domXML = dom_import_simplexml($xml); - $domNode = dom_import_simplexml($node); - $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); - $xml = simplexml_import_dom($domXML); - break; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); } /** @@ -754,16 +631,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param string $comment The comment to inject * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); */ public static function xmlComment(&$xml, $comment) { - $domXML = dom_import_simplexml($xml); - $domComment = new DOMComment($comment); - $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); - $domXML->appendChild($nodeTarget); - $xml = simplexml_import_dom($domXML); + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); } /** @@ -773,14 +646,11 @@ abstract class ###Component###Helper * @param array $attributes The attributes to apply to the XML element * * @return null - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); */ public static function xmlAddAttributes(&$xml, $attributes = array()) { - foreach ($attributes as $key => $value) - { - $xml->addAttribute($key, $value); - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); } /** @@ -790,16 +660,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return void - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); */ public static function xmlAddOptions(&$xml, $options = array()) { - foreach ($options as $key => $value) - { - $addOption = $xml->addChild('option'); - $addOption->addAttribute('value', $key); - $addOption[] = $value; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); } /** @@ -810,28 +675,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); */ public static function getFieldObject(&$attributes, $default = '', $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes) && isset($attributes['type'])) - { - // make sure the form helper class is loaded - if (!method_exists('JFormHelper', 'loadFieldType')) - { - jimport('joomla.form.form'); - } - // get field type - $field = JFormHelper::loadFieldType($attributes['type'], true); - // get field xml - $XML = self::getFieldXML($attributes, $options); - // setup the field - $field->setup($XML, $default); - // return the field object - return $field; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); } /** @@ -841,27 +689,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); */ public static function getFieldXML(&$attributes, $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes)) - { - // start field xml - $XML = new SimpleXMLElement(''); - // load the attributes - self::xmlAddAttributes($XML, $attributes); - // check if we have options - if (self::checkArray($options)) - { - // load the options - self::xmlAddOptions($XML, $options); - } - // return the field xml - return $XML; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); } /** @@ -885,17 +717,17 @@ abstract class ###Component###Helper // button attributes $buttonAttributes = array( 'type' => 'radio', - 'name' => isset($args[0]) ? self::htmlEscape($args[0]) : 'bool_button', - 'label' => isset($args[0]) ? self::safeString(self::htmlEscape($args[0]), 'Ww') : 'Bool Button', // not seen anyway + 'name' => isset($args[0]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[0]) : 'bool_button', + 'label' => isset($args[0]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe(Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[0]), 'Ww') : 'Bool Button', // not seen anyway 'class' => 'btn-group', 'filter' => 'INT', 'default' => isset($args[2]) ? (int) $args[2] : 0); // set the button options $buttonOptions = array( - '1' => isset($args[3]) ? self::htmlEscape($args[3]) : 'JYES', - '0' => isset($args[4]) ? self::htmlEscape($args[4]) : 'JNO'); + '1' => isset($args[3]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[3]) : 'JYES', + '0' => isset($args[4]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[4]) : 'JNO'); // return the input - return self::getFieldObject($buttonAttributes, $buttonAttributes['default'], $buttonOptions)->input; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($buttonAttributes, $buttonAttributes['default'], $buttonOptions)->input; } /** @@ -904,15 +736,11 @@ abstract class ###Component###Helper * @input string The json string to check * * @returns bool true on success + * @deprecated 3.3 Use Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::check($string); */ public static function checkJson($string) { - if (self::checkString($string)) - { - json_decode($string); - return (json_last_error() === JSON_ERROR_NONE); - } - return false; + return Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::check($string); } /** @@ -921,14 +749,11 @@ abstract class ###Component###Helper * @input object The object to check * * @returns bool true on success + * @deprecated 3.3 Use Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($object); */ public static function checkObject($object) { - if (isset($object) && is_object($object)) - { - return count((array)$object) > 0; - } - return false; + return Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($object); } /** @@ -937,26 +762,11 @@ abstract class ###Component###Helper * @input array The array to check * * @returns bool/int number of items in array on success + * @deprecated 3.3 Use Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($array, $removeEmptyString); */ public static function checkArray($array, $removeEmptyString = false) { - if (isset($array) && is_array($array) && ($nr = count((array)$array)) > 0) - { - // also make sure the empty strings are removed - if ($removeEmptyString) - { - foreach ($array as $key => $string) - { - if (empty($string)) - { - unset($array[$key]); - } - } - return self::checkArray($array, false); - } - return $nr; - } - return false; + return Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($array, $removeEmptyString); } /** @@ -965,14 +775,11 @@ abstract class ###Component###Helper * @input string The string to check * * @returns bool true on success + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($string); */ public static function checkString($string) { - if (isset($string) && is_string($string) && strlen($string) > 0) - { - return true; - } - return false; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($string); } /** @@ -984,7 +791,7 @@ abstract class ###Component###Helper public static function isConnected() { // If example.com is down, then probably the whole internet is down, since IANA maintains the domain. Right? - $connected = @fsockopen("www.example.com", 80); + $connected = @fsockopen("www.example.com", 80); // website, port (try 80 or 443) if ($connected) { @@ -1006,22 +813,11 @@ abstract class ###Component###Helper * @input array The arrays you would like to merge * * @returns array on success + * @deprecated 3.3 Use Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::merge($arrays); */ public static function mergeArrays($arrays) { - if(self::checkArray($arrays)) - { - $arrayBuket = array(); - foreach ($arrays as $array) - { - if (self::checkArray($array)) - { - $arrayBuket = array_merge($arrayBuket, $array); - } - } - return $arrayBuket; - } - return false; + return Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::merge($arrays); } // typo sorry! @@ -1036,39 +832,11 @@ abstract class ###Component###Helper * @input string The you would like to shorten * * @returns string on success + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::shorten(...); */ public static function shorten($string, $length = 40, $addTip = true) { - if (self::checkString($string)) - { - $initial = strlen($string); - $words = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE); - $words_count = count((array)$words); - - $word_length = 0; - $last_word = 0; - for (; $last_word < $words_count; ++$last_word) - { - $word_length += strlen($words[$last_word]); - if ($word_length > $length) - { - break; - } - } - - $newString = implode(array_slice($words, 0, $last_word)); - $final = strlen($newString); - if ($initial != $final && $addTip) - { - $title = self::shorten($string, 400 , false); - return ''.trim($newString).'...'; - } - elseif ($initial != $final && !$addTip) - { - return trim($newString).'...'; - } - } - return $string; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::shorten($string, $length, $addTip); } /** @@ -1077,157 +845,61 @@ abstract class ###Component###Helper * @input string The you would like to make safe * * @returns string on success + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe(...); */ public static function safeString($string, $type = 'L', $spacer = '_', $replaceNumbers = true, $keepOnlyCharacters = true) { - if ($replaceNumbers === true) - { - // remove all numbers and replace with english text version (works well only up to millions) - $string = self::replaceNumbers($string); - } - // 0nly continue if we have a string - if (self::checkString($string)) - { - // create file name without the extention that is safe - if ($type === 'filename') - { - // make sure VDM is not in the string - $string = str_replace('VDM', 'vDm', $string); - // Remove anything which isn't a word, whitespace, number - // or any of the following caracters -_() - // If you don't need to handle multi-byte characters - // you can use preg_replace rather than mb_ereg_replace - // Thanks @Ɓukasz Rysiak! - // $string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string); - $string = preg_replace("([^\w\s\d\-_\(\)])", '', $string); - // http://stackoverflow.com/a/2021729/1429677 - return preg_replace('/\s+/', ' ', $string); - } - // remove all other characters - $string = trim($string); - $string = preg_replace('/'.$spacer.'+/', ' ', $string); - $string = preg_replace('/\s+/', ' ', $string); - // Transliterate string - $string = self::transliterate($string); - // remove all and keep only characters - if ($keepOnlyCharacters) - { - $string = preg_replace("/[^A-Za-z ]/", '', $string); - } - // keep both numbers and characters - else - { - $string = preg_replace("/[^A-Za-z0-9 ]/", '', $string); - } - // select final adaptations - if ($type === 'L' || $type === 'strtolower') - { - // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); - // default is to return lower - return strtolower($string); - } - elseif ($type === 'W') - { - // return a string with all first letter of each word uppercase(no undersocre) - return ucwords(strtolower($string)); - } - elseif ($type === 'w' || $type === 'word') - { - // return a string with all lowercase(no undersocre) - return strtolower($string); - } - elseif ($type === 'Ww' || $type === 'Word') - { - // return a string with first letter of the first word uppercase and all the rest lowercase(no undersocre) - return ucfirst(strtolower($string)); - } - elseif ($type === 'WW' || $type === 'WORD') - { - // return a string with all the uppercase(no undersocre) - return strtoupper($string); - } - elseif ($type === 'U' || $type === 'strtoupper') - { - // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); - // return all upper - return strtoupper($string); - } - elseif ($type === 'F' || $type === 'ucfirst') - { - // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); - // return with first caracter to upper - return ucfirst(strtolower($string)); - } - elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase') - { - // convert all words to first letter uppercase - $string = ucwords(strtolower($string)); - // remove white space - $string = preg_replace('/\s+/', '', $string); - // now return first letter lowercase - return lcfirst($string); - } - // return string - return $string; - } - // not a string - return ''; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe( + $string, + $type, + $spacer, + $replaceNumbers, + $keepOnlyCharacters + ); } + /** + * Convert none English strings to code usable string + * + * @input an string + * + * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::transliterate($string); + */ public static function transliterate($string) { - // set tag only once - if (!self::checkString(self::$langTag)) - { - // get global value - self::$langTag = JComponentHelper::getParams('com_###component###')->get('language', 'en-GB'); - } - // Transliterate on the language requested - $lang = Language::getInstance(self::$langTag); - return $lang->transliterate($string); + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::transliterate($string); } + /** + * make sure a string is HTML save + * + * @input an html string + * + * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html(...); + */ public static function htmlEscape($var, $charset = 'UTF-8', $shorten = false, $length = 40) { - if (self::checkString($var)) - { - $filter = new JFilterInput(); - $string = $filter->clean(html_entity_decode(htmlentities($var, ENT_COMPAT, $charset)), 'HTML'); - if ($shorten) - { - return self::shorten($string,$length); - } - return $string; - } - else - { - return ''; - } + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html( + $var, + $charset, + $shorten, + $length + ); }###HELPER_LICENSE_LOCK### + /** + * Convert all int in a string to an English word string + * + * @input an string with numbers + * + * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::numbers($string); + */ public static function replaceNumbers($string) { - // set numbers array - $numbers = array(); - // first get all numbers - preg_match_all('!\d+!', $string, $numbers); - // check if we have any numbers - if (isset($numbers[0]) && self::checkArray($numbers[0])) - { - foreach ($numbers[0] as $number) - { - $searchReplace[$number] = self::numberToString((int)$number); - } - // now replace numbers in string - $string = str_replace(array_keys($searchReplace), array_values($searchReplace),$string); - // check if we missed any, strange if we did. - return self::replaceNumbers($string); - } - // return the string with no numbers remaining. - return $string; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::numbers($string); } /** @@ -1236,107 +908,21 @@ abstract class ###Component###Helper * * @input an int * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::number($x); */ public static function numberToString($x) { - $nwords = array( "zero", "one", "two", "three", "four", "five", "six", "seven", - "eight", "nine", "ten", "eleven", "twelve", "thirteen", - "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", - "nineteen", "twenty", 30 => "thirty", 40 => "forty", - 50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty", - 90 => "ninety" ); - - if(!is_numeric($x)) - { - $w = $x; - } - elseif(fmod($x, 1) != 0) - { - $w = $x; - } - else - { - if($x < 0) - { - $w = 'minus '; - $x = -$x; - } - else - { - $w = ''; - // ... now $x is a non-negative integer. - } - - if($x < 21) // 0 to 20 - { - $w .= $nwords[$x]; - } - elseif($x < 100) // 21 to 99 - { - $w .= $nwords[10 * floor($x/10)]; - $r = fmod($x, 10); - if($r > 0) - { - $w .= ' '. $nwords[$r]; - } - } - elseif($x < 1000) // 100 to 999 - { - $w .= $nwords[floor($x/100)] .' hundred'; - $r = fmod($x, 100); - if($r > 0) - { - $w .= ' and '. self::numberToString($r); - } - } - elseif($x < 1000000) // 1000 to 999999 - { - $w .= self::numberToString(floor($x/1000)) .' thousand'; - $r = fmod($x, 1000); - if($r > 0) - { - $w .= ' '; - if($r < 100) - { - $w .= 'and '; - } - $w .= self::numberToString($r); - } - } - else // millions - { - $w .= self::numberToString(floor($x/1000000)) .' million'; - $r = fmod($x, 1000000); - if($r > 0) - { - $w .= ' '; - if($r < 100) - { - $w .= 'and '; - } - $w .= self::numberToString($r); - } - } - } - return $w; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::number($x); } /** * Random Key * * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::random($size); */ public static function randomkey($size) { - $bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ"; - $key = array(); - $bagsize = strlen($bag) - 1; - for ($i = 0; $i < $size; $i++) - { - $get = rand(0, $bagsize); - $key[] = $bag[$get]; - } - return implode($key); + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::random($size); }###GET_CRYPT_KEY### } - diff --git a/admin/compiler/joomla_3/Helper_site.php b/admin/compiler/joomla_3/Helper_site.php index d9069328c..2f61d0c50 100644 --- a/admin/compiler/joomla_3/Helper_site.php +++ b/admin/compiler/joomla_3/Helper_site.php @@ -26,14 +26,14 @@ abstract class ###Component###Helper { /** * Composer Switch - * + * * @var array */ protected static $composer = array(); /** * The Main Active Language - * + * * @var string */ public static $langTag;###SITE_GLOBAL_EVENT_HELPER######SITE_CUSTOM_HELPER_SCRIPT######BOTH_CUSTOM_HELPER_SCRIPT### @@ -47,7 +47,7 @@ abstract class ###Component###Helper if (!isset(self::$composer[$target])) { // get the function name - $functionName = self::safeString('compose' . $target); + $functionName = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe('compose' . $target); // check if method exist if (method_exists(__CLASS__, $functionName)) { @@ -59,54 +59,22 @@ abstract class ###Component###Helper } /** - * Convert it into a string + * Convert a json object to a string + * + * @input string $value The json string to convert + * + * @returns a string + * @deprecated 3.3 Use Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::string(...); */ public static function jsonToString($value, $sperator = ", ", $table = null, $id = 'id', $name = 'name') { - // do some table foot work - $external = false; - if (strpos($table, '#__') !== false) - { - $external = true; - $table = str_replace('#__', '', $table); - } - // check if string is JSON - $result = json_decode($value, true); - if (json_last_error() === JSON_ERROR_NONE) - { - // is JSON - if (self::checkArray($result)) - { - if (self::checkString($table)) - { - $names = array(); - foreach ($result as $val) - { - if ($external) - { - if ($_name = self::getVar(null, $val, $id, $name, '=', $table)) - { - $names[] = $_name; - } - } - else - { - if ($_name = self::getVar($table, $val, $id, $name)) - { - $names[] = $_name; - } - } - } - if (self::checkArray($names)) - { - return (string) implode($sperator,$names); - } - } - return (string) implode($sperator,$result); - } - return (string) json_decode($value); - } - return $value; + return Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::string( + $value, + $sperator, + $table, + $id, + $name + ); } /** @@ -120,7 +88,7 @@ abstract class ###Component###Helper /** * Joomla version object - */ + */ protected static $JVersion; /** @@ -129,7 +97,7 @@ abstract class ###Component###Helper public static function jVersion() { // check if set - if (!self::checkObject(self::$JVersion)) + if (!Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check(self::$JVersion)) { self::$JVersion = new JVersion(); } @@ -167,8 +135,8 @@ abstract class ###Component###Helper $link_front = ''; $link_back = ''; } - $contributors[$nr]['title'] = self::htmlEscape($params->get("titleContributor".$nr)); - $contributors[$nr]['name'] = $link_front.self::htmlEscape($params->get("nameContributor".$nr)).$link_back; + $contributors[$nr]['title'] = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($params->get("titleContributor".$nr)); + $contributors[$nr]['name'] = $link_front.Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($params->get("nameContributor".$nr)).$link_back; } } return $contributors; @@ -180,13 +148,13 @@ abstract class ###Component###Helper public static function getModel($name, $path = JPATH_COMPONENT_SITE, $Component = '###Component###', $config = array()) { // fix the name - $name = self::safeString($name); + $name = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe($name); // full path to models $fullPathModels = $path . '/models'; // load the model file JModelLegacy::addIncludePath($fullPathModels, $Component . 'Model'); // make sure the table path is loaded - if (!isset($config['table_path']) || !self::checkString($config['table_path'])) + if (!isset($config['table_path']) || !Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($config['table_path'])) { // This is the JCB default path to tables in Joomla 3.x $config['table_path'] = JPATH_ADMINISTRATOR . '/components/com_' . strtolower($Component) . '/tables'; @@ -229,7 +197,7 @@ abstract class ###Component###Helper { $parent = JTable::getInstance('Asset'); $parent->loadByName('com_###component###'); - + $parentId = $parent->id; $name = 'com_###component###.'.$table.'.'.$id; $title = ''; @@ -349,35 +317,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param mixed $node A SimpleXMLElement node to append to the XML element reference, or a stdClass object containing a comment attribute to be injected before the XML node and a fieldXML attribute containing a SimpleXMLElement * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); */ public static function xmlAppend(&$xml, $node) { - if (!$node) - { - // element was not returned - return; - } - switch (get_class($node)) - { - case 'stdClass': - if (property_exists($node, 'comment')) - { - self::xmlComment($xml, $node->comment); - } - if (property_exists($node, 'fieldXML')) - { - self::xmlAppend($xml, $node->fieldXML); - } - break; - case 'SimpleXMLElement': - $domXML = dom_import_simplexml($xml); - $domNode = dom_import_simplexml($node); - $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); - $xml = simplexml_import_dom($domXML); - break; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); } /** @@ -386,16 +331,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param string $comment The comment to inject * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); */ public static function xmlComment(&$xml, $comment) { - $domXML = dom_import_simplexml($xml); - $domComment = new DOMComment($comment); - $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); - $domXML->appendChild($nodeTarget); - $xml = simplexml_import_dom($domXML); + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); } /** @@ -405,14 +346,11 @@ abstract class ###Component###Helper * @param array $attributes The attributes to apply to the XML element * * @return null - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); */ public static function xmlAddAttributes(&$xml, $attributes = array()) { - foreach ($attributes as $key => $value) - { - $xml->addAttribute($key, $value); - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); } /** @@ -422,16 +360,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return void - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); */ public static function xmlAddOptions(&$xml, $options = array()) { - foreach ($options as $key => $value) - { - $addOption = $xml->addChild('option'); - $addOption->addAttribute('value', $key); - $addOption[] = $value; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); } /** @@ -442,28 +375,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); */ public static function getFieldObject(&$attributes, $default = '', $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes) && isset($attributes['type'])) - { - // make sure the form helper class is loaded - if (!method_exists('JFormHelper', 'loadFieldType')) - { - jimport('joomla.form.form'); - } - // get field type - $field = JFormHelper::loadFieldType($attributes['type'], true); - // get field xml - $XML = self::getFieldXML($attributes, $options); - // setup the field - $field->setup($XML, $default); - // return the field object - return $field; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); } /** @@ -473,27 +389,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); */ public static function getFieldXML(&$attributes, $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes)) - { - // start field xml - $XML = new SimpleXMLElement(''); - // load the attributes - self::xmlAddAttributes($XML, $attributes); - // check if we have options - if (self::checkArray($options)) - { - // load the options - self::xmlAddOptions($XML, $options); - } - // return the field xml - return $XML; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); } /** @@ -517,21 +417,21 @@ abstract class ###Component###Helper // button attributes $buttonAttributes = array( 'type' => 'radio', - 'name' => isset($args[0]) ? self::htmlEscape($args[0]) : 'bool_button', - 'label' => isset($args[0]) ? self::safeString(self::htmlEscape($args[0]), 'Ww') : 'Bool Button', // not seen anyway + 'name' => isset($args[0]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[0]) : 'bool_button', + 'label' => isset($args[0]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe(Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[0]), 'Ww') : 'Bool Button', // not seen anyway 'class' => 'btn-group', 'filter' => 'INT', 'default' => isset($args[2]) ? (int) $args[2] : 0); // set the button options $buttonOptions = array( - '1' => isset($args[3]) ? self::htmlEscape($args[3]) : 'JYES', - '0' => isset($args[4]) ? self::htmlEscape($args[4]) : 'JNO'); + '1' => isset($args[3]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[3]) : 'JYES', + '0' => isset($args[4]) ? Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html($args[4]) : 'JNO'); // return the input - return self::getFieldObject($buttonAttributes, $buttonAttributes['default'], $buttonOptions)->input; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($buttonAttributes, $buttonAttributes['default'], $buttonOptions)->input; }###HELPER_UIKIT######HELPER_CREATEUSER### /** - * Get a variable + * Get a variable * * @param string $table The table from which to get the variable * @param string $where The value where @@ -541,46 +441,18 @@ abstract class ###Component###Helper * @param string $main The component in which the table is found * * @return mix string/int/float - * + * @deprecated 3.3 Use Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::var(...); */ public static function getVar($table, $where = null, $whereString = 'user', $what = 'id', $operator = '=', $main = '###component###') { - if(!$where) - { - $where = JFactory::getUser()->id; - } - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array($what))); - if (empty($table)) - { - $query->from($db->quoteName('#__'.$main)); - } - else - { - $query->from($db->quoteName('#__'.$main.'_'.$table)); - } - if (is_numeric($where)) - { - $query->where($db->quoteName($whereString) . ' '.$operator.' '.(int) $where); - } - elseif (is_string($where)) - { - $query->where($db->quoteName($whereString) . ' '.$operator.' '. $db->quote((string)$where)); - } - else - { - return false; - } - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadResult(); - } - return false; + return Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::var( + $table, + $where, + $whereString, + $what, + $operator, + $main + ); } /** @@ -595,63 +467,20 @@ abstract class ###Component###Helper * @param bool $unique The switch to return a unique array * * @return array - * + * @deprecated 3.3 Use Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::vars(...); */ public static function getVars($table, $where = null, $whereString = 'user', $what = 'id', $operator = 'IN', $main = '###component###', $unique = true) { - if(!$where) - { - $where = JFactory::getUser()->id; - } - - if (!self::checkArray($where) && $where > 0) - { - $where = array($where); - } - - if (self::checkArray($where)) - { - // prep main <-- why? well if $main='' is empty then $table can be categories or users - if (self::checkString($main)) - { - $main = '_'.ltrim($main, '_'); - } - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - - $query->select($db->quoteName(array($what))); - if (empty($table)) - { - $query->from($db->quoteName('#__'.$main)); - } - else - { - $query->from($db->quoteName('#_'.$main.'_'.$table)); - } - // add strings to array search - if ('IN_STRINGS' === $operator || 'NOT IN_STRINGS' === $operator) - { - $query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","',$where) . '")'); - } - else - { - $query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',',$where) . ')'); - } - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - if ($unique) - { - return array_unique($db->loadColumn()); - } - return $db->loadColumn(); - } - } - return false; - } + return Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::vars( + $table, + $where, + $whereString, + $what, + $operator, + $main, + $unique + ); + } public static function isPublished($id,$type) { @@ -703,12 +532,12 @@ abstract class ###Component###Helper * @param object $user The user whose permissions we are loading * * @return object The JObject of permission/authorised actions - * + * */ public static function getActions($view, &$record = null, $views = null, $target = null, $component = '###component###', $user = 'null') { // load the user if not given - if (!self::checkObject($user)) + if (!Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($user)) { // get the user object $user = JFactory::getUser(); @@ -716,10 +545,10 @@ abstract class ###Component###Helper // load the JObject $result = new JObject; // make view name safe (just incase) - $view = self::safeString($view); - if (self::checkString($views)) + $view = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe($view); + if (Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($views)) { - $views = self::safeString($views); + $views = Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe($views); } // get all actions from component $actions = JAccess::getActionsFromFile( @@ -732,9 +561,9 @@ abstract class ###Component###Helper return $result; } // get created by if not found - if (self::checkObject($record) && !isset($record->created_by) && isset($record->id)) + if (Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($record) && !isset($record->created_by) && isset($record->id)) { - $record->created_by = self::getVar($view, $record->id, 'id', 'created_by', '=', $component); + $record->created_by = Super___db87c339_5bb6_4291_a7ef_2c48ea1b06bc___Power::var($view, $record->id, 'id', 'created_by', '=', $component); } // set actions only set in component settings $componentActions = array('core.admin', 'core.manage', 'core.options', 'core.export'); @@ -743,12 +572,12 @@ abstract class ###Component###Helper if ($target) { // convert to an array - if (self::checkString($target)) + if (Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($target)) { $target = array($target); } // check if we are good to go - if (self::checkArray($target)) + if (Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($target)) { $checkTarget = true; } @@ -769,7 +598,7 @@ abstract class ###Component###Helper // set area $area = 'comp'; // check if the record has an ID and the action is item related (not a component action) - if (self::checkObject($record) && isset($record->id) && $record->id > 0 && !in_array($action->name, $componentActions) && + if (Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($record) && isset($record->id) && $record->id > 0 && !in_array($action->name, $componentActions) && (strpos($action->name, 'core.') !== false || strpos($action->name, $view . '.') !== false)) { // we are in item @@ -802,7 +631,7 @@ abstract class ###Component###Helper } } } - elseif (self::checkString($views) && isset($record->catid) && $record->catid > 0) + elseif (Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($views) && isset($record->catid) && $record->catid > 0) { // we are in item $area = 'category'; @@ -874,7 +703,7 @@ abstract class ###Component###Helper * @param array $targets The array of target actions * * @return boolean true if action should be filtered out - * + * */ protected static function filterActions(&$view, &$action, &$targets) { @@ -896,15 +725,11 @@ abstract class ###Component###Helper * @input string The json string to check * * @returns bool true on success + * @deprecated 3.3 Use Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::check($string); */ public static function checkJson($string) { - if (self::checkString($string)) - { - json_decode($string); - return (json_last_error() === JSON_ERROR_NONE); - } - return false; + return Super___4b225c51_d293_48e4_b3f6_5136cf5c3f18___Power::check($string); } /** @@ -913,14 +738,11 @@ abstract class ###Component###Helper * @input object The object to check * * @returns bool true on success + * @deprecated 3.3 Use Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($object); */ public static function checkObject($object) { - if (isset($object) && is_object($object)) - { - return count((array)$object) > 0; - } - return false; + return Super___91004529_94a9_4590_b842_e7c6b624ecf5___Power::check($object); } /** @@ -929,26 +751,11 @@ abstract class ###Component###Helper * @input array The array to check * * @returns bool/int number of items in array on success + * @deprecated 3.3 Use Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($array, $removeEmptyString); */ public static function checkArray($array, $removeEmptyString = false) { - if (isset($array) && is_array($array) && ($nr = count((array)$array)) > 0) - { - // also make sure the empty strings are removed - if ($removeEmptyString) - { - foreach ($array as $key => $string) - { - if (empty($string)) - { - unset($array[$key]); - } - } - return self::checkArray($array, false); - } - return $nr; - } - return false; + return Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($array, $removeEmptyString); } /** @@ -957,14 +764,11 @@ abstract class ###Component###Helper * @input string The string to check * * @returns bool true on success + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($string); */ public static function checkString($string) { - if (isset($string) && is_string($string) && strlen($string) > 0) - { - return true; - } - return false; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::check($string); } /** @@ -976,7 +780,7 @@ abstract class ###Component###Helper public static function isConnected() { // If example.com is down, then probably the whole internet is down, since IANA maintains the domain. Right? - $connected = @fsockopen("www.example.com", 80); + $connected = @fsockopen("www.example.com", 80); // website, port (try 80 or 443) if ($connected) { @@ -998,22 +802,11 @@ abstract class ###Component###Helper * @input array The arrays you would like to merge * * @returns array on success + * @deprecated 3.3 Use Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::merge($arrays); */ public static function mergeArrays($arrays) { - if(self::checkArray($arrays)) - { - $arrayBuket = array(); - foreach ($arrays as $array) - { - if (self::checkArray($array)) - { - $arrayBuket = array_merge($arrayBuket, $array); - } - } - return $arrayBuket; - } - return false; + return Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::merge($arrays); } // typo sorry! @@ -1028,39 +821,11 @@ abstract class ###Component###Helper * @input string The you would like to shorten * * @returns string on success + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::shorten(...); */ public static function shorten($string, $length = 40, $addTip = true) { - if (self::checkString($string)) - { - $initial = strlen($string); - $words = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE); - $words_count = count((array)$words); - - $word_length = 0; - $last_word = 0; - for (; $last_word < $words_count; ++$last_word) - { - $word_length += strlen($words[$last_word]); - if ($word_length > $length) - { - break; - } - } - - $newString = implode(array_slice($words, 0, $last_word)); - $final = strlen($newString); - if ($initial != $final && $addTip) - { - $title = self::shorten($string, 400 , false); - return ''.trim($newString).'...'; - } - elseif ($initial != $final && !$addTip) - { - return trim($newString).'...'; - } - } - return $string; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::shorten($string, $length, $addTip); } /** @@ -1069,157 +834,61 @@ abstract class ###Component###Helper * @input string The you would like to make safe * * @returns string on success + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe(...); */ public static function safeString($string, $type = 'L', $spacer = '_', $replaceNumbers = true, $keepOnlyCharacters = true) { - if ($replaceNumbers === true) - { - // remove all numbers and replace with english text version (works well only up to millions) - $string = self::replaceNumbers($string); - } - // 0nly continue if we have a string - if (self::checkString($string)) - { - // create file name without the extention that is safe - if ($type === 'filename') - { - // make sure VDM is not in the string - $string = str_replace('VDM', 'vDm', $string); - // Remove anything which isn't a word, whitespace, number - // or any of the following caracters -_() - // If you don't need to handle multi-byte characters - // you can use preg_replace rather than mb_ereg_replace - // Thanks @Ɓukasz Rysiak! - // $string = mb_ereg_replace("([^\w\s\d\-_\(\)])", '', $string); - $string = preg_replace("([^\w\s\d\-_\(\)])", '', $string); - // http://stackoverflow.com/a/2021729/1429677 - return preg_replace('/\s+/', ' ', $string); - } - // remove all other characters - $string = trim($string); - $string = preg_replace('/'.$spacer.'+/', ' ', $string); - $string = preg_replace('/\s+/', ' ', $string); - // Transliterate string - $string = self::transliterate($string); - // remove all and keep only characters - if ($keepOnlyCharacters) - { - $string = preg_replace("/[^A-Za-z ]/", '', $string); - } - // keep both numbers and characters - else - { - $string = preg_replace("/[^A-Za-z0-9 ]/", '', $string); - } - // select final adaptations - if ($type === 'L' || $type === 'strtolower') - { - // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); - // default is to return lower - return strtolower($string); - } - elseif ($type === 'W') - { - // return a string with all first letter of each word uppercase(no undersocre) - return ucwords(strtolower($string)); - } - elseif ($type === 'w' || $type === 'word') - { - // return a string with all lowercase(no undersocre) - return strtolower($string); - } - elseif ($type === 'Ww' || $type === 'Word') - { - // return a string with first letter of the first word uppercase and all the rest lowercase(no undersocre) - return ucfirst(strtolower($string)); - } - elseif ($type === 'WW' || $type === 'WORD') - { - // return a string with all the uppercase(no undersocre) - return strtoupper($string); - } - elseif ($type === 'U' || $type === 'strtoupper') - { - // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); - // return all upper - return strtoupper($string); - } - elseif ($type === 'F' || $type === 'ucfirst') - { - // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); - // return with first caracter to upper - return ucfirst(strtolower($string)); - } - elseif ($type === 'cA' || $type === 'cAmel' || $type === 'camelcase') - { - // convert all words to first letter uppercase - $string = ucwords(strtolower($string)); - // remove white space - $string = preg_replace('/\s+/', '', $string); - // now return first letter lowercase - return lcfirst($string); - } - // return string - return $string; - } - // not a string - return ''; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::safe( + $string, + $type, + $spacer, + $replaceNumbers, + $keepOnlyCharacters + ); } + /** + * Convert none English strings to code usable string + * + * @input an string + * + * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::transliterate($string); + */ public static function transliterate($string) { - // set tag only once - if (!self::checkString(self::$langTag)) - { - // get global value - self::$langTag = JComponentHelper::getParams('com_###component###')->get('language', 'en-GB'); - } - // Transliterate on the language requested - $lang = Language::getInstance(self::$langTag); - return $lang->transliterate($string); + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::transliterate($string); } + /** + * make sure a string is HTML save + * + * @input an html string + * + * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html(...); + */ public static function htmlEscape($var, $charset = 'UTF-8', $shorten = false, $length = 40) { - if (self::checkString($var)) - { - $filter = new JFilterInput(); - $string = $filter->clean(html_entity_decode(htmlentities($var, ENT_COMPAT, $charset)), 'HTML'); - if ($shorten) - { - return self::shorten($string,$length); - } - return $string; - } - else - { - return ''; - } + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::html( + $var, + $charset, + $shorten, + $length + ); }###HELPER_SITE_LICENSE_LOCK### + /** + * Convert all int in a string to an English word string + * + * @input an string with numbers + * + * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::numbers($string); + */ public static function replaceNumbers($string) { - // set numbers array - $numbers = array(); - // first get all numbers - preg_match_all('!\d+!', $string, $numbers); - // check if we have any numbers - if (isset($numbers[0]) && self::checkArray($numbers[0])) - { - foreach ($numbers[0] as $number) - { - $searchReplace[$number] = self::numberToString((int)$number); - } - // now replace numbers in string - $string = str_replace(array_keys($searchReplace), array_values($searchReplace),$string); - // check if we missed any, strange if we did. - return self::replaceNumbers($string); - } - // return the string with no numbers remaining. - return $string; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::numbers($string); } /** @@ -1228,107 +897,21 @@ abstract class ###Component###Helper * * @input an int * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::number($x); */ public static function numberToString($x) { - $nwords = array( "zero", "one", "two", "three", "four", "five", "six", "seven", - "eight", "nine", "ten", "eleven", "twelve", "thirteen", - "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", - "nineteen", "twenty", 30 => "thirty", 40 => "forty", - 50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty", - 90 => "ninety" ); - - if(!is_numeric($x)) - { - $w = $x; - } - elseif(fmod($x, 1) != 0) - { - $w = $x; - } - else - { - if($x < 0) - { - $w = 'minus '; - $x = -$x; - } - else - { - $w = ''; - // ... now $x is a non-negative integer. - } - - if($x < 21) // 0 to 20 - { - $w .= $nwords[$x]; - } - elseif($x < 100) // 21 to 99 - { - $w .= $nwords[10 * floor($x/10)]; - $r = fmod($x, 10); - if($r > 0) - { - $w .= ' '. $nwords[$r]; - } - } - elseif($x < 1000) // 100 to 999 - { - $w .= $nwords[floor($x/100)] .' hundred'; - $r = fmod($x, 100); - if($r > 0) - { - $w .= ' and '. self::numberToString($r); - } - } - elseif($x < 1000000) // 1000 to 999999 - { - $w .= self::numberToString(floor($x/1000)) .' thousand'; - $r = fmod($x, 1000); - if($r > 0) - { - $w .= ' '; - if($r < 100) - { - $w .= 'and '; - } - $w .= self::numberToString($r); - } - } - else // millions - { - $w .= self::numberToString(floor($x/1000000)) .' million'; - $r = fmod($x, 1000000); - if($r > 0) - { - $w .= ' '; - if($r < 100) - { - $w .= 'and '; - } - $w .= self::numberToString($r); - } - } - } - return $w; + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::number($x); } /** * Random Key * * @returns a string + * @deprecated 3.3 Use Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::random($size); */ public static function randomkey($size) { - $bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ"; - $key = array(); - $bagsize = strlen($bag) - 1; - for ($i = 0; $i < $size; $i++) - { - $get = rand(0, $bagsize); - $key[] = $bag[$get]; - } - return implode($key); + return Super___1f28cb53_60d9_4db1_b517_3c7dc6b429ef___Power::random($size); }###GET_CRYPT_KEY### } - diff --git a/admin/compiler/joomla_3/HtmlView_custom_admin.php b/admin/compiler/joomla_3/HtmlView_custom_admin.php index ca7f5df16..a7f97fbee 100644 --- a/admin/compiler/joomla_3/HtmlView_custom_admin.php +++ b/admin/compiler/joomla_3/HtmlView_custom_admin.php @@ -43,7 +43,7 @@ class ###Component###View###SView### extends HtmlView protected function setDocument() {###CUSTOM_ADMIN_LIBRARIES_LOADER######CUSTOM_ADMIN_DOCUMENT_METADATA######CUSTOM_ADMIN_UIKIT_LOADER######CUSTOM_ADMIN_GOOGLECHART_LOADER######CUSTOM_ADMIN_FOOTABLE_LOADER######CUSTOM_ADMIN_DOCUMENT_CUSTOM_PHP### // add the document default css file - $this->document->addStyleSheet(JURI::root(true) .'/administrator/components/com_###component###/assets/css/###sview###.css', (###Component###Helper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css');###CUSTOM_ADMIN_DOCUMENT_CUSTOM_CSS######CUSTOM_ADMIN_DOCUMENT_CUSTOM_JS### + JHtml::_('stylesheet', 'administrator/components/com_###component###/assets/css/###sview###.css', ['version' => 'auto']);###CUSTOM_ADMIN_DOCUMENT_CUSTOM_CSS######CUSTOM_ADMIN_DOCUMENT_CUSTOM_JS### } /** diff --git a/admin/compiler/joomla_3/HtmlView_list_custom_admin.php b/admin/compiler/joomla_3/HtmlView_list_custom_admin.php index 766c63395..171226444 100644 --- a/admin/compiler/joomla_3/HtmlView_list_custom_admin.php +++ b/admin/compiler/joomla_3/HtmlView_list_custom_admin.php @@ -43,7 +43,7 @@ class ###Component###View###SViews### extends HtmlView protected function setDocument() {###CUSTOM_ADMIN_LIBRARIES_LOADER######CUSTOM_ADMIN_UIKIT_LOADER######CUSTOM_ADMIN_GOOGLECHART_LOADER######CUSTOM_ADMIN_FOOTABLE_LOADER######CUSTOM_ADMIN_DOCUMENT_CUSTOM_PHP### // add the document default css file - $this->document->addStyleSheet(JURI::root(true) .'/administrator/components/com_###component###/assets/css/###sviews###.css', (###Component###Helper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css');###CUSTOM_ADMIN_DOCUMENT_CUSTOM_CSS######CUSTOM_ADMIN_DOCUMENT_CUSTOM_JS### + JHtml::_('stylesheet', 'administrator/components/com_###component###/assets/css/###sviews###.css', ['version' => 'auto']);###CUSTOM_ADMIN_DOCUMENT_CUSTOM_CSS######CUSTOM_ADMIN_DOCUMENT_CUSTOM_JS### } /** diff --git a/admin/compiler/joomla_3/HtmlView_list_site.php b/admin/compiler/joomla_3/HtmlView_list_site.php index dea200543..e981783d2 100644 --- a/admin/compiler/joomla_3/HtmlView_list_site.php +++ b/admin/compiler/joomla_3/HtmlView_list_site.php @@ -41,7 +41,7 @@ class ###Component###View###SViews### extends HtmlView protected function _prepareDocument() {###SITE_LIBRARIES_LOADER######SITE_UIKIT_LOADER######SITE_GOOGLECHART_LOADER######SITE_FOOTABLE_LOADER######SITE_DOCUMENT_METADATA######SITE_DOCUMENT_CUSTOM_PHP### // add the document default css file - $this->document->addStyleSheet(JURI::root(true) .'/components/com_###component###/assets/css/###sview###.css', (###Component###Helper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css');###SITE_DOCUMENT_CUSTOM_CSS######SITE_DOCUMENT_CUSTOM_JS######SITE_JAVASCRIPT_FOR_BUTTONS### + JHtml::_('stylesheet', 'components/com_###component###/assets/css/###sview###.css', ['version' => 'auto']);###SITE_DOCUMENT_CUSTOM_CSS######SITE_DOCUMENT_CUSTOM_JS######SITE_JAVASCRIPT_FOR_BUTTONS### } /** diff --git a/admin/compiler/joomla_3/HtmlView_site.php b/admin/compiler/joomla_3/HtmlView_site.php index 12e20f031..13bc3fd01 100644 --- a/admin/compiler/joomla_3/HtmlView_site.php +++ b/admin/compiler/joomla_3/HtmlView_site.php @@ -41,7 +41,7 @@ class ###Component###View###SView### extends HtmlView protected function _prepareDocument() {###SITE_LIBRARIES_LOADER######SITE_UIKIT_LOADER######SITE_GOOGLECHART_LOADER######SITE_FOOTABLE_LOADER######SITE_DOCUMENT_METADATA######SITE_DOCUMENT_CUSTOM_PHP### // add the document default css file - $this->document->addStyleSheet(JURI::root(true) .'/components/com_###component###/assets/css/###sview###.css', (###Component###Helper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css');###SITE_DOCUMENT_CUSTOM_CSS######SITE_DOCUMENT_CUSTOM_JS######SITE_JAVASCRIPT_FOR_BUTTONS### + JHtml::_('stylesheet', 'components/com_###component###/assets/css/###sview###.css', ['version' => 'auto']);###SITE_DOCUMENT_CUSTOM_CSS######SITE_DOCUMENT_CUSTOM_JS######SITE_JAVASCRIPT_FOR_BUTTONS### } /** diff --git a/admin/compiler/joomla_3/JCB_Helper.php b/admin/compiler/joomla_3/JCB_Helper.php index 4f65b36c9..1819d2ba2 100644 --- a/admin/compiler/joomla_3/JCB_Helper.php +++ b/admin/compiler/joomla_3/JCB_Helper.php @@ -551,35 +551,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param mixed $node A SimpleXMLElement node to append to the XML element reference, or a stdClass object containing a comment attribute to be injected before the XML node and a fieldXML attribute containing a SimpleXMLElement * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); */ public static function xmlAppend(&$xml, $node) { - if (!$node) - { - // element was not returned - return; - } - switch (get_class($node)) - { - case 'stdClass': - if (property_exists($node, 'comment')) - { - self::xmlComment($xml, $node->comment); - } - if (property_exists($node, 'fieldXML')) - { - self::xmlAppend($xml, $node->fieldXML); - } - break; - case 'SimpleXMLElement': - $domXML = dom_import_simplexml($xml); - $domNode = dom_import_simplexml($node); - $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); - $xml = simplexml_import_dom($domXML); - break; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); } /** @@ -588,16 +565,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param string $comment The comment to inject * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); */ public static function xmlComment(&$xml, $comment) { - $domXML = dom_import_simplexml($xml); - $domComment = new DOMComment($comment); - $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); - $domXML->appendChild($nodeTarget); - $xml = simplexml_import_dom($domXML); + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); } /** @@ -607,14 +580,11 @@ abstract class ###Component###Helper * @param array $attributes The attributes to apply to the XML element * * @return null - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); */ public static function xmlAddAttributes(&$xml, $attributes = array()) { - foreach ($attributes as $key => $value) - { - $xml->addAttribute($key, $value); - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); } /** @@ -624,16 +594,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return void - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); */ public static function xmlAddOptions(&$xml, $options = array()) { - foreach ($options as $key => $value) - { - $addOption = $xml->addChild('option'); - $addOption->addAttribute('value', $key); - $addOption[] = $value; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); } /** @@ -644,28 +609,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); */ public static function getFieldObject(&$attributes, $default = '', $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes) && isset($attributes['type'])) - { - // make sure the form helper class is loaded - if (!method_exists('JFormHelper', 'loadFieldType')) - { - jimport('joomla.form.form'); - } - // get field type - $field = JFormHelper::loadFieldType($attributes['type'], true); - // get field xml - $XML = self::getFieldXML($attributes, $options); - // setup the field - $field->setup($XML, $default); - // return the field object - return $field; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); } /** @@ -675,27 +623,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); */ public static function getFieldXML(&$attributes, $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes)) - { - // start field xml - $XML = new SimpleXMLElement(''); - // load the attributes - self::xmlAddAttributes($XML, $attributes); - // check if we have options - if (self::checkArray($options)) - { - // load the options - self::xmlAddOptions($XML, $options); - } - // return the field xml - return $XML; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); } /** diff --git a/admin/compiler/joomla_3/JCB_Helper_site.php b/admin/compiler/joomla_3/JCB_Helper_site.php index c85a72e34..2d37461ba 100644 --- a/admin/compiler/joomla_3/JCB_Helper_site.php +++ b/admin/compiler/joomla_3/JCB_Helper_site.php @@ -303,35 +303,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param mixed $node A SimpleXMLElement node to append to the XML element reference, or a stdClass object containing a comment attribute to be injected before the XML node and a fieldXML attribute containing a SimpleXMLElement * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); */ public static function xmlAppend(&$xml, $node) { - if (!$node) - { - // element was not returned - return; - } - switch (get_class($node)) - { - case 'stdClass': - if (property_exists($node, 'comment')) - { - self::xmlComment($xml, $node->comment); - } - if (property_exists($node, 'fieldXML')) - { - self::xmlAppend($xml, $node->fieldXML); - } - break; - case 'SimpleXMLElement': - $domXML = dom_import_simplexml($xml); - $domNode = dom_import_simplexml($node); - $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); - $xml = simplexml_import_dom($domXML); - break; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::append($xml, $node); } /** @@ -340,16 +317,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param string $comment The comment to inject * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); */ public static function xmlComment(&$xml, $comment) { - $domXML = dom_import_simplexml($xml); - $domComment = new DOMComment($comment); - $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); - $domXML->appendChild($nodeTarget); - $xml = simplexml_import_dom($domXML); + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::comment($xml, $comment); } /** @@ -358,15 +331,12 @@ abstract class ###Component###Helper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param array $attributes The attributes to apply to the XML element * - * @return null - * + * @return void + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); */ public static function xmlAddAttributes(&$xml, $attributes = array()) { - foreach ($attributes as $key => $value) - { - $xml->addAttribute($key, $value); - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::attributes($xml, $attributes); } /** @@ -376,16 +346,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return void - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); */ public static function xmlAddOptions(&$xml, $options = array()) { - foreach ($options as $key => $value) - { - $addOption = $xml->addChild('option'); - $addOption->addAttribute('value', $key); - $addOption[] = $value; - } + Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::options($xml, $options); } /** @@ -396,28 +361,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); */ public static function getFieldObject(&$attributes, $default = '', $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes) && isset($attributes['type'])) - { - // make sure the form helper class is loaded - if (!method_exists('JFormHelper', 'loadFieldType')) - { - jimport('joomla.form.form'); - } - // get field type - $field = JFormHelper::loadFieldType($attributes['type'], true); - // get field xml - $XML = self::getFieldXML($attributes, $options); - // setup the field - $field->setup($XML, $default); - // return the field object - return $field; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::field($attributes, $default, $options); } /** @@ -427,27 +375,11 @@ abstract class ###Component###Helper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); */ public static function getFieldXML(&$attributes, $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes)) - { - // start field xml - $XML = new SimpleXMLElement(''); - // load the attributes - self::xmlAddAttributes($XML, $attributes); - // check if we have options - if (self::checkArray($options)) - { - // load the options - self::xmlAddOptions($XML, $options); - } - // return the field xml - return $XML; - } - return false; + return Super___1198aecf_84c6_45d2_aea8_d531aa4afdfa___Power::xml($attributes, $options); } /** diff --git a/admin/compiler/joomla_3/component_admin.php b/admin/compiler/joomla_3/component_admin.php index 622b1bde0..43ddf1f01 100644 --- a/admin/compiler/joomla_3/component_admin.php +++ b/admin/compiler/joomla_3/component_admin.php @@ -15,7 +15,7 @@ defined('_JEXEC') or die('Restricted access'); ###BOM### // No direct access to this file -defined('_JEXEC') or die('Restricted access'); +defined('_JEXEC') or die('Restricted access');###ADMIN_POWER_HELPER### ###ADMIN_COMPONENT_HEADER### diff --git a/admin/compiler/joomla_3/component_site.php b/admin/compiler/joomla_3/component_site.php index 451f984fd..88d3a5de8 100644 --- a/admin/compiler/joomla_3/component_site.php +++ b/admin/compiler/joomla_3/component_site.php @@ -15,7 +15,7 @@ defined('_JEXEC') or die('Restricted access'); ###BOM### // No direct access to this file -defined('_JEXEC') or die('Restricted access'); +defined('_JEXEC') or die('Restricted access');###ADMIN_POWER_HELPER### ###SITE_COMPONENT_HEADER### diff --git a/admin/compiler/joomla_3/getBible.txt b/admin/compiler/joomla_3/getBible.txt new file mode 100644 index 000000000..8e228213c --- /dev/null +++ b/admin/compiler/joomla_3/getBible.txt @@ -0,0 +1,10 @@ +/** + * @package getBible.net + * + * @created ###CREATIONDATE### + * @author ###AUTHOR### <###AUTHORWEBSITE###> + * @git Get Bible + * @github Get Bible + * @copyright ###COPYRIGHT### + * @license ###LICENSE### + */ \ No newline at end of file diff --git a/admin/compiler/joomla_3/settings.json b/admin/compiler/joomla_3/settings.json index a49ebc81f..0b412ee2a 100644 --- a/admin/compiler/joomla_3/settings.json +++ b/admin/compiler/joomla_3/settings.json @@ -207,6 +207,12 @@ "rename": false, "type": "file" }, + "CHANGELOG.md": { + "naam": "CHANGELOG.md", + "path": "c0mp0n3nt/", + "rename": false, + "type": "file" + }, "headercheck.php": { "naam": "headercheck.php", "path": "c0mp0n3nt/site/helpers", diff --git a/admin/compiler/joomla_3/settings_componentbuilder.json b/admin/compiler/joomla_3/settings_componentbuilder.json index d543db459..79cbabbfa 100644 --- a/admin/compiler/joomla_3/settings_componentbuilder.json +++ b/admin/compiler/joomla_3/settings_componentbuilder.json @@ -207,6 +207,12 @@ "rename": false, "type": "file" }, + "CHANGELOG.md": { + "naam": "CHANGELOG.md", + "path": "c0mp0n3nt/", + "rename": false, + "type": "file" + }, "headercheck.php": { "naam": "headercheck.php", "path": "c0mp0n3nt/site/helpers", diff --git a/admin/componentbuilder.php b/admin/componentbuilder.php index 0fcdaa5eb..53857eff6 100644 --- a/admin/componentbuilder.php +++ b/admin/componentbuilder.php @@ -12,6 +12,61 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +// add the autoloader for the composer classes +$composer_autoloader = JPATH_LIBRARIES . '/phpseclib3/vendor/autoload.php'; +if (file_exists($composer_autoloader)) +{ + require_once $composer_autoloader; +} + +// register this component namespace +spl_autoload_register(function ($class) { + // project-specific base directories and namespace prefix + $search = [ + 'libraries/jcb_powers/VDM.Joomla.Openai' => 'VDM\\Joomla\\Openai', + 'libraries/jcb_powers/VDM.Joomla.Gitea' => 'VDM\\Joomla\\Gitea', + 'libraries/jcb_powers/VDM.Joomla.FOF' => 'VDM\\Joomla\\FOF', + 'libraries/jcb_powers/VDM.Joomla' => 'VDM\\Joomla', + 'libraries/jcb_powers/VDM.Minify' => 'VDM\\Minify', + 'libraries/jcb_powers/VDM.Psr' => 'VDM\\Psr' + ]; + // Start the search and load if found + $found = false; + $found_base_dir = ""; + $found_len = 0; + foreach ($search as $base_dir => $prefix) + { + // does the class use the namespace prefix? + $len = strlen($prefix); + if (strncmp($prefix, $class, $len) === 0) + { + // we have a match so load the values + $found = true; + $found_base_dir = $base_dir; + $found_len = $len; + // done here + break; + } + } + // check if we found a match + if (!$found) + { + // not found so move to the next registered autoloader + return; + } + // get the relative class name + $relative_class = substr($class, $found_len); + // replace the namespace prefix with the base directory, replace namespace + // separators with directory separators in the relative class name, append + // with .php + $file = JPATH_ROOT . '/' . $found_base_dir . '/src' . str_replace('\\', '/', $relative_class) . '.php'; + // if the file exists, require it + if (file_exists($file)) + { + require $file; + } +}); + // Access check. diff --git a/admin/config.xml b/admin/config.xml index 4535b441b..75fbfed59 100644 --- a/admin/config.xml +++ b/admin/config.xml @@ -289,6 +289,18 @@ name="uikit_config" label="COM_COMPONENTBUILDER_CONFIG_UIKIT_LABEL" description="COM_COMPONENTBUILDER_CONFIG_UIKIT_DESC"> + + + " + " + - - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
"; + $tabs .= PHP_EOL . Indent::_(3) . ""; + $tabs .= PHP_EOL . Indent::_(2) . ""; + $tabs .= PHP_EOL . Indent::_(1) . ""; - $tabs .= PHP_EOL . $this->_t(1) . ""; + $tabs .= PHP_EOL . Indent::_(1) . ""; } return $tabs; @@ -13584,13 +12715,11 @@ class Interpretation extends Fields protected function addCustomTabs($nr, $name_single, $target) { // check if this view is having custom tabs - if (isset($this->customTabs[$name_single]) - && ArrayHelper::check( - $this->customTabs[$name_single] - )) + if (($tabs = CFactory::_('Compiler.Builder.Custom.Tabs')->get($name_single)) !== null + && ArrayHelper::check($tabs)) { - $html = array(); - foreach ($this->customTabs[$name_single] as $customTab) + $html = []; + foreach ($tabs as $customTab) { if (ArrayHelper::check($customTab) && isset($customTab['html'])) @@ -13623,42 +12752,42 @@ class Interpretation extends Fields { // set view name $fadein[] = ""; - $fadein[] = "
componentCodeName + $fadein[] = "
component_code_name . "_loader\" style=\"display: none;\">"; return implode(PHP_EOL, $fadein); } - return "
componentCodeName . "_loader\">"; + return "
component_code_name . "_loader\">"; } /** @@ -13674,26 +12803,22 @@ class Interpretation extends Fields { // first build the layout file $target = array('admin' => $nameSingleCode); - $this->buildDynamique($target, $type, $layoutName); + CFactory::_('Utilities.Structure')->build($target, $type, $layoutName); // add to front if needed - if ($this->lang === 'both') + if (CFactory::_('Config')->lang_target === 'both') { $target = array('site' => $nameSingleCode); - $this->buildDynamique($target, $type, $layoutName); + CFactory::_('Utilities.Structure')->build($target, $type, $layoutName); } if (StringHelper::check($items)) { // LAYOUTITEMS <<>> - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutName][$this->hhh . 'LAYOUTITEMS' . $this->hhh] - = $items; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutName . '|LAYOUTITEMS', $items); } else { // LAYOUTITEMS <<>> - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutName][$this->hhh . 'bogus' . $this->hhh] - = 'boom'; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutName . '|bogus', 'boom'); } } } @@ -13708,16 +12833,16 @@ class Interpretation extends Fields protected function setLayoutOverride($nameSingleCode, $layoutName, $items) { if (($data = $this->getLayoutOverride($nameSingleCode, $layoutName)) - !== false) + !== null) { // first build the layout file $target = array('admin' => $nameSingleCode); - $this->buildDynamique($target, 'layoutoverride', $layoutName); + CFactory::_('Utilities.Structure')->build($target, 'layoutoverride', $layoutName); // add to front if needed - if ($this->lang === 'both') + if (CFactory::_('Config')->lang_target === 'both') { $target = array('site' => $nameSingleCode); - $this->buildDynamique($target, 'layoutoverride', $layoutName); + CFactory::_('Utilities.Structure')->build($target, 'layoutoverride', $layoutName); } // make sure items is an empty string (should not be needed.. but) if (!StringHelper::check($items)) @@ -13725,42 +12850,36 @@ class Interpretation extends Fields $items = ''; } // set placeholder - $placeholder = $this->placeholders; - $placeholder[$this->hhh . 'LAYOUTITEMS' . $this->hhh] = $items; + $placeholder = CFactory::_('Placeholder')->active; + $placeholder[Placefix::_h('LAYOUTITEMS')] = $items; // OVERRIDE_LAYOUT_CODE <<>> - $php_view = (array) explode(PHP_EOL, $data['php_view']); + $php_view = (array) explode(PHP_EOL, (string) $data['php_view'] ?? ''); if (ArrayHelper::check($php_view)) { $php_view = PHP_EOL . PHP_EOL . implode(PHP_EOL, $php_view); - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutName][$this->hhh - . 'OVERRIDE_LAYOUT_CODE' . $this->hhh] - = $this->setPlaceholders( - $php_view, $placeholder + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutName . '|OVERRIDE_LAYOUT_CODE', + CFactory::_('Placeholder')->update( + $php_view, $placeholder + ) ); } else { - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutName][$this->hhh - . 'OVERRIDE_LAYOUT_CODE' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutName . '|OVERRIDE_LAYOUT_CODE', ''); } // OVERRIDE_LAYOUT_BODY <<>> - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutName][$this->hhh - . 'OVERRIDE_LAYOUT_BODY' . $this->hhh] - = PHP_EOL . $this->setPlaceholders( - $data['html'], $placeholder - ); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutName . '|OVERRIDE_LAYOUT_BODY', + PHP_EOL . CFactory::_('Placeholder')->update( + $data['html'] ?? '', $placeholder + ) + ); // OVERRIDE_LAYOUT_HEADER <<>> - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutName][$this->hhh - . 'OVERRIDE_LAYOUT_HEADER' . $this->hhh] - = (($header = $this->setFileHeader( - 'override.layout', - $layoutName, false) - ) !== false) ? PHP_EOL . PHP_EOL . $header : ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutName . '|OVERRIDE_LAYOUT_HEADER', + (($header = $this->setFileHeader( + 'override.layout', + $layoutName, false) + ) !== false) ? PHP_EOL . PHP_EOL . $header : '' + ); // since override was found return true; @@ -13773,69 +12892,26 @@ class Interpretation extends Fields * @param string $nameSingleCode * @param string $layoutName * - * @return array the layout data + * @return array|null the layout data */ - protected function getLayoutOverride($nameSingleCode, $layoutName) + protected function getLayoutOverride($nameSingleCode, $layoutName): ?array { + $get_key = null; // check if there is an override by component name, view name, & layout name if ($this->setTemplateAndLayoutData( 'override', $nameSingleCode, false, array(''), - array($this->componentCodeName . $nameSingleCode . $layoutName) + array(CFactory::_('Config')->component_code_name . $nameSingleCode . $layoutName) )) { - $data = $this->layoutData[$this->target][$this->componentCodeName - . $nameSingleCode . $layoutName]; - // remove since we will add the layout now - if ($this->lang === 'both') - { - unset( - $this->layoutData['admin'][$this->componentCodeName - . $nameSingleCode . $layoutName] - ); - unset( - $this->layoutData['site'][$this->componentCodeName - . $nameSingleCode . $layoutName] - ); - } - else - { - unset( - $this->layoutData[$this->target][$this->componentCodeName - . $nameSingleCode . $layoutName] - ); - } - - return $data; + $get_key = CFactory::_('Config')->component_code_name . $nameSingleCode . $layoutName; } // check if there is an override by component name & layout name elseif ($this->setTemplateAndLayoutData( 'override', $nameSingleCode, false, array(''), - array($this->componentCodeName . $layoutName) + array(CFactory::_('Config')->component_code_name . $layoutName) )) { - $data = $this->layoutData[$this->target][$this->componentCodeName - . $layoutName]; - // remove since we will add the layout now - if ($this->lang === 'both') - { - unset( - $this->layoutData['admin'][$this->componentCodeName - . $layoutName] - ); - unset( - $this->layoutData['site'][$this->componentCodeName - . $layoutName] - ); - } - else - { - unset( - $this->layoutData[$this->target][$this->componentCodeName - . $layoutName] - ); - } - - return $data; + $get_key = CFactory::_('Config')->component_code_name . $layoutName; } // check if there is an override by view & layout name elseif ($this->setTemplateAndLayoutData( @@ -13843,22 +12919,7 @@ class Interpretation extends Fields array($nameSingleCode . $layoutName) )) { - $data = $this->layoutData[$this->target][$nameSingleCode - . $layoutName]; - // remove since we will add the layout now - if ($this->lang === 'both') - { - unset( - $this->layoutData['admin'][$nameSingleCode . $layoutName] - ); - unset($this->layoutData['site'][$nameSingleCode . $layoutName]); - } - else - { - unset($this->layoutData[$this->target][$layoutName]); - } - - return $data; + $get_key = $nameSingleCode . $layoutName; } // check if there is an override by layout name (global layout) elseif ($this->setTemplateAndLayoutData( @@ -13866,22 +12927,46 @@ class Interpretation extends Fields array($layoutName) )) { - $data = $this->layoutData[$this->target][$layoutName]; - // remove since we will add the layout now - if ($this->lang === 'both') + $get_key = $layoutName; + } + + // check if we have a get key + if ($get_key) + { + $data = CFactory::_('Compiler.Builder.Layout.Data')-> + get(CFactory::_('Config')->build_target . '.' . $get_key); + + if ($data === null) { - unset($this->layoutData['admin'][$layoutName]); - unset($this->layoutData['site'][$layoutName]); + var_dump(CFactory::_('Config')->build_target . '.' . $get_key); + var_dump('admin.' .$get_key); + var_dump(CFactory::_('Compiler.Builder.Layout.Data')->get('admin.' .$get_key)); + var_dump('site.' .$get_key); + var_dump(CFactory::_('Compiler.Builder.Layout.Data')->get('site.' . $get_key)); + var_dump('both.' .$get_key); + var_dump(CFactory::_('Compiler.Builder.Layout.Data')->get('both.' . $get_key)); + exit; + } + // remove since we will add the layout now + if (CFactory::_('Config')->lang_target === 'both') + { + CFactory::_('Compiler.Builder.Layout.Data')-> + remove('admin.' . $get_key); + CFactory::_('Compiler.Builder.Layout.Data')-> + remove('site.' . $get_key); + CFactory::_('Compiler.Builder.Layout.Data')-> + remove('both.' . $get_key); } else { - unset($this->layoutData[$this->target][$layoutName]); + CFactory::_('Compiler.Builder.Layout.Data')-> + remove(CFactory::_('Config')->build_target . '.' . $get_key); } return $data; } - return false; + return null; } /** @@ -13901,7 +12986,7 @@ class Interpretation extends Fields extract($args, EXTR_PREFIX_SAME, "oops"); $single = ''; $name_list_code = ''; - foreach ($this->componentData->admin_views as $array) + foreach (CFactory::_('Component')->get('admin_views') as $array) { if ($array['adminview'] == $viewId) { @@ -13922,48 +13007,47 @@ class Interpretation extends Fields ); $functionName = StringHelper::safe($codeName, 'F'); // LAYOUTITEMSTABLE <<>> - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutCodeName][$this->hhh . 'LAYOUTITEMSTABLE' . $this->hhh] - = $head . $body; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutCodeName . '|LAYOUTITEMSTABLE', + $head . $body + ); // LAYOUTITEMSHEADER <<>> - $headerscript = '//' . $this->setLine(__LINE__) + $headerscript = '//' . Line::_(__Line__, __Class__) . ' set the edit URL'; $headerscript .= PHP_EOL . '$edit = "index.php?option=com_' - . $this->componentCodeName . '&view=' . $name_list_code + . CFactory::_('Config')->component_code_name . '&view=' . $name_list_code . '&task=' . $name_single_code . '.edit";'; - $headerscript .= PHP_EOL . '//' . $this->setLine(__LINE__) + $headerscript .= PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' set a return value'; $headerscript .= PHP_EOL . '$return = ($id) ? "index.php?option=com_' - . $this->componentCodeName . '&view=' . $nameSingleCode + . CFactory::_('Config')->component_code_name . '&view=' . $nameSingleCode . '&layout=edit&id=" . $id : "";'; - $headerscript .= PHP_EOL . '//' . $this->setLine(__LINE__) + $headerscript .= PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' check for a return value'; $headerscript .= PHP_EOL . '$jinput = JFactory::getApplication()->input;'; $headerscript .= PHP_EOL . "if (\$_return = \$jinput->get('return', null, 'base64'))"; $headerscript .= PHP_EOL . '{'; - $headerscript .= PHP_EOL . $this->_t(1) + $headerscript .= PHP_EOL . Indent::_(1) . '$return .= "&return=" . $_return;'; $headerscript .= PHP_EOL . '}'; - $headerscript .= PHP_EOL . '//' . $this->setLine(__LINE__) + $headerscript .= PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' check if return value was set'; $headerscript .= PHP_EOL . 'if (' - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper::checkString($return))'; + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper::checkString($return))'; $headerscript .= PHP_EOL . '{'; - $headerscript .= PHP_EOL . $this->_t(1) . '//' . $this->setLine( - __LINE__ + $headerscript .= PHP_EOL . Indent::_(1) . '//' . Line::_( + __LINE__,__CLASS__ ) . ' set the referral values'; - $headerscript .= PHP_EOL . $this->_t(1) . '$ref = ($id) ? "&ref=' + $headerscript .= PHP_EOL . Indent::_(1) . '$ref = ($id) ? "&ref=' . $nameSingleCode . '&refid=" . $id . "&return=" . urlencode(base64_encode($return)) : "&return=" . urlencode(base64_encode($return));'; $headerscript .= PHP_EOL . '}'; $headerscript .= PHP_EOL . 'else'; $headerscript .= PHP_EOL . '{'; - $headerscript .= PHP_EOL . $this->_t(1) . '$ref = ($id) ? "&ref=' + $headerscript .= PHP_EOL . Indent::_(1) . '$ref = ($id) ? "&ref=' . $nameSingleCode . '&refid=" . $id : "";'; $headerscript .= PHP_EOL . '}'; if ($addNewButon > 0) @@ -13971,69 +13055,66 @@ class Interpretation extends Fields // add the link for new if ($addNewButon == 1 || $addNewButon == 2) { - $headerscript .= PHP_EOL . '//' . $this->setLine(__LINE__) + $headerscript .= PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' set the create new URL'; $headerscript .= PHP_EOL . '$new = "index.php?option=com_' - . $this->componentCodeName . '&view=' . $name_list_code + . CFactory::_('Config')->component_code_name . '&view=' . $name_list_code . '&task=' . $name_single_code . '.edit" . $ref;'; } // and the link for close and new if ($addNewButon == 2 || $addNewButon == 3) { - $headerscript .= PHP_EOL . '//' . $this->setLine(__LINE__) + $headerscript .= PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' set the create new and close URL'; $headerscript .= PHP_EOL . '$close_new = "index.php?option=com_' - . $this->componentCodeName . '&view=' . $name_list_code + . CFactory::_('Config')->component_code_name . '&view=' . $name_list_code . '&task=' . $name_single_code . '.edit";'; } - $headerscript .= PHP_EOL . '//' . $this->setLine(__LINE__) + $headerscript .= PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' load the action object'; $headerscript .= PHP_EOL . '$can = ' - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper::getActions(' . "'" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper::getActions(' . "'" . $name_single_code . "'" . ');'; } - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutCodeName][$this->hhh . 'LAYOUTITEMSHEADER' . $this->hhh] - = $headerscript; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutCodeName . '|LAYOUTITEMSHEADER', + $headerscript + ); // LINKEDVIEWITEMS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWITEMS' . $this->hhh] - .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ - ) . " Get Linked view data" . PHP_EOL . $this->_t(2) + CFactory::_('Compiler.Builder.Content.Multi')->add($nameSingleCode . '|LINKEDVIEWITEMS', + PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " Get Linked view data" . PHP_EOL . Indent::_(2) . "\$this->" . $codeName . " = \$this->get('" . $functionName - . "');"; + . "');", false + ); // LINKEDVIEWTABLESCRIPTS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWTABLESCRIPTS' . $this->hhh] - = $this->setFootableScripts(); - if (strpos($parentKey, '-R>') !== false - || strpos($parentKey, '-A>') !== false) + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|LINKEDVIEWTABLESCRIPTS', $this->setFootableScripts()); + if (strpos((string) $parentKey, '-R>') !== false + || strpos((string) $parentKey, '-A>') !== false) { - list($parent_key) = explode('-', $parentKey); + list($parent_key) = explode('-', (string) $parentKey); } - elseif (strpos($parentKey, '-OR>') !== false) + elseif (strpos((string) $parentKey, '-OR>') !== false) { // this is not good... (TODO) - $parent_keys = explode('-OR>', $parentKey); + $parent_keys = explode('-OR>', (string) $parentKey); } else { $parent_key = $parentKey; } - if (strpos($key, '-R>') !== false || strpos($key, '-A>') !== false) + if (strpos((string) $key, '-R>') !== false || strpos((string) $key, '-A>') !== false) { - list($_key) = explode('-', $key); + list($_key) = explode('-', (string) $key); } - elseif (strpos($key, '-OR>') !== false) + elseif (strpos((string) $key, '-OR>') !== false) { - $_key = str_replace('-OR>', '', $key); + $_key = str_replace('-OR>', '', (string) $key); } else { @@ -14052,11 +13133,10 @@ class Interpretation extends Fields = StringHelper::safe( $_key . $this->uniquekey(4) ); - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWGLOBAL' . $this->hhh] - .= PHP_EOL . $this->_t(2) . "\$this->" - . $globalKey[$parent_key] . " = \$item->" . $parent_key - . ";"; + CFactory::_('Compiler.Builder.Content.Multi')->add($nameSingleCode . '|LINKEDVIEWGLOBAL', + PHP_EOL . Indent::_(2) . "\$this->" + . $globalKey[$parent_key] . " = \$item->" . $parent_key . ";", false + ); } } else @@ -14065,28 +13145,26 @@ class Interpretation extends Fields $globalKey = StringHelper::safe( $_key . $this->uniquekey(4) ); - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWGLOBAL' . $this->hhh] - .= PHP_EOL . $this->_t(2) . "\$this->" . $globalKey - . " = \$item->" . $parent_key . ";"; + CFactory::_('Compiler.Builder.Content.Multi')->add($nameSingleCode . '|LINKEDVIEWGLOBAL', + PHP_EOL . Indent::_(2) . "\$this->" . $globalKey + . " = \$item->" . $parent_key . ";", false + ); } // LINKEDVIEWMETHODS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWMETHODS' . $this->hhh] - .= $this->setListQueryLinked( - $name_single_code, $name_list_code, $functionName, $key, $_key, - $parentKey, - $parent_key, $globalKey + CFactory::_('Compiler.Builder.Content.Multi')->add($nameSingleCode . '|LINKEDVIEWMETHODS', + $this->setListQueryLinked( + $name_single_code, $name_list_code, $functionName, $key, $_key, + $parentKey, + $parent_key, $globalKey + ), false ); } else { - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutCodeName][$this->hhh . 'LAYOUTITEMSTABLE' . $this->hhh] - = 'oops! error.....'; - $this->fileContentDynamic[$nameSingleCode . '_' - . $layoutCodeName][$this->hhh . 'LAYOUTITEMSHEADER' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutCodeName . '|LAYOUTITEMSTABLE', + 'oops! error.....' + ); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '_' . $layoutCodeName . '|LAYOUTITEMSHEADER', ''); } } @@ -14097,93 +13175,93 @@ class Interpretation extends Fields */ public function setFootableScripts($init = true) { - if (!isset($this->footableVersion) - || 2 == $this->footableVersion) // loading version 2 + $footable_version = CFactory::_('Config')->get('footable_version', 2); + if (2 == $footable_version) // loading version 2 { - $foo = PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $foo = PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Add the CSS for Footable."; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('stylesheet', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v2/css/footable.core.min.css', ['version' => 'auto']);"; - $foo .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $foo .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Use the Metro Style"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "if (!isset(\$this->fooTableStyle) || 0 == \$this->fooTableStyle)"; - $foo .= PHP_EOL . $this->_t(2) . "{"; - $foo .= PHP_EOL . $this->_t(3) + $foo .= PHP_EOL . Indent::_(2) . "{"; + $foo .= PHP_EOL . Indent::_(3) . "JHtml::_('stylesheet', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v2/css/footable.metro.min.css', ['version' => 'auto']);"; - $foo .= PHP_EOL . $this->_t(2) . "}"; - $foo .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $foo .= PHP_EOL . Indent::_(2) . "}"; + $foo .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Use the Legacy Style."; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "elseif (isset(\$this->fooTableStyle) && 1 == \$this->fooTableStyle)"; - $foo .= PHP_EOL . $this->_t(2) . "{"; - $foo .= PHP_EOL . $this->_t(3) + $foo .= PHP_EOL . Indent::_(2) . "{"; + $foo .= PHP_EOL . Indent::_(3) . "JHtml::_('stylesheet', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v2/css/footable.standalone.min.css', ['version' => 'auto']);"; - $foo .= PHP_EOL . $this->_t(2) . "}"; - $foo .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $foo .= PHP_EOL . Indent::_(2) . "}"; + $foo .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Add the JavaScript for Footable"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('script', 'media/com_" - . $this->componentCodeName . "/footable-v2/js/footable.js', ['version' => 'auto']);"; - $foo .= PHP_EOL . $this->_t(2) + . CFactory::_('Config')->component_code_name . "/footable-v2/js/footable.js', ['version' => 'auto']);"; + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('script', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v2/js/footable.sort.js', ['version' => 'auto']);"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('script', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v2/js/footable.filter.js', ['version' => 'auto']);"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('script', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v2/js/footable.paginate.js', ['version' => 'auto']);"; if ($init) { - $foo .= PHP_EOL . PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . PHP_EOL . Indent::_(2) . '$footable = "jQuery(document).ready(function() { jQuery(function () { jQuery(' . "'.footable'" . ').footable(); }); jQuery(' . "'.nav-tabs'" . ').on(' . "'click'" . ', ' . "'li'" . ', function() { setTimeout(tableFix, 10); }); }); function tableFix() { jQuery(' . "'.footable'" . ').trigger(' . "'footable_resize'" . '); }";'; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "\$this->document->addScriptDeclaration(\$footable);" . PHP_EOL; } } - elseif (3 == $this->footableVersion) // loading version 3 + elseif (3 == $footable_version) // loading version 3 { - $foo = PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $foo = PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Add the CSS for Footable"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "\$this->document->addStyleSheet('https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css');"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('stylesheet', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v3/css/footable.standalone.min.css', ['version' => 'auto']);"; - $foo .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $foo .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Add the JavaScript for Footable (adding all functions)"; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "JHtml::_('script', 'media/com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "/footable-v3/js/footable.min.js', ['version' => 'auto']);"; if ($init) { - $foo .= PHP_EOL . PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . PHP_EOL . Indent::_(2) . '$footable = "jQuery(document).ready(function() { jQuery(function () { jQuery(' . "'.footable'" . ').footable();});});";'; - $foo .= PHP_EOL . $this->_t(2) + $foo .= PHP_EOL . Indent::_(2) . "\$this->document->addScriptDeclaration(\$footable);" . PHP_EOL; } @@ -14205,46 +13283,35 @@ class Interpretation extends Fields $refview ) { - if (isset($this->listBuilder[$nameListCode]) - && ArrayHelper::check( - $this->listBuilder[$nameListCode] - )) + if (($items = CFactory::_('Compiler.Builder.Lists')->get($nameListCode)) !== null) { // component helper name - $Helper = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper'; + $Helper = CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper'; + $footable_version = CFactory::_('Config')->get('footable_version', 2); // make sure the custom links are only added once $firstTimeBeingAdded = true; - // setup correct core target - $coreLoad = false; - $core = null; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } $counter = 0; // add the default $body = PHP_EOL . ""; $body .= PHP_EOL . " \$item): ?>"; - $body .= PHP_EOL . $this->_t(1) . "_t(2) + $body .= PHP_EOL . Indent::_(1) . "authorise('core.manage', 'com_checkin') || \$item->checked_out == \$user->id || \$item->checked_out == 0;"; - $body .= PHP_EOL . $this->_t(2) + $body .= PHP_EOL . Indent::_(2) . "\$userChkOut = JFactory::getUser(\$item->checked_out);"; - $body .= PHP_EOL . $this->_t(2) . "\$canDo = " . $Helper + $body .= PHP_EOL . Indent::_(2) . "\$canDo = " . $Helper . "::getActions('" . $nameSingleCode . "',\$item,'" . $nameListCode . "');"; - $body .= PHP_EOL . $this->_t(1) . "?>"; - $body .= PHP_EOL . $this->_t(1) . ''; + $body .= PHP_EOL . Indent::_(1) . "?>"; + $body .= PHP_EOL . Indent::_(1) . ''; // check if this view has fields that should not be escaped $doNotEscape = false; - if (isset($this->doNotEscape[$nameListCode])) + if (CFactory::_('Compiler.Builder.Do.Not.Escape')->exists($nameListCode)) { $doNotEscape = true; } // start adding the dynamic - foreach ($this->listBuilder[$nameListCode] as $item) + foreach ($items as $item) { // check if target is linked list view if (1 == $item['target'] || 4 == $item['target']) @@ -14256,7 +13323,7 @@ class Interpretation extends Fields // set the item row $itemRow = $this->getListItemBuilder( $item, $nameSingleCode, $nameListCode, $itemClass, - $doNotEscape, $coreLoad, $core, false, $ref, + $doNotEscape, false, $ref, '$displayData->escape', '$user', $refview ); // check if buttons was aready added @@ -14271,111 +13338,111 @@ class Interpretation extends Fields $firstTimeBeingAdded = false; } // add row to body - $body .= PHP_EOL . $this->_t(2) . ""; + $body .= PHP_EOL . Indent::_(2) . ""; $body .= $itemRow; $body .= $customAdminViewButtons; - $body .= PHP_EOL . $this->_t(2) . ""; + $body .= PHP_EOL . Indent::_(2) . ""; // increment counter $counter++; } } - $data_value = (3 == $this->footableVersion) ? 'data-sort-value' + $data_value = (3 == $footable_version) ? 'data-sort-value' : 'data-value'; // add the defaults - if (!isset($this->fieldsNames[$nameSingleCode]['published'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.published')) { $counter++; // add the defaults - $body .= PHP_EOL . $this->_t(2) + $body .= PHP_EOL . Indent::_(2) . "published == 1): ?>"; - $body .= PHP_EOL . $this->_t(3) . ''; - $body .= PHP_EOL . $this->_t(4) + $body .= PHP_EOL . Indent::_(4) . 'langPrefix . "_PUBLISHED'" . '); ?>">'; - $body .= PHP_EOL . $this->_t(5) . 'langPrefix . "_PUBLISHED'" . '); ?>'; - $body .= PHP_EOL . $this->_t(4) . ''; - $body .= PHP_EOL . $this->_t(3) . ''; + $body .= PHP_EOL . Indent::_(4) . ''; + $body .= PHP_EOL . Indent::_(3) . ''; - $body .= PHP_EOL . $this->_t(2) + $body .= PHP_EOL . Indent::_(2) . "published == 0): ?>"; - $body .= PHP_EOL . $this->_t(3) . ''; - $body .= PHP_EOL . $this->_t(4) + $body .= PHP_EOL . Indent::_(4) . 'langPrefix . "_INACTIVE'" . '); ?>">'; - $body .= PHP_EOL . $this->_t(5) . 'langPrefix . "_INACTIVE'" . '); ?>'; - $body .= PHP_EOL . $this->_t(4) . ''; - $body .= PHP_EOL . $this->_t(3) . ''; + $body .= PHP_EOL . Indent::_(4) . ''; + $body .= PHP_EOL . Indent::_(3) . ''; - $body .= PHP_EOL . $this->_t(2) + $body .= PHP_EOL . Indent::_(2) . "published == 2): ?>"; - $body .= PHP_EOL . $this->_t(3) . ''; - $body .= PHP_EOL . $this->_t(4) + $body .= PHP_EOL . Indent::_(4) . 'langPrefix . "_ARCHIVED'" . '); ?>">'; - $body .= PHP_EOL . $this->_t(5) . 'langPrefix . "_ARCHIVED'" . '); ?>'; - $body .= PHP_EOL . $this->_t(4) . ''; - $body .= PHP_EOL . $this->_t(3) . ''; + $body .= PHP_EOL . Indent::_(4) . ''; + $body .= PHP_EOL . Indent::_(3) . ''; - $body .= PHP_EOL . $this->_t(2) + $body .= PHP_EOL . Indent::_(2) . "published == -2): ?>"; - $body .= PHP_EOL . $this->_t(3) . ''; - $body .= PHP_EOL . $this->_t(4) + $body .= PHP_EOL . Indent::_(4) . 'langPrefix . "_TRASHED'" . '); ?>">'; - $body .= PHP_EOL . $this->_t(5) . 'langPrefix . "_TRASHED'" . '); ?>'; - $body .= PHP_EOL . $this->_t(4) . ''; - $body .= PHP_EOL . $this->_t(3) . ''; - $body .= PHP_EOL . $this->_t(2) . ''; + $body .= PHP_EOL . Indent::_(4) . ''; + $body .= PHP_EOL . Indent::_(3) . ''; + $body .= PHP_EOL . Indent::_(2) . ''; } // add the defaults - if (!isset($this->fieldsNames[$nameSingleCode]['id'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.id')) { $counter++; - $body .= PHP_EOL . $this->_t(2) + $body .= PHP_EOL . Indent::_(2) . ''; - $body .= PHP_EOL . $this->_t(3) . "id; ?>"; - $body .= PHP_EOL . $this->_t(2) . ""; + $body .= PHP_EOL . Indent::_(3) . "id; ?>"; + $body .= PHP_EOL . Indent::_(2) . ""; } - $body .= PHP_EOL . $this->_t(1) . ""; + $body .= PHP_EOL . Indent::_(1) . ""; $body .= PHP_EOL . ""; $body .= PHP_EOL . ""; - if (2 == $this->footableVersion) + if (2 == $footable_version) { $body .= PHP_EOL . ''; - $body .= PHP_EOL . $this->_t(1) . ''; - $body .= PHP_EOL . $this->_t(2) . ''; - $body .= PHP_EOL . $this->_t(3) + $body .= PHP_EOL . Indent::_(3) . ''; - $body .= PHP_EOL . $this->_t(2) . ''; - $body .= PHP_EOL . $this->_t(1) . ''; + $body .= PHP_EOL . Indent::_(2) . ''; + $body .= PHP_EOL . Indent::_(1) . ''; $body .= PHP_EOL . ''; } $body .= PHP_EOL . ''; $body .= PHP_EOL . ''; - $body .= PHP_EOL . $this->_t(1) + $body .= PHP_EOL . Indent::_(1) . '
'; - $body .= PHP_EOL . $this->_t(2) . ''; - $body .= PHP_EOL . $this->_t(1) . '
'; + $body .= PHP_EOL . Indent::_(1) . '
'; $body .= PHP_EOL . ''; // return the build @@ -14399,57 +13466,30 @@ class Interpretation extends Fields $addNewButon, $refview ) { - if (isset($this->listBuilder[$nameListCode]) - && ArrayHelper::check( - $this->listBuilder[$nameListCode] - )) + if (($items = CFactory::_('Compiler.Builder.Lists')->get($nameListCode)) !== null) { // component helper name - $Helper = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper'; + $Helper = CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper'; $head = ''; + $footable_version = CFactory::_('Config')->get('footable_version', 2); // only add new button if set if ($addNewButon > 0) { - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } - // check if the item has permissions. - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) - { - // set permissions. - $accessCheck = "\$can->get('" . $core['core.create'] . "')"; - } - else - { - // set permissions. - $accessCheck = "\$can->get('core.create')"; - } + // set permissions. + $accessCheck = "\$can->get('" . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') . "')"; // add a button for new $head = ''; // make group button if needed $tabB = ""; if ($addNewButon == 2) { - $head .= PHP_EOL . $this->_t(1) . '
'; - $tabB = $this->_t(1); + $head .= PHP_EOL . Indent::_(1) . '
'; + $tabB = Indent::_(1); } // add the new buttons if ($addNewButon == 1 || $addNewButon == 2) { - $head .= PHP_EOL . $tabB . $this->_t(1) + $head .= PHP_EOL . $tabB . Indent::_(1) . ' langPrefix . "_NEW'" . '); ?>'; @@ -14457,7 +13497,7 @@ class Interpretation extends Fields // add the close and new button if ($addNewButon == 2 || $addNewButon == 3) { - $head .= PHP_EOL . $tabB . $this->_t(1) + $head .= PHP_EOL . $tabB . Indent::_(1) . ' _t(1) . '


'; + $head .= PHP_EOL . Indent::_(1) . '


'; } else { @@ -14477,17 +13517,17 @@ class Interpretation extends Fields } $head .= ''; // set the style for V2 - $metro_blue = (2 == $this->footableVersion) ? ' metro-blue' : ''; + $metro_blue = (2 == $footable_version) ? ' metro-blue' : ''; // set the toggle for V3 - $toggle = (3 == $this->footableVersion) + $toggle = (3 == $footable_version) ? ' data-show-toggle="true" data-toggle-column="first"' : ''; // set paging - $paging = (2 == $this->footableVersion) + $paging = (2 == $footable_version) ? ' data-page-size="20" data-filter="#filter_' . $nameListCode . '"' : ' data-sorting="true" data-paging="true" data-paging-size="20" data-filtering="true"'; // add html fix for V3 - $htmlFix = (3 == $this->footableVersion) + $htmlFix = (3 == $footable_version) ? ' data-type="html" data-sort-use="text"' : ''; $head .= PHP_EOL . ''; @@ -14502,85 +13542,81 @@ class Interpretation extends Fields // make sure only first link is used as togeler $firstLink = true; // add to lang array - $this->setLangContent($this->lang, $statusLangName, 'Status'); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $statusLangName, 'Status'); // add to lang array - $this->setLangContent($this->lang, $idLangName, 'Id'); - $head .= PHP_EOL . $this->_t(1) . ""; + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $idLangName, 'Id'); + $head .= PHP_EOL . Indent::_(1) . ""; // set controller for data hiding options $controller = 1; // build the dynamic fields - foreach ($this->listBuilder[$nameListCode] as $item) + foreach ($items as $item) { // check if target is linked list view if (1 == $item['target'] || 4 == $item['target']) { // check if we have an over-ride - if (isset($this->listHeadOverRide[$nameListCode]) - && ArrayHelper::check( - $this->listHeadOverRide[$nameListCode] - ) - && isset($this->listHeadOverRide[$nameListCode][$item['id']])) + if (($list_head_override = CFactory::_('Compiler.Builder.List.Head.Override')-> + get($nameListCode . '.' . (int) $item['id'])) !== null) { - $item['lang'] - = $this->listHeadOverRide[$nameListCode][$item['id']]; + $item['lang'] = $list_head_override; } - $setin = (2 == $this->footableVersion) + $setin = (2 == $footable_version) ? ' data-hide="phone"' : ' data-breakpoints="xs sm"'; if ($controller > 3) { - $setin = (2 == $this->footableVersion) + $setin = (2 == $footable_version) ? ' data-hide="phone,tablet"' : ' data-breakpoints="xs sm md"'; } if ($controller > 6) { - $setin = (2 == $this->footableVersion) + $setin = (2 == $footable_version) ? ' data-hide="all"' : ' data-breakpoints="all"'; } if ($item['link'] && $firstLink) { - $setin = (2 == $this->footableVersion) + $setin = (2 == $footable_version) ? ' data-toggle="true"' : ''; $firstLink = false; } - $head .= PHP_EOL . $this->_t(2) . ""; - $head .= PHP_EOL . $this->_t(3) . ""; - $head .= PHP_EOL . $this->_t(2) . ""; + $head .= PHP_EOL . Indent::_(2) . ""; $controller++; } } // set some V3 attr - $data_hide = (2 == $this->footableVersion) + $data_hide = (2 == $footable_version) ? 'data-hide="phone,tablet"' : 'data-breakpoints="xs sm md"'; // add the defaults - if (!isset($this->fieldsNames[$nameSingleCode]['published'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.published')) { - $head .= PHP_EOL . $this->_t(2) . '"; + $head .= PHP_EOL . Indent::_(2) . ""; } // add the defaults - if (!isset($this->fieldsNames[$nameSingleCode]['id'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.id')) { - $data_type = (2 == $this->footableVersion) + $data_type = (2 == $footable_version) ? 'data-type="numeric"' : 'data-type="number"'; - $head .= PHP_EOL . $this->_t(2) . '"; + $head .= PHP_EOL . Indent::_(2) . ""; } - $head .= PHP_EOL . $this->_t(1) . ""; + $head .= PHP_EOL . Indent::_(1) . ""; $head .= PHP_EOL . ""; return $head; @@ -14602,111 +13638,107 @@ class Interpretation extends Fields * @return string */ public function setListQueryLinked($nameSingleCode, $nameListCode, - $functionName, $key, $_key, $parentKey, $parent_key, $globalKey - ) + $functionName, $key, $_key, $parentKey, $parent_key, $globalKey) { // check if this view has category added - if (isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.code")) { - $categoryCodeName = $this->categoryBuilder[$nameListCode]['code']; + $categoryCodeName = CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.code"); $addCategory = true; } else { $addCategory = false; } - $query = PHP_EOL . PHP_EOL . $this->_t(1) . "/**"; - $query .= PHP_EOL . $this->_t(1) . " * Method to get list data."; - $query .= PHP_EOL . $this->_t(1) . " *"; - $query .= PHP_EOL . $this->_t(1) + $query = PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $query .= PHP_EOL . Indent::_(1) . " * Method to get list data."; + $query .= PHP_EOL . Indent::_(1) . " *"; + $query .= PHP_EOL . Indent::_(1) . " * @return mixed An array of data items on success, false on failure."; - $query .= PHP_EOL . $this->_t(1) . " */"; - $query .= PHP_EOL . $this->_t(1) . "public function get" . $functionName + $query .= PHP_EOL . Indent::_(1) . " */"; + $query .= PHP_EOL . Indent::_(1) . "public function get" . $functionName . "()"; - $query .= PHP_EOL . $this->_t(1) . "{"; + $query .= PHP_EOL . Indent::_(1) . "{"; // setup the query - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Get the user object."; - $query .= PHP_EOL . $this->_t(2) . "\$user = JFactory::getUser();"; - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Create a new query object."; - $query .= PHP_EOL . $this->_t(2) . "\$db = JFactory::getDBO();"; - $query .= PHP_EOL . $this->_t(2) . "\$query = \$db->getQuery(true);"; - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(2) . "\$db = JFactory::getDBO();"; + $query .= PHP_EOL . Indent::_(2) . "\$query = \$db->getQuery(true);"; + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Select some fields"; - $query .= PHP_EOL . $this->_t(2) . "\$query->select('a.*');"; + $query .= PHP_EOL . Indent::_(2) . "\$query->select('a.*');"; // add the category if ($addCategory) { - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->select(\$db->quoteName('c.title','category_title'));"; } - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ - ) . " From the " . $this->componentCodeName . "_" + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " From the " . CFactory::_('Config')->component_code_name . "_" . $nameSingleCode . " table"; - $query .= PHP_EOL . $this->_t(2) . "\$query->from(\$db->quoteName('#__" - . $this->componentCodeName . "_" . $nameSingleCode . "', 'a'));"; + $query .= PHP_EOL . Indent::_(2) . "\$query->from(\$db->quoteName('#__" + . CFactory::_('Config')->component_code_name . "_" . $nameSingleCode . "', 'a'));"; // add the category if ($addCategory) { - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->join('LEFT', \$db->quoteName('#__categories', 'c') . ' ON (' . \$db->quoteName('a." . $categoryCodeName . "') . ' = ' . \$db->quoteName('c.id') . ')');"; } // add custom filtering php - $query .= $this->getCustomScriptBuilder( + $query .= CFactory::_('Customcode.Dispenser')->get( 'php_getlistquery', $nameSingleCode, PHP_EOL . PHP_EOL ); // add the custom fields query $query .= $this->setCustomQuery($nameListCode, $nameSingleCode); if (StringHelper::check($globalKey) && $key && strpos( - $key, '-R>' + (string) $key, '-R>' ) === false - && strpos($key, '-A>') === false - && strpos($key, '-OR>') === false + && strpos((string) $key, '-A>') === false + && strpos((string) $key, '-OR>') === false && $parentKey - && strpos($parentKey, '-R>') === false - && strpos($parentKey, '-A>') === false - && strpos($parentKey, '-OR>') === false) + && strpos((string) $parentKey, '-R>') === false + && strpos((string) $parentKey, '-A>') === false + && strpos((string) $parentKey, '-OR>') === false) { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by " . $globalKey . " global."; - $query .= PHP_EOL . $this->_t(2) . "\$" . $globalKey . " = \$this->" + $query .= PHP_EOL . Indent::_(2) . "\$" . $globalKey . " = \$this->" . $globalKey . ";"; - $query .= PHP_EOL . $this->_t(2) . "if (is_numeric(\$" . $globalKey + $query .= PHP_EOL . Indent::_(2) . "if (is_numeric(\$" . $globalKey . " ))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$query->where('a." . $key + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a." . $key . " = ' . (int) \$" . $globalKey . " );"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "elseif (is_string(\$" + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "elseif (is_string(\$" . $globalKey . "))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$query->where('a." . $key + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a." . $key . " = ' . \$db->quote(\$" . $globalKey . "));"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "else"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$query->where('a." . $key + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "else"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a." . $key . " = -5');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } - elseif (strpos($parentKey, '-OR>') !== false - || strpos($key, '-OR>') !== false) + elseif (strpos((string) $parentKey, '-OR>') !== false + || strpos((string) $key, '-OR>') !== false) { // get both strings - if (strpos($key, '-OR>') !== false) + if (strpos((string) $key, '-OR>') !== false) { - $ORarray = explode('-OR>', $key); + $ORarray = explode('-OR>', (string) $key); } else { @@ -14729,89 +13761,85 @@ class Interpretation extends Fields $ORquery['s'][] = "a." . $ORkey . " = ' . \$db->quote(\$" . $_globalKey . ")"; } - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Filter by " . $_globalKey + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Filter by " . $_globalKey . " global."; - $query .= PHP_EOL . $this->_t(2) . "\$" . $_globalKey + $query .= PHP_EOL . Indent::_(2) . "\$" . $_globalKey . " = \$this->" . $_globalKey . ";"; - $query .= PHP_EOL . $this->_t(2) . "if (is_numeric(\$" + $query .= PHP_EOL . Indent::_(2) . "if (is_numeric(\$" . $_globalKey . " ))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$query->where('" . implode( + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('" . implode( " . ' OR ", $ORquery['i'] ) . ", ' OR');"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "elseif (is_string(\$" + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "elseif (is_string(\$" . $_globalKey . "))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$query->where('" . implode( + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('" . implode( " . ' OR ", $ORquery['s'] ) . ", ' OR');"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "else"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$query->where('a." . $ORkey + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "else"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a." . $ORkey . " = -5');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } } - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - )) + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode)) { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Join over the asset groups."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->select('ag.title AS access_level');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access');"; // check if the access field was over ridden - if (!isset($this->fieldsNames[$nameSingleCode]['access'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.access')) { // component helper name - $Helper = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper'; + $Helper = CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper'; // load the access filter query code - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by access level."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$_access = \$this->getState('filter.access');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "if (\$_access && is_numeric(\$_access))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.access = ' . (int) \$_access);"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "elseif (" + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "elseif (" . $Helper . "::checkArray(\$_access))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "//" - . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Secure the array for the query"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$_access = ArrayHelper::toInteger(\$_access);"; - $query .= PHP_EOL . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " Filter by the Access Array."; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Filter by the Access Array."; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.access IN (' . implode(',', \$_access) . ')');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } // TODO the following will fight against the above access filter - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Implement View Level Access"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "if (!\$user->authorise('core.options', 'com_" - . $this->componentCodeName . "'))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + . CFactory::_('Config')->component_code_name . "'))"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$groups = implode(',', \$user->getAuthorisedViewLevels());"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.access IN (' . \$groups . ')');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } // add dynamic ordering (Linked view) if (isset($this->viewsDefaultOrdering[$nameListCode]) @@ -14823,18 +13851,18 @@ class Interpretation extends Fields as $order_field ) { - if (($order_field_name = $this->getFieldDatabaseName( + if (($order_field_name = CFactory::_('Field.Database.Name')->get( $nameListCode, $order_field['field'] // We Removed This 'listJoinBuilder' as targetArea // we will keep an eye on this )) !== false) { // default ordering is by publish and ordering - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" - . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" + . Line::_( + __LINE__,__CLASS__ ) . " Order the results by ordering"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->order('" . $order_field_name . " " . $order_field['direction'] . "');"; @@ -14844,272 +13872,258 @@ class Interpretation extends Fields else { // default ordering is by publish and ordering - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Order the results by ordering"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->order('a.published ASC');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->order('a.ordering ASC');"; } - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Load the items"; - $query .= PHP_EOL . $this->_t(2) . "\$db->setQuery(\$query);"; - $query .= PHP_EOL . $this->_t(2) . "\$db->execute();"; - $query .= PHP_EOL . $this->_t(2) . "if (\$db->getNumRows())"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "\$items = \$db->loadObjectList();"; + $query .= PHP_EOL . Indent::_(2) . "\$db->setQuery(\$query);"; + $query .= PHP_EOL . Indent::_(2) . "\$db->execute();"; + $query .= PHP_EOL . Indent::_(2) . "if (\$db->getNumRows())"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$items = \$db->loadObjectList();"; // add the fixing strings method $query .= $this->setGetItemsMethodStringFix( $nameSingleCode, $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh], - $this->_t(1) + CFactory::_('Compiler.Builder.Content.One')->get('Component'), + Indent::_(1) ); // add translations $query .= $this->setSelectionTranslationFix( $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh], - $this->_t(1) + CFactory::_('Compiler.Builder.Content.One')->get('Component'), + Indent::_(1) ); // filter by child repetable field values if (StringHelper::check($globalKey) && $key && strpos( - $key, '-R>' + (string) $key, '-R>' ) !== false - && strpos($key, '-A>') === false) + && strpos((string) $key, '-A>') === false) { - list($field, $target) = explode('-R>', $key); - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + list($field, $target) = explode('-R>', (string) $key); + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by " . $globalKey . " in this Repetable Field"; - $query .= PHP_EOL . $this->_t(3) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$items) && isset(\$this->" + $query .= PHP_EOL . Indent::_(3) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$items) && isset(\$this->" . $globalKey . "))"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "foreach (\$items as \$nr => &\$item)"; - $query .= PHP_EOL . $this->_t(4) . "{"; - $query .= PHP_EOL . $this->_t(5) . "if (isset(\$item->" . $field - . ") && " . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkJson(\$item->" . $field . "))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) + $query .= PHP_EOL . Indent::_(4) . "{"; + $query .= PHP_EOL . Indent::_(5) . "if (isset(\$item->" . $field + . ") && " . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkJson(\$item->" . $field . "))"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "\$tmpArray = json_decode(\$item->" . $field . ",true);"; - $query .= PHP_EOL . $this->_t(6) . "if (!isset(\$tmpArray['" - . $target . "']) || !" . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] . "Helper::checkArray(\$tmpArray['" + $query .= PHP_EOL . Indent::_(6) . "if (!isset(\$tmpArray['" + . $target . "']) || !" . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$tmpArray['" . $target . "']) || !in_array(\$this->" . $globalKey . ", \$tmpArray['" . $target . "']))"; - $query .= PHP_EOL . $this->_t(6) . "{"; - $query .= PHP_EOL . $this->_t(7) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(7) . "continue;"; - $query .= PHP_EOL . $this->_t(6) . "}"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "else"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(6) . "continue;"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(4) . "}"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "else"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) . "return false;"; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(6) . "{"; + $query .= PHP_EOL . Indent::_(7) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(7) . "continue;"; + $query .= PHP_EOL . Indent::_(6) . "}"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "else"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(6) . "continue;"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(4) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "else"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "return false;"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // filter by child array field values if (StringHelper::check($globalKey) && $key && strpos( - $key, '-R>' + (string) $key, '-R>' ) === false - && strpos($key, '-A>') !== false) + && strpos((string) $key, '-A>') !== false) { - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by " . $globalKey . " Array Field"; - $query .= PHP_EOL . $this->_t(3) . "\$" . $globalKey . " = \$this->" + $query .= PHP_EOL . Indent::_(3) . "\$" . $globalKey . " = \$this->" . $globalKey . ";"; - $query .= PHP_EOL . $this->_t(3) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$items) && \$" . $globalKey + $query .= PHP_EOL . Indent::_(3) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$items) && \$" . $globalKey . ")"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "foreach (\$items as \$nr => &\$item)"; - $query .= PHP_EOL . $this->_t(4) . "{"; - list($bin, $target) = explode('-A>', $key); + $query .= PHP_EOL . Indent::_(4) . "{"; + list($bin, $target) = explode('-A>', (string) $key); if (StringHelper::check($target)) { - $query .= PHP_EOL . $this->_t(5) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkJson(\$item->" . $target - . "))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "\$item->" . $target + $query .= PHP_EOL . Indent::_(5) . "if (isset(\$item->" . $target + . ") && " . CFactory::_('Compiler.Builder.Content.One')->get('Component') + . "Helper::checkJson(\$item->" . $target . "))"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "\$item->" . $target . " = json_decode(\$item->" . $target . ", true);"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "elseif (!isset(\$item->" - . $target . ") || !" . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] . "Helper::checkArray(\$item->" + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "elseif (!isset(\$item->" + . $target . ") || !" . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$item->" . $target . "))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(6) . "continue;"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "if (!in_array(\$" + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(6) . "continue;"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "if (!in_array(\$" . $globalKey . ",\$item->" . $target . "))"; } else { - $query .= PHP_EOL . $this->_t(5) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkJson(\$item->" . $_key . "))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "\$item->" . $_key + $query .= PHP_EOL . Indent::_(5) . "if (isset(\$item->" . $_key . ") && " + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkJson(\$item->" . $_key . "))"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "\$item->" . $_key . " = json_decode(\$item->" . $_key . ", true);"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "elseif (!isset(\$item->" - . $_key . ") || !" . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] . "Helper::checkArray(\$item->" + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "elseif (!isset(\$item->" + . $_key . ") || !" . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$item->" . $_key . "))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(6) . "continue;"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "if (!in_array(\$" + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(6) . "continue;"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "if (!in_array(\$" . $globalKey . ",\$item->" . $_key . "))"; } - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(6) . "continue;"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(4) . "}"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "else"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) . "return false;"; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(6) . "continue;"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(4) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "else"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "return false;"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // filter by parent repetable field values if (StringHelper::check($globalKey) && $key && strpos( - $parentKey, '-R>' + (string) $parentKey, '-R>' ) !== false - && strpos($parentKey, '-A>') === false) + && strpos((string) $parentKey, '-A>') === false) { - list($bin, $target) = explode('-R>', $parentKey); - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + list($bin, $target) = explode('-R>', (string) $parentKey); + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by " . $_key . " Repetable Field"; - $query .= PHP_EOL . $this->_t(3) . "\$" . $globalKey + $query .= PHP_EOL . Indent::_(3) . "\$" . $globalKey . " = json_decode(\$this->" . $globalKey . ",true);"; - $query .= PHP_EOL . $this->_t(3) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$items) && isset(\$" - . $globalKey . ") && " . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] . "Helper::checkArray(\$" + $query .= PHP_EOL . Indent::_(3) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$items) && isset(\$" + . $globalKey . ") && " . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$" . $globalKey . "))"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "foreach (\$items as \$nr => &\$item)"; - $query .= PHP_EOL . $this->_t(4) . "{"; - $query .= PHP_EOL . $this->_t(5) . "if (\$item->" . $_key + $query .= PHP_EOL . Indent::_(4) . "{"; + $query .= PHP_EOL . Indent::_(5) . "if (\$item->" . $_key . " && isset(\$" . $globalKey . "['" . $target . "']) && " - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$" . $globalKey . "['" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$" . $globalKey . "['" . $target . "']))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "if (!in_array(\$item->" . $_key + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "if (!in_array(\$item->" . $_key . ",\$" . $globalKey . "['" . $target . "']))"; - $query .= PHP_EOL . $this->_t(6) . "{"; - $query .= PHP_EOL . $this->_t(7) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(7) . "continue;"; - $query .= PHP_EOL . $this->_t(6) . "}"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "else"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(6) . "continue;"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(4) . "}"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "else"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) . "return false;"; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(6) . "{"; + $query .= PHP_EOL . Indent::_(7) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(7) . "continue;"; + $query .= PHP_EOL . Indent::_(6) . "}"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "else"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(6) . "continue;"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(4) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "else"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "return false;"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // filter by parent array field values if (StringHelper::check($globalKey) && $key && strpos( - $parentKey, '-R>' + (string) $parentKey, '-R>' ) === false - && strpos($parentKey, '-A>') !== false) + && strpos((string) $parentKey, '-A>') !== false) { - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by " . $globalKey . " Array Field"; - $query .= PHP_EOL . $this->_t(3) . "\$" . $globalKey . " = \$this->" + $query .= PHP_EOL . Indent::_(3) . "\$" . $globalKey . " = \$this->" . $globalKey . ";"; - $query .= PHP_EOL . $this->_t(3) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$items) && " - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$" . $globalKey . "))"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$items) && " + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$" . $globalKey . "))"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "foreach (\$items as \$nr => &\$item)"; - $query .= PHP_EOL . $this->_t(4) . "{"; - list($bin, $target) = explode('-A>', $parentKey); + $query .= PHP_EOL . Indent::_(4) . "{"; + list($bin, $target) = explode('-A>', (string) $parentKey); if (StringHelper::check($target)) { - $query .= PHP_EOL . $this->_t(5) . "if (\$item->" . $_key - . " && " . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$" . $globalKey . "['" + $query .= PHP_EOL . Indent::_(5) . "if (\$item->" . $_key + . " && " . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$" . $globalKey . "['" . $target . "']))"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "if (!in_array(\$item->" + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "if (!in_array(\$item->" . $_key . ",\$" . $globalKey . "['" . $target . "']))"; } else { - $query .= PHP_EOL . $this->_t(5) . "if (\$item->" . $_key . ")"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "if (!in_array(\$item->" + $query .= PHP_EOL . Indent::_(5) . "if (\$item->" . $_key . ")"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "if (!in_array(\$item->" . $_key . ",\$" . $globalKey . "))"; } - $query .= PHP_EOL . $this->_t(6) . "{"; - $query .= PHP_EOL . $this->_t(7) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(7) . "continue;"; - $query .= PHP_EOL . $this->_t(6) . "}"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(5) . "else"; - $query .= PHP_EOL . $this->_t(5) . "{"; - $query .= PHP_EOL . $this->_t(6) . "unset(\$items[\$nr]);"; - $query .= PHP_EOL . $this->_t(6) . "continue;"; - $query .= PHP_EOL . $this->_t(5) . "}"; - $query .= PHP_EOL . $this->_t(4) . "}"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "else"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) . "return false;"; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(6) . "{"; + $query .= PHP_EOL . Indent::_(7) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(7) . "continue;"; + $query .= PHP_EOL . Indent::_(6) . "}"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(5) . "else"; + $query .= PHP_EOL . Indent::_(5) . "{"; + $query .= PHP_EOL . Indent::_(6) . "unset(\$items[\$nr]);"; + $query .= PHP_EOL . Indent::_(6) . "continue;"; + $query .= PHP_EOL . Indent::_(5) . "}"; + $query .= PHP_EOL . Indent::_(4) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "else"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "return false;"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // add custom php to getitems method after all - $query .= $this->getCustomScriptBuilder( + $query .= CFactory::_('Customcode.Dispenser')->get( 'php_getitems_after_all', $nameSingleCode, - PHP_EOL . PHP_EOL . $this->_t(1) + PHP_EOL . PHP_EOL . Indent::_(1) ); - $query .= PHP_EOL . $this->_t(3) . "return \$items;"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "return false;"; - $query .= PHP_EOL . $this->_t(1) . "}"; + $query .= PHP_EOL . Indent::_(3) . "return \$items;"; + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "return false;"; + $query .= PHP_EOL . Indent::_(1) . "}"; // SELECTIONTRANSLATIONFIXFUNC<<>> $query .= $this->setSelectionTranslationFixFunc( $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh] + CFactory::_('Compiler.Builder.Content.One')->get('Component') ); // fixe mothod name clash @@ -15142,24 +14156,24 @@ class Interpretation extends Fields { // Load to lang $keyLang = $this->langPrefix . '_' . $custom_button['NAME']; - $this->setLangContent( - $this->lang, $keyLang, StringHelper::safe( + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $keyLang, StringHelper::safe( $custom_button['name'], 'Ww' ) ); // add cpanel button - $buttons[] = $this->_t(2) . "if (\$this->canDo->get('" + $buttons[] = Indent::_(2) . "if (\$this->canDo->get('" . $custom_button['link'] . ".access'))"; - $buttons[] = $this->_t(2) . "{"; - $buttons[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $buttons[] = Indent::_(2) . "{"; + $buttons[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " add " . $custom_button['name'] . " button."; - $buttons[] = $this->_t(3) . "JToolBarHelper::custom('" + $buttons[] = Indent::_(3) . "JToolBarHelper::custom('" . $nameListCode . ".redirectTo" . StringHelper::safe( $custom_button['link'], 'F' ) . "', '" . $custom_button['icon'] . "', '', '" . $keyLang . "', true);"; - $buttons[] = $this->_t(2) . "}"; + $buttons[] = Indent::_(2) . "}"; } if (ArrayHelper::check($buttons)) { @@ -15190,59 +14204,59 @@ class Interpretation extends Fields ) { // add the custom redirect method - $method[] = PHP_EOL . PHP_EOL . $this->_t(1) + $method[] = PHP_EOL . PHP_EOL . Indent::_(1) . "public function redirectTo" . StringHelper::safe( $custom_button['link'], 'F' ) . "()"; - $method[] = $this->_t(1) . "{"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(1) . "{"; + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check for request forgeries"; - $method[] = $this->_t(2) + $method[] = Indent::_(2) . "JSession::checkToken() or die(JText:" . ":_('JINVALID_TOKEN'));"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if export is allowed for this user."; - $method[] = $this->_t(2) . "\$user = JFactory::getUser();"; - $method[] = $this->_t(2) . "if (\$user->authorise('" + $method[] = Indent::_(2) . "\$user = JFactory::getUser();"; + $method[] = Indent::_(2) . "if (\$user->authorise('" . $custom_button['link'] . ".access', 'com_" - . $this->componentCodeName . "'))"; - $method[] = $this->_t(2) . "{"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + . CFactory::_('Config')->component_code_name . "'))"; + $method[] = Indent::_(2) . "{"; + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get the input"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$input = JFactory::getApplication()->input;"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$pks = \$input->post->get('cid', array(), 'array');"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Sanitize the input"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$pks = ArrayHelper::toInteger(\$pks);"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " convert to string"; - $method[] = $this->_t(3) . "\$ids = implode('_', \$pks);"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$ids = implode('_', \$pks);"; + $method[] = Indent::_(3) . "\$this->setRedirect(JRoute::_('index.php?option=com_" - . $this->componentCodeName . "&view=" + . CFactory::_('Config')->component_code_name . "&view=" . $custom_button['link'] . "&cid='.\$ids, false));"; - $method[] = $this->_t(3) . "return;"; - $method[] = $this->_t(2) . "}"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "return;"; + $method[] = Indent::_(2) . "}"; + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Redirect to the list screen with error."; - $method[] = $this->_t(2) . "\$message = JText:" . ":_('" + $method[] = Indent::_(2) . "\$message = JText:" . ":_('" . $this->langPrefix . "_ACCESS_TO_" . $custom_button['NAME'] . "_FAILED');"; - $method[] = $this->_t(2) + $method[] = Indent::_(2) . "\$this->setRedirect(JRoute::_('index.php?option=com_" - . $this->componentCodeName . "&view=" . $nameListCode + . CFactory::_('Config')->component_code_name . "&view=" . $nameListCode . "', false), \$message, 'error');"; - $method[] = $this->_t(2) . "return;"; - $method[] = $this->_t(1) . "}"; + $method[] = Indent::_(2) . "return;"; + $method[] = Indent::_(1) . "}"; // add to lang array $lankey = $this->langPrefix . "_ACCESS_TO_" . $custom_button['NAME'] . "_FAILED"; - $this->setLangContent( - $this->lang, $lankey, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lankey, 'Access to ' . $custom_button['link'] . ' was denied.' ); } @@ -15265,8 +14279,8 @@ class Interpretation extends Fields public function setGetItemsModelMethod(&$nameSingleCode, &$nameListCode, $config = array('functionName' => 'getExportData', - 'docDesc' => 'Method to get list export data.', - 'type' => 'export') + 'docDesc' => 'Method to get list export data.', + 'type' => 'export') ) { // start the query string @@ -15278,109 +14292,107 @@ class Interpretation extends Fields && $this->eximportView[$nameListCode]) || !$isExport) { - $query = PHP_EOL . PHP_EOL . $this->_t(1) . "/**"; - $query .= PHP_EOL . $this->_t(1) . " * " . $config['docDesc']; - $query .= PHP_EOL . $this->_t(1) . " *"; - $query .= PHP_EOL . $this->_t(1) + $query = PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $query .= PHP_EOL . Indent::_(1) . " * " . $config['docDesc']; + $query .= PHP_EOL . Indent::_(1) . " *"; + $query .= PHP_EOL . Indent::_(1) . " * @param array \$pks The ids of the items to get"; - $query .= PHP_EOL . $this->_t(1) + $query .= PHP_EOL . Indent::_(1) . " * @param JUser \$user The user making the request"; - $query .= PHP_EOL . $this->_t(1) . " *"; - $query .= PHP_EOL . $this->_t(1) + $query .= PHP_EOL . Indent::_(1) . " *"; + $query .= PHP_EOL . Indent::_(1) . " * @return mixed An array of data items on success, false on failure."; - $query .= PHP_EOL . $this->_t(1) . " */"; - $query .= PHP_EOL . $this->_t(1) . "public function " + $query .= PHP_EOL . Indent::_(1) . " */"; + $query .= PHP_EOL . Indent::_(1) . "public function " . $config['functionName'] . "(\$pks, \$user = null)"; - $query .= PHP_EOL . $this->_t(1) . "{"; - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(1) . "{"; + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " setup the query"; - $query .= PHP_EOL . $this->_t(2) . "if ((\$pks_size = " - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] + $query .= PHP_EOL . Indent::_(2) . "if ((\$pks_size = " + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$pks)) !== false || 'bulk' === \$pks)"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Set a value to know this is " . $config['type'] . " method. (USE IN CUSTOM CODE TO ALTER OUTCOME)"; - $query .= PHP_EOL . $this->_t(3) . "\$_" . $config['type'] + $query .= PHP_EOL . Indent::_(3) . "\$_" . $config['type'] . " = true;"; - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get the user object if not set."; - $query .= PHP_EOL . $this->_t(3) . "if (!isset(\$user) || !" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkObject(\$user))"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) . "\$user = JFactory::getUser();"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(3) . "if (!isset(\$user) || !" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkObject(\$user))"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "\$user = JFactory::getUser();"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Create a new query object."; - $query .= PHP_EOL . $this->_t(3) . "\$db = JFactory::getDBO();"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$db = JFactory::getDBO();"; + $query .= PHP_EOL . Indent::_(3) . "\$query = \$db->getQuery(true);"; - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Select some fields"; - $query .= PHP_EOL . $this->_t(3) . "\$query->select('a.*');"; - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ - ) . " From the " . $this->componentCodeName . "_" + $query .= PHP_EOL . Indent::_(3) . "\$query->select('a.*');"; + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " From the " . CFactory::_('Config')->component_code_name . "_" . $nameSingleCode . " table"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->from(\$db->quoteName('#__" - . $this->componentCodeName . "_" . $nameSingleCode + . CFactory::_('Config')->component_code_name . "_" . $nameSingleCode . "', 'a'));"; - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " The bulk export path"; - $query .= PHP_EOL . $this->_t(3) . "if ('bulk' === \$pks)"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "if ('bulk' === \$pks)"; + $query .= PHP_EOL . Indent::_(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "\$query->where('a.id > 0');"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " A large array of ID's will not work out well"; - $query .= PHP_EOL . $this->_t(3) . "elseif (\$pks_size > 500)"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "elseif (\$pks_size > 500)"; + $query .= PHP_EOL . Indent::_(3) . "{"; - $query .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Use lowest ID"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "\$query->where('a.id >= ' . (int) min(\$pks));"; - $query .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Use highest ID"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "\$query->where('a.id <= ' . (int) max(\$pks));"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " The normal default path"; - $query .= PHP_EOL . $this->_t(3) . "else"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "else"; + $query .= PHP_EOL . Indent::_(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "\$query->where('a.id IN (' . implode(',',\$pks) . ')');"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "}"; // add custom filtering php - $query .= $this->getCustomScriptBuilder( + $query .= CFactory::_('Customcode.Dispenser')->get( 'php_getlistquery', $nameSingleCode, - PHP_EOL . PHP_EOL . $this->_t(1) + PHP_EOL . PHP_EOL . Indent::_(1) ); // first check if we export of text only is avalable if ($this->exportTextOnly) { // add switch - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Get global switch to activate text only export"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$export_text_only = JComponentHelper::getParams('com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "')->get('export_text_only', 0);"; // first check if we have custom queries $custom_query = $this->setCustomQuery( - $nameListCode, $nameSingleCode, $this->_t(2), true + $nameListCode, $nameSingleCode, Indent::_(2), true ); } // if values were returned add the area @@ -15389,33 +14401,30 @@ class Interpretation extends Fields $custom_query )) { - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Add these queries only if text only is required"; - $query .= PHP_EOL . $this->_t(3) . "if (\$export_text_only)"; - $query .= PHP_EOL . $this->_t(3) . "{"; + $query .= PHP_EOL . Indent::_(3) . "if (\$export_text_only)"; + $query .= PHP_EOL . Indent::_(3) . "{"; // add the custom fields query $query .= $custom_query; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // add access levels if the view has access set - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - )) + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode)) { - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Implement View Level Access"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "if (!\$user->authorise('core.options', 'com_" - . $this->componentCodeName . "'))"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + . CFactory::_('Config')->component_code_name . "'))"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "\$groups = implode(',', \$user->getAuthorisedViewLevels());"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "\$query->where('a.access IN (' . \$groups . ')');"; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // add dynamic ordering (Exported data) if (isset($this->viewsDefaultOrdering[$nameListCode]) @@ -15427,15 +14436,15 @@ class Interpretation extends Fields as $order_field ) { - if (($order_field_name = $this->getFieldDatabaseName( + if (($order_field_name = CFactory::_('Field.Database.Name')->get( $nameListCode, $order_field['field'] )) !== false) { - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" - . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" + . Line::_( + __LINE__,__CLASS__ ) . " Order the results by ordering"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->order('" . $order_field_name . " " . $order_field['direction'] . "');"; @@ -15444,80 +14453,79 @@ class Interpretation extends Fields } else { - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" - . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" + . Line::_( + __LINE__,__CLASS__ ) . " Order the results by ordering"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->order('a.ordering ASC');"; } - $query .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Load the items"; - $query .= PHP_EOL . $this->_t(3) . "\$db->setQuery(\$query);"; - $query .= PHP_EOL . $this->_t(3) . "\$db->execute();"; - $query .= PHP_EOL . $this->_t(3) . "if (\$db->getNumRows())"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "\$db->setQuery(\$query);"; + $query .= PHP_EOL . Indent::_(3) . "\$db->execute();"; + $query .= PHP_EOL . Indent::_(3) . "if (\$db->getNumRows())"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "\$items = \$db->loadObjectList();"; // set the string fixing code $query .= $this->setGetItemsMethodStringFix( $nameSingleCode, $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh], - $this->_t(2), $isExport, true + CFactory::_('Compiler.Builder.Content.One')->get('Component'), + Indent::_(2), $isExport, true ); // first check if we export of text only is avalable if ($this->exportTextOnly) { $query_translations = $this->setSelectionTranslationFix( $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh], $this->_t(3) + CFactory::_('Compiler.Builder.Content.One')->get('Component'), Indent::_(3) ); } // add translations if (isset($query_translations) && StringHelper::check($query_translations)) { - $query .= PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Add these translation only if text only is required"; - $query .= PHP_EOL . $this->_t(3) . "if (\$export_text_only)"; - $query .= PHP_EOL . $this->_t(3) . "{"; + $query .= PHP_EOL . Indent::_(3) . "if (\$export_text_only)"; + $query .= PHP_EOL . Indent::_(3) . "{"; $query .= $query_translations; - $query .= PHP_EOL . $this->_t(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; } // add custom php to getItems method after all - $query .= $this->getCustomScriptBuilder( + $query .= CFactory::_('Customcode.Dispenser')->get( 'php_getitems_after_all', $nameSingleCode, - PHP_EOL . PHP_EOL . $this->_t(2) + PHP_EOL . PHP_EOL . Indent::_(2) ); // in privacy export we must return array of arrays if ('privacy' === $config['type']) { - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "return json_decode(json_encode(\$items), true);"; } else { - $query .= PHP_EOL . $this->_t(4) . "return \$items;"; + $query .= PHP_EOL . Indent::_(4) . "return \$items;"; } - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "return false;"; - $query .= PHP_EOL . $this->_t(1) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "return false;"; + $query .= PHP_EOL . Indent::_(1) . "}"; // get the header script if ($isExport) { $header = ComponentbuilderHelper::getDynamicScripts('headers'); // add getExImPortHeaders - $query .= $this->getCustomScriptBuilder( + $query .= CFactory::_('Customcode.Dispenser')->get( 'php_import_headers', 'import_' . $nameListCode, PHP_EOL . PHP_EOL, null, true, // set a default script for those with no custom script - PHP_EOL . PHP_EOL . $this->setPlaceholders( - $header, $this->placeholders + PHP_EOL . PHP_EOL . CFactory::_('Placeholder')->update_( + $header ) ); } @@ -15537,150 +14545,147 @@ class Interpretation extends Fields $method = array(); // add the export method - $method[] = PHP_EOL . PHP_EOL . $this->_t(1) + $method[] = PHP_EOL . PHP_EOL . Indent::_(1) . "public function exportData()"; - $method[] = $this->_t(1) . "{"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(1) . "{"; + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check for request forgeries"; - $method[] = $this->_t(2) . "JSession::checkToken() or die(JText:" + $method[] = Indent::_(2) . "JSession::checkToken() or die(JText:" . ":_('JINVALID_TOKEN'));"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if export is allowed for this user."; - $method[] = $this->_t(2) . "\$user = JFactory::getUser();"; - $method[] = $this->_t(2) . "if (\$user->authorise('" + $method[] = Indent::_(2) . "\$user = JFactory::getUser();"; + $method[] = Indent::_(2) . "if (\$user->authorise('" . $nameSingleCode . ".export', 'com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "') && \$user->authorise('core.export', 'com_" - . $this->componentCodeName . "'))"; - $method[] = $this->_t(2) . "{"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + . CFactory::_('Config')->component_code_name . "'))"; + $method[] = Indent::_(2) . "{"; + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get the input"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$input = JFactory::getApplication()->input;"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$pks = \$input->post->get('cid', array(), 'array');"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Sanitize the input"; - $method[] = $this->_t(3) . "\$pks = ArrayHelper::toInteger(\$pks);"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "\$pks = ArrayHelper::toInteger(\$pks);"; + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get the model"; - $method[] = $this->_t(3) . "\$model = \$this->getModel('" + $method[] = Indent::_(3) . "\$model = \$this->getModel('" . StringHelper::safe($nameListCode, 'F') . "');"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " get the data to export"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$data = \$model->getExportData(\$pks);"; - $method[] = $this->_t(3) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkArray(\$data))"; - $method[] = $this->_t(3) . "{"; - $method[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkArray(\$data))"; + $method[] = Indent::_(3) . "{"; + $method[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " now set the data to the spreadsheet"; - $method[] = $this->_t(4) . "\$date = JFactory::getDate();"; - $method[] = $this->_t(4) . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] . "Helper::xls(\$data,'" + $method[] = Indent::_(4) . "\$date = JFactory::getDate();"; + $method[] = Indent::_(4) . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::xls(\$data,'" . StringHelper::safe($nameListCode, 'F') . "_'.\$date->format('jS_F_Y'),'" . StringHelper::safe($nameListCode, 'Ww') . " exported ('.\$date->format('jS F, Y').')','" . StringHelper::safe($nameListCode, 'w') . "');"; - $method[] = $this->_t(3) . "}"; - $method[] = $this->_t(2) . "}"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "}"; + $method[] = Indent::_(2) . "}"; + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Redirect to the list screen with error."; - $method[] = $this->_t(2) . "\$message = JText:" . ":_('" + $method[] = Indent::_(2) . "\$message = JText:" . ":_('" . $this->langPrefix . "_EXPORT_FAILED');"; - $method[] = $this->_t(2) + $method[] = Indent::_(2) . "\$this->setRedirect(JRoute::_('index.php?option=com_" - . $this->componentCodeName . "&view=" . $nameListCode + . CFactory::_('Config')->component_code_name . "&view=" . $nameListCode . "', false), \$message, 'error');"; - $method[] = $this->_t(2) . "return;"; - $method[] = $this->_t(1) . "}"; + $method[] = Indent::_(2) . "return;"; + $method[] = Indent::_(1) . "}"; // add the import method - $method[] = PHP_EOL . PHP_EOL . $this->_t(1) + $method[] = PHP_EOL . PHP_EOL . Indent::_(1) . "public function importData()"; - $method[] = $this->_t(1) . "{"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(1) . "{"; + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check for request forgeries"; - $method[] = $this->_t(2) . "JSession::checkToken() or die(JText:" + $method[] = Indent::_(2) . "JSession::checkToken() or die(JText:" . ":_('JINVALID_TOKEN'));"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if import is allowed for this user."; - $method[] = $this->_t(2) . "\$user = JFactory::getUser();"; - $method[] = $this->_t(2) . "if (\$user->authorise('" + $method[] = Indent::_(2) . "\$user = JFactory::getUser();"; + $method[] = Indent::_(2) . "if (\$user->authorise('" . $nameSingleCode . ".import', 'com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "') && \$user->authorise('core.import', 'com_" - . $this->componentCodeName . "'))"; - $method[] = $this->_t(2) . "{"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + . CFactory::_('Config')->component_code_name . "'))"; + $method[] = Indent::_(2) . "{"; + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Get the import model"; - $method[] = $this->_t(3) . "\$model = \$this->getModel('" + $method[] = Indent::_(3) . "\$model = \$this->getModel('" . StringHelper::safe($nameListCode, 'F') . "');"; - $method[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " get the headers to import"; - $method[] = $this->_t(3) + $method[] = Indent::_(3) . "\$headers = \$model->getExImPortHeaders();"; - $method[] = $this->_t(3) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkObject(\$headers))"; - $method[] = $this->_t(3) . "{"; - $method[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(3) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkObject(\$headers))"; + $method[] = Indent::_(3) . "{"; + $method[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Load headers to session."; - $method[] = $this->_t(4) . "\$session = JFactory::getSession();"; - $method[] = $this->_t(4) . "\$headers = json_encode(\$headers);"; - $method[] = $this->_t(4) . "\$session->set('" . $nameSingleCode + $method[] = Indent::_(4) . "\$session = JFactory::getSession();"; + $method[] = Indent::_(4) . "\$headers = json_encode(\$headers);"; + $method[] = Indent::_(4) . "\$session->set('" . $nameSingleCode . "_VDM_IMPORTHEADERS', \$headers);"; - $method[] = $this->_t(4) . "\$session->set('backto_VDM_IMPORT', '" + $method[] = Indent::_(4) . "\$session->set('backto_VDM_IMPORT', '" . $nameListCode . "');"; - $method[] = $this->_t(4) + $method[] = Indent::_(4) . "\$session->set('dataType_VDM_IMPORTINTO', '" . $nameSingleCode . "');"; - $method[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Redirect to import view."; // add to lang array $selectImportFileNote = $this->langPrefix . "_IMPORT_SELECT_FILE_FOR_" . StringHelper::safe($nameListCode, 'U'); - $this->setLangContent( - $this->lang, $selectImportFileNote, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $selectImportFileNote, 'Select the file to import data to ' . $nameListCode . '.' ); - $method[] = $this->_t(4) . "\$message = JText:" . ":_('" + $method[] = Indent::_(4) . "\$message = JText:" . ":_('" . $selectImportFileNote . "');"; // if this view has custom script it must have as custom import (model, veiw, controller) if (isset($this->importCustomScripts[$nameListCode]) && $this->importCustomScripts[$nameListCode]) { - $method[] = $this->_t(4) + $method[] = Indent::_(4) . "\$this->setRedirect(JRoute::_('index.php?option=com_" - . $this->componentCodeName . "&view=import_" + . CFactory::_('Config')->component_code_name . "&view=import_" . $nameListCode . "', false), \$message);"; } else { - $method[] = $this->_t(4) + $method[] = Indent::_(4) . "\$this->setRedirect(JRoute::_('index.php?option=com_" - . $this->componentCodeName + . CFactory::_('Config')->component_code_name . "&view=import', false), \$message);"; } - $method[] = $this->_t(4) . "return;"; - $method[] = $this->_t(3) . "}"; - $method[] = $this->_t(2) . "}"; - $method[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $method[] = Indent::_(4) . "return;"; + $method[] = Indent::_(3) . "}"; + $method[] = Indent::_(2) . "}"; + $method[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Redirect to the list screen with error."; - $method[] = $this->_t(2) . "\$message = JText:" . ":_('" + $method[] = Indent::_(2) . "\$message = JText:" . ":_('" . $this->langPrefix . "_IMPORT_FAILED');"; - $method[] = $this->_t(2) + $method[] = Indent::_(2) . "\$this->setRedirect(JRoute::_('index.php?option=com_" - . $this->componentCodeName . "&view=" . $nameListCode + . CFactory::_('Config')->component_code_name . "&view=" . $nameListCode . "', false), \$message, 'error');"; - $method[] = $this->_t(2) . "return;"; - $method[] = $this->_t(1) . "}"; + $method[] = Indent::_(2) . "return;"; + $method[] = Indent::_(1) . "}"; return implode(PHP_EOL, $method); } @@ -15698,16 +14703,16 @@ class Interpretation extends Fields $langExport = $this->langPrefix . '_' . StringHelper::safe('Export Data', 'U'); // add to lang array - $this->setLangContent($this->lang, $langExport, 'Export Data'); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langExport, 'Export Data'); $button = array(); - $button[] = PHP_EOL . PHP_EOL . $this->_t(3) + $button[] = PHP_EOL . PHP_EOL . Indent::_(3) . "if (\$this->canDo->get('core.export') && \$this->canDo->get('" . $nameSingleCode . ".export'))"; - $button[] = $this->_t(3) . "{"; - $button[] = $this->_t(4) . "JToolBarHelper::custom('" + $button[] = Indent::_(3) . "{"; + $button[] = Indent::_(4) . "JToolBarHelper::custom('" . $nameListCode . ".exportData', 'download', '', '" . $langExport . "', true);"; - $button[] = $this->_t(3) . "}"; + $button[] = Indent::_(3) . "}"; return implode(PHP_EOL, $button); } @@ -15725,17 +14730,17 @@ class Interpretation extends Fields $langImport = $this->langPrefix . '_' . StringHelper::safe('Import Data', 'U'); // add to lang array - $this->setLangContent($this->lang, $langImport, 'Import Data'); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langImport, 'Import Data'); $button = array(); - $button[] = PHP_EOL . PHP_EOL . $this->_t(2) + $button[] = PHP_EOL . PHP_EOL . Indent::_(2) . "if (\$this->canDo->get('core.import') && \$this->canDo->get('" . $nameSingleCode . ".import'))"; - $button[] = $this->_t(2) . "{"; - $button[] = $this->_t(3) . "JToolBarHelper::custom('" + $button[] = Indent::_(2) . "{"; + $button[] = Indent::_(3) . "JToolBarHelper::custom('" . $nameListCode . ".importData', 'upload', '', '" . $langImport . "', false);"; - $button[] = $this->_t(2) . "}"; + $button[] = Indent::_(2) . "}"; return implode(PHP_EOL, $button); } @@ -15747,94 +14752,73 @@ class Interpretation extends Fields { // setup Ajax files $target = array('admin' => 'import_' . $nameListCode); - $this->buildDynamique($target, 'customimport'); + CFactory::_('Utilities.Structure')->build($target, 'customimport'); // load the custom script to the files // IMPORT_EXT_METHOD <<>> - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'IMPORT_EXT_METHOD' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_EXT_METHOD', CFactory::_('Customcode.Dispenser')->get( 'php_import_ext', 'import_' . $nameListCode, PHP_EOL, null, true - ); + )); // IMPORT_DISPLAY_METHOD_CUSTOM <<>> - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'IMPORT_DISPLAY_METHOD_CUSTOM' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_DISPLAY_METHOD_CUSTOM', CFactory::_('Customcode.Dispenser')->get( 'php_import_display', 'import_' . $nameListCode, PHP_EOL, null, true - ); + )); // IMPORT_SETDATA_METHOD <<>> - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'IMPORT_SETDATA_METHOD' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_SETDATA_METHOD', CFactory::_('Customcode.Dispenser')->get( 'php_import_setdata', 'import_' . $nameListCode, PHP_EOL, null, true - ); + )); // IMPORT_METHOD_CUSTOM <<>> - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'IMPORT_METHOD_CUSTOM' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_METHOD_CUSTOM', CFactory::_('Customcode.Dispenser')->get( 'php_import', 'import_' . $nameListCode, PHP_EOL, null, true - ); + )); // IMPORT_SAVE_METHOD <<>> - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'IMPORT_SAVE_METHOD' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_SAVE_METHOD', CFactory::_('Customcode.Dispenser')->get( 'php_import_save', 'import_' . $nameListCode, PHP_EOL, null, true - ); + )); // IMPORT_DEFAULT_VIEW_CUSTOM <<>> - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'IMPORT_DEFAULT_VIEW_CUSTOM' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_DEFAULT_VIEW_CUSTOM', CFactory::_('Customcode.Dispenser')->get( 'html_import_view', 'import_' . $nameListCode, PHP_EOL, null, true - ); + )); // insure we have the view placeholders setup - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'VIEW' . $this->hhh] - = 'IMPORT_' . $this->placeholders[$this->hhh . 'VIEWS' - . $this->hhh]; - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'View' . $this->hhh] - = 'Import_' . $this->placeholders[$this->hhh . 'views' - . $this->hhh]; - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'view' . $this->hhh] - = 'import_' . $this->placeholders[$this->hhh . 'views' - . $this->hhh]; - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'VIEWS' . $this->hhh] - = 'IMPORT_' . $this->placeholders[$this->hhh . 'VIEWS' - . $this->hhh]; - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'Views' . $this->hhh] - = 'Import_' . $this->placeholders[$this->hhh . 'views' - . $this->hhh]; - $this->fileContentDynamic['import_' . $nameListCode][$this->hhh - . 'views' . $this->hhh] - = 'import_' . $this->placeholders[$this->hhh . 'views' - . $this->hhh]; + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|VIEW', 'IMPORT_' . CFactory::_('Placeholder')->get_h('VIEWS')); + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|View', 'Import_' . CFactory::_('Placeholder')->get_h('views')); + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|view', 'import_' . CFactory::_('Placeholder')->get_h('views')); + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|VIEWS', 'IMPORT_' . CFactory::_('Placeholder')->get_h('VIEWS')); + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|Views', 'Import_' . CFactory::_('Placeholder')->get_h('views')); + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|views', 'import_' . CFactory::_('Placeholder')->get_h('views')); + + // IMPORT_CUSTOM_CONTROLLER_HEADER <<>> add the header details for the controller + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_CUSTOM_CONTROLLER_HEADER', $this->setFileHeader( + 'import.custom.controller', + $nameListCode + )); + + // IMPORT_CUSTOM_MODEL_HEADER <<>> add the header details for the model + CFactory::_('Compiler.Builder.Content.Multi')->set('import_' . $nameListCode . '|IMPORT_CUSTOM_MODEL_HEADER', $this->setFileHeader( + 'import.custom.model', + $nameListCode + )); } public function setListQuery(&$nameSingleCode, &$nameListCode) { // check if this view has category added - if (isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.code")) { - $categoryCodeName = $this->categoryBuilder[$nameListCode]['code']; + $categoryCodeName = CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.code"); $addCategory = true; $addCategoryFilter - = $this->categoryBuilder[$nameListCode]['filter']; + = CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.filter", 'error'); } else { @@ -15842,113 +14826,109 @@ class Interpretation extends Fields $addCategoryFilter = 0; } // setup the query - $query = "//" . $this->setLine(__LINE__) . " Get the user object."; - $query .= PHP_EOL . $this->_t(2) . "\$user = JFactory::getUser();"; - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query = "//" . Line::_(__Line__, __Class__) . " Get the user object."; + $query .= PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Create a new query object."; - $query .= PHP_EOL . $this->_t(2) . "\$db = JFactory::getDBO();"; - $query .= PHP_EOL . $this->_t(2) . "\$query = \$db->getQuery(true);"; - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(2) . "\$db = JFactory::getDBO();"; + $query .= PHP_EOL . Indent::_(2) . "\$query = \$db->getQuery(true);"; + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Select some fields"; - $query .= PHP_EOL . $this->_t(2) . "\$query->select('a.*');"; + $query .= PHP_EOL . Indent::_(2) . "\$query->select('a.*');"; // add the category if ($addCategory) { - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->select(\$db->quoteName('c.title','category_title'));"; } - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ - ) . " From the " . $this->componentCodeName . "_item table"; - $query .= PHP_EOL . $this->_t(2) . "\$query->from(\$db->quoteName('#__" - . $this->componentCodeName . "_" . $nameSingleCode . "', 'a'));"; + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " From the " . CFactory::_('Config')->component_code_name . "_item table"; + $query .= PHP_EOL . Indent::_(2) . "\$query->from(\$db->quoteName('#__" + . CFactory::_('Config')->component_code_name . "_" . $nameSingleCode . "', 'a'));"; // add the category if ($addCategory) { - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->join('LEFT', \$db->quoteName('#__categories', 'c') . ' ON (' . \$db->quoteName('a." . $categoryCodeName . "') . ' = ' . \$db->quoteName('c.id') . ')');"; } // add custom filtering php - $query .= $this->getCustomScriptBuilder( + $query .= CFactory::_('Customcode.Dispenser')->get( 'php_getlistquery', $nameSingleCode, PHP_EOL . PHP_EOL ); // add the custom fields query $query .= $this->setCustomQuery($nameListCode, $nameSingleCode); - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by published state"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$published = \$this->getState('filter.published');"; - $query .= PHP_EOL . $this->_t(2) . "if (is_numeric(\$published))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "if (is_numeric(\$published))"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.published = ' . (int) \$published);"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "elseif (\$published === '')"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "elseif (\$published === '')"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('(a.published = 0 OR a.published = 1)');"; - $query .= PHP_EOL . $this->_t(2) . "}"; - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - )) + $query .= PHP_EOL . Indent::_(2) . "}"; + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode)) { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Join over the asset groups."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->select('ag.title AS access_level');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access');"; // check if the access field was over ridden - if (!isset($this->fieldsNames[$nameSingleCode]['access'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.access')) { // component helper name - $Helper = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper'; + $Helper = CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper'; // load the access filter query code - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by access level."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$_access = \$this->getState('filter.access');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "if (\$_access && is_numeric(\$_access))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.access = ' . (int) \$_access);"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) . "elseif (" + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "elseif (" . $Helper . "::checkArray(\$_access))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) . "//" - . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Secure the array for the query"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$_access = ArrayHelper::toInteger(\$_access);"; - $query .= PHP_EOL . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " Filter by the Access Array."; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Filter by the Access Array."; + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.access IN (' . implode(',', \$_access) . ')');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } // TODO the following will fight against the above access filter - $query .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Implement View Level Access"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "if (!\$user->authorise('core.options', 'com_" - . $this->componentCodeName . "'))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + . CFactory::_('Config')->component_code_name . "'))"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$groups = implode(',', \$user->getAuthorisedViewLevels());"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a.access IN (' . \$groups . ')');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } // set the search query $query .= $this->setSearchQuery($nameListCode); @@ -15957,38 +14937,38 @@ class Interpretation extends Fields // add the category if ($addCategory && $addCategoryFilter >= 1) { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Filter by a single or group of categories."; - $query .= PHP_EOL . $this->_t(2) . "\$baselevel = 1;"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$baselevel = 1;"; + $query .= PHP_EOL . Indent::_(2) . "\$categoryId = \$this->getState('filter.category_id');"; $query .= PHP_EOL; - $query .= PHP_EOL . $this->_t(2) . "if (is_numeric(\$categoryId))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "if (is_numeric(\$categoryId))"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$cat_tbl = JTable::getInstance('Category', 'JTable');"; - $query .= PHP_EOL . $this->_t(3) . "\$cat_tbl->load(\$categoryId);"; - $query .= PHP_EOL . $this->_t(3) . "\$rgt = \$cat_tbl->rgt;"; - $query .= PHP_EOL . $this->_t(3) . "\$lft = \$cat_tbl->lft;"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$cat_tbl->load(\$categoryId);"; + $query .= PHP_EOL . Indent::_(3) . "\$rgt = \$cat_tbl->rgt;"; + $query .= PHP_EOL . Indent::_(3) . "\$lft = \$cat_tbl->lft;"; + $query .= PHP_EOL . Indent::_(3) . "\$baselevel = (int) \$cat_tbl->level;"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->where('c.lft >= ' . (int) \$lft)"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(4) . "->where('c.rgt <= ' . (int) \$rgt);"; - $query .= PHP_EOL . $this->_t(2) . "}"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "elseif (is_array(\$categoryId))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$categoryId = ArrayHelper::toInteger(\$categoryId);"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$categoryId = implode(',', \$categoryId);"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(3) . "\$query->where('a." . $categoryCodeName . " IN (' . \$categoryId . ')');"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; $query .= PHP_EOL; } // setup values for the view ordering @@ -16004,7 +14984,7 @@ class Interpretation extends Fields as $order_field ) { - if (($order_field_name = $this->getFieldDatabaseName( + if (($order_field_name = CFactory::_('Field.Database.Name')->get( $nameListCode, $order_field['field'] )) !== false) { @@ -16012,30 +14992,30 @@ class Interpretation extends Fields { // just the first field is based on state $order_first = false; - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" - . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" + . Line::_( + __LINE__,__CLASS__ ) . " Add the list ordering clause."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$orderCol = \$this->state->get('list.ordering', '" . $order_field_name . "');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$orderDirn = \$this->state->get('list.direction', '" . $order_field['direction'] . "');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "if (\$orderCol != '')"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->order(\$db->escape(\$orderCol . ' ' . \$orderDirn));"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } else { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" - . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" + . Line::_( + __LINE__,__CLASS__ ) . " Add a permanent list ordering."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$query->order(\$db->escape('" . $order_field_name . " " . $order_field['direction'] . "'));"; @@ -16045,35 +15025,32 @@ class Interpretation extends Fields } else { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Add the list ordering clause."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$orderCol = \$this->state->get('list.ordering', 'a.id');"; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$orderDirn = \$this->state->get('list.direction', 'desc');"; - $query .= PHP_EOL . $this->_t(2) . "if (\$orderCol != '')"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "if (\$orderCol != '')"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "\$query->order(\$db->escape(\$orderCol . ' ' . \$orderDirn));"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; } $query .= PHP_EOL; - $query .= PHP_EOL . $this->_t(2) . "return \$query;"; + $query .= PHP_EOL . Indent::_(2) . "return \$query;"; return $query; } public function setSearchQuery($nameListCode) { - if (isset($this->searchBuilder[$nameListCode]) - && ArrayHelper::check( - $this->searchBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Search')->exists($nameListCode)) { // setup the searh options $search = "'("; - foreach ($this->searchBuilder[$nameListCode] as $nr => $array) + foreach (CFactory::_('Compiler.Builder.Search')->get($nameListCode) as $nr => $array) { // array( 'type' => $typeName, 'code' => $name, 'custom' => $custom, 'list' => $field['list']); if ($nr == 0) @@ -16099,26 +15076,26 @@ class Interpretation extends Fields } $search .= ")'"; // now setup query - $query = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $query = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Filter by search."; - $query .= PHP_EOL . $this->_t(2) + $query .= PHP_EOL . Indent::_(2) . "\$search = \$this->getState('filter.search');"; - $query .= PHP_EOL . $this->_t(2) . "if (!empty(\$search))"; - $query .= PHP_EOL . $this->_t(2) . "{"; - $query .= PHP_EOL . $this->_t(3) + $query .= PHP_EOL . Indent::_(2) . "if (!empty(\$search))"; + $query .= PHP_EOL . Indent::_(2) . "{"; + $query .= PHP_EOL . Indent::_(3) . "if (stripos(\$search, 'id:') === 0)"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "\$query->where('a.id = ' . (int) substr(\$search, 3));"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(3) . "else"; - $query .= PHP_EOL . $this->_t(3) . "{"; - $query .= PHP_EOL . $this->_t(4) + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(3) . "else"; + $query .= PHP_EOL . Indent::_(3) . "{"; + $query .= PHP_EOL . Indent::_(4) . "\$search = \$db->quote('%' . \$db->escape(\$search) . '%');"; - $query .= PHP_EOL . $this->_t(4) . "\$query->where(" . $search + $query .= PHP_EOL . Indent::_(4) . "\$query->where(" . $search . ");"; - $query .= PHP_EOL . $this->_t(3) . "}"; - $query .= PHP_EOL . $this->_t(2) . "}"; + $query .= PHP_EOL . Indent::_(3) . "}"; + $query .= PHP_EOL . Indent::_(2) . "}"; $query .= PHP_EOL; return $query; @@ -16132,36 +15109,22 @@ class Interpretation extends Fields $just_text = false ) { - if (isset($this->customBuilder[$nameListCode]) - && ArrayHelper::check( - $this->customBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Custom.Field')->exists($nameListCode)) { $query = ""; - foreach ($this->customBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Custom.Field')->get($nameListCode) as $filter) { // only load this if table is set - if ((isset($this->customBuilderList[$nameListCode]) - && ArrayHelper::check( - $this->customBuilderList[$nameListCode] - ) - && in_array( - $filter['code'], - $this->customBuilderList[$nameListCode] - ) + if ((CFactory::_('Compiler.Builder.Custom.List')->exists($nameSingleCode . '.' . $filter['code']) && isset($filter['custom']['table']) - && StringHelper::check( - $filter['custom']['table'] - ) + && StringHelper::check($filter['custom']['table']) && $filter['method'] == 0) || ($just_text && isset($filter['custom']['table']) - && StringHelper::check( - $filter['custom']['table'] - ) + && StringHelper::check($filter['custom']['table']) && $filter['method'] == 0)) { - $query .= PHP_EOL . PHP_EOL . $this->_t(2) . $tab . "//" - . $this->setLine(__LINE__) . " From the " + $query .= PHP_EOL . PHP_EOL . Indent::_(2) . $tab . "//" + . Line::_(__Line__, __Class__) . " From the " . StringHelper::safe( StringHelper::safe( $filter['custom']['table'], 'w' @@ -16174,7 +15137,7 @@ class Interpretation extends Fields // we want to at times just have the words and not the ids as well if ($just_text) { - $query .= PHP_EOL . $this->_t(2) . $tab + $query .= PHP_EOL . Indent::_(2) . $tab . "\$query->select(\$db->quoteName(['" . $filter['custom']['db'] . "." . $filter['custom']['text'] . "','" @@ -16184,7 +15147,7 @@ class Interpretation extends Fields } else { - $query .= PHP_EOL . $this->_t(2) . $tab + $query .= PHP_EOL . Indent::_(2) . $tab . "\$query->select(\$db->quoteName(['" . $filter['custom']['db'] . "." . $filter['custom']['text'] . "','" @@ -16198,7 +15161,7 @@ class Interpretation extends Fields // we want to at times just have the words and not the ids as well if ($just_text) { - $query .= PHP_EOL . $this->_t(2) . $tab + $query .= PHP_EOL . Indent::_(2) . $tab . "\$query->select(\$db->quoteName('" . $filter['custom']['db'] . "." . $filter['custom']['text'] . "','" @@ -16206,7 +15169,7 @@ class Interpretation extends Fields } else { - $query .= PHP_EOL . $this->_t(2) . $tab + $query .= PHP_EOL . Indent::_(2) . $tab . "\$query->select(\$db->quoteName('" . $filter['custom']['db'] . "." . $filter['custom']['text'] . "','" @@ -16214,7 +15177,7 @@ class Interpretation extends Fields . "'));"; } } - $query .= PHP_EOL . $this->_t(2) . $tab + $query .= PHP_EOL . Indent::_(2) . $tab . "\$query->join('LEFT', \$db->quoteName('" . $filter['custom']['table'] . "', '" . $filter['custom']['db'] @@ -16224,7 +15187,7 @@ class Interpretation extends Fields . $filter['custom']['id'] . "') . ')');"; } // build the field type file - $this->setCustomFieldTypeFile( + CFactory::_('Compiler.Creator.Custom.Field.Type.File')->set( $filter, $nameListCode, $nameSingleCode ); } @@ -16243,28 +15206,23 @@ class Interpretation extends Fields */ public function setFilterQuery($nameListCode) { - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { // component helper name - $Helper = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper'; + $Helper = CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper'; // start building the filter query $filterQuery = ""; - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { // only add for none category fields if ($filter['type'] != 'category') { - $filterQuery .= PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Filter by " - . ucwords($filter['code']) . "."; + $filterQuery .= PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Filter by " + . ucwords((string) $filter['code']) . "."; // we only add multi filter option if new filter type // and we have multi filter set for this field (2 = topbar) - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 2 + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 2 && isset($filter['multi']) && $filter['multi'] == 2) { @@ -16299,34 +15257,34 @@ class Interpretation extends Fields */ protected function setSingleFilterQuery($filter, $Helper, $a = "a") { - $filterQuery = PHP_EOL . $this->_t(2) . "\$_" + $filterQuery = PHP_EOL . Indent::_(2) . "\$_" . $filter['code'] . " = \$this->getState('filter." . $filter['code'] . "');"; - $filterQuery .= PHP_EOL . $this->_t(2) . "if (is_numeric(\$_" + $filterQuery .= PHP_EOL . Indent::_(2) . "if (is_numeric(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(2) . "{"; - $filterQuery .= PHP_EOL . $this->_t(3) . "if (is_float(\$_" + $filterQuery .= PHP_EOL . Indent::_(2) . "{"; + $filterQuery .= PHP_EOL . Indent::_(3) . "if (is_float(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(3) . "{"; - $filterQuery .= PHP_EOL . $this->_t(4) + $filterQuery .= PHP_EOL . Indent::_(3) . "{"; + $filterQuery .= PHP_EOL . Indent::_(4) . "\$query->where('" . $a . "." . $filter['code'] . " = ' . (float) \$_" . $filter['code'] . ");"; - $filterQuery .= PHP_EOL . $this->_t(3) . "}"; - $filterQuery .= PHP_EOL . $this->_t(3) . "else"; - $filterQuery .= PHP_EOL . $this->_t(3) . "{"; - $filterQuery .= PHP_EOL . $this->_t(4) + $filterQuery .= PHP_EOL . Indent::_(3) . "}"; + $filterQuery .= PHP_EOL . Indent::_(3) . "else"; + $filterQuery .= PHP_EOL . Indent::_(3) . "{"; + $filterQuery .= PHP_EOL . Indent::_(4) . "\$query->where('" . $a . "." . $filter['code'] . " = ' . (int) \$_" . $filter['code'] . ");"; - $filterQuery .= PHP_EOL . $this->_t(3) . "}"; - $filterQuery .= PHP_EOL . $this->_t(2) . "}"; - $filterQuery .= PHP_EOL . $this->_t(2) . "elseif (" + $filterQuery .= PHP_EOL . Indent::_(3) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "elseif (" . $Helper . "::checkString(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(2) . "{"; - $filterQuery .= PHP_EOL . $this->_t(3) + $filterQuery .= PHP_EOL . Indent::_(2) . "{"; + $filterQuery .= PHP_EOL . Indent::_(3) . "\$query->where('" . $a . "." . $filter['code'] . " = ' . \$db->quote(\$db->escape(\$_" . $filter['code'] . ")));"; - $filterQuery .= PHP_EOL . $this->_t(2) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "}"; return $filterQuery; } @@ -16343,71 +15301,71 @@ class Interpretation extends Fields */ protected function setMultiFilterQuery($filter, $Helper, $a = "a") { - $filterQuery = PHP_EOL . $this->_t(2) . "\$_" + $filterQuery = PHP_EOL . Indent::_(2) . "\$_" . $filter['code'] . " = \$this->getState('filter." . $filter['code'] . "');"; - $filterQuery .= PHP_EOL . $this->_t(2) . "if (is_numeric(\$_" + $filterQuery .= PHP_EOL . Indent::_(2) . "if (is_numeric(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(2) . "{"; - $filterQuery .= PHP_EOL . $this->_t(3) . "if (is_float(\$_" + $filterQuery .= PHP_EOL . Indent::_(2) . "{"; + $filterQuery .= PHP_EOL . Indent::_(3) . "if (is_float(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(3) . "{"; - $filterQuery .= PHP_EOL . $this->_t(4) + $filterQuery .= PHP_EOL . Indent::_(3) . "{"; + $filterQuery .= PHP_EOL . Indent::_(4) . "\$query->where('" . $a . "." . $filter['code'] . " = ' . (float) \$_" . $filter['code'] . ");"; - $filterQuery .= PHP_EOL . $this->_t(3) . "}"; - $filterQuery .= PHP_EOL . $this->_t(3) . "else"; - $filterQuery .= PHP_EOL . $this->_t(3) . "{"; - $filterQuery .= PHP_EOL . $this->_t(4) + $filterQuery .= PHP_EOL . Indent::_(3) . "}"; + $filterQuery .= PHP_EOL . Indent::_(3) . "else"; + $filterQuery .= PHP_EOL . Indent::_(3) . "{"; + $filterQuery .= PHP_EOL . Indent::_(4) . "\$query->where('" . $a . "." . $filter['code'] . " = ' . (int) \$_" . $filter['code'] . ");"; - $filterQuery .= PHP_EOL . $this->_t(3) . "}"; - $filterQuery .= PHP_EOL . $this->_t(2) . "}"; - $filterQuery .= PHP_EOL . $this->_t(2) . "elseif (" + $filterQuery .= PHP_EOL . Indent::_(3) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "elseif (" . $Helper . "::checkString(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(2) . "{"; - $filterQuery .= PHP_EOL . $this->_t(3) + $filterQuery .= PHP_EOL . Indent::_(2) . "{"; + $filterQuery .= PHP_EOL . Indent::_(3) . "\$query->where('" . $a . "." . $filter['code'] . " = ' . \$db->quote(\$db->escape(\$_" . $filter['code'] . ")));"; - $filterQuery .= PHP_EOL . $this->_t(2) . "}"; - $filterQuery .= PHP_EOL . $this->_t(2) . "elseif (" + $filterQuery .= PHP_EOL . Indent::_(2) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "elseif (" . $Helper . "::checkArray(\$_" . $filter['code'] . "))"; - $filterQuery .= PHP_EOL . $this->_t(2) . "{"; + $filterQuery .= PHP_EOL . Indent::_(2) . "{"; - $filterQuery .= PHP_EOL . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " Secure the array for the query"; + $filterQuery .= PHP_EOL . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Secure the array for the query"; - $filterQuery .= PHP_EOL . $this->_t(3) . "\$_" . $filter['code'] + $filterQuery .= PHP_EOL . Indent::_(3) . "\$_" . $filter['code'] . " = array_map( function (\$val) use(&\$db) {"; - $filterQuery .= PHP_EOL . $this->_t(4) . "if (is_numeric(\$val))"; - $filterQuery .= PHP_EOL . $this->_t(4) . "{"; - $filterQuery .= PHP_EOL . $this->_t(5) . "if (is_float(\$val))"; - $filterQuery .= PHP_EOL . $this->_t(5) . "{"; - $filterQuery .= PHP_EOL . $this->_t(6) . "return (float) \$val;"; - $filterQuery .= PHP_EOL . $this->_t(5) . "}"; - $filterQuery .= PHP_EOL . $this->_t(5) . "else"; - $filterQuery .= PHP_EOL . $this->_t(5) . "{"; - $filterQuery .= PHP_EOL . $this->_t(6) . "return (int) \$val;"; - $filterQuery .= PHP_EOL . $this->_t(5) . "}"; - $filterQuery .= PHP_EOL . $this->_t(4) . "}"; - $filterQuery .= PHP_EOL . $this->_t(4) . "elseif (" + $filterQuery .= PHP_EOL . Indent::_(4) . "if (is_numeric(\$val))"; + $filterQuery .= PHP_EOL . Indent::_(4) . "{"; + $filterQuery .= PHP_EOL . Indent::_(5) . "if (is_float(\$val))"; + $filterQuery .= PHP_EOL . Indent::_(5) . "{"; + $filterQuery .= PHP_EOL . Indent::_(6) . "return (float) \$val;"; + $filterQuery .= PHP_EOL . Indent::_(5) . "}"; + $filterQuery .= PHP_EOL . Indent::_(5) . "else"; + $filterQuery .= PHP_EOL . Indent::_(5) . "{"; + $filterQuery .= PHP_EOL . Indent::_(6) . "return (int) \$val;"; + $filterQuery .= PHP_EOL . Indent::_(5) . "}"; + $filterQuery .= PHP_EOL . Indent::_(4) . "}"; + $filterQuery .= PHP_EOL . Indent::_(4) . "elseif (" . $Helper . "::checkString(\$val))"; - $filterQuery .= PHP_EOL . $this->_t(4) . "{"; - $filterQuery .= PHP_EOL . $this->_t(5) + $filterQuery .= PHP_EOL . Indent::_(4) . "{"; + $filterQuery .= PHP_EOL . Indent::_(5) . "return \$db->quote(\$db->escape(\$val));"; - $filterQuery .= PHP_EOL . $this->_t(4) . "}"; - $filterQuery .= PHP_EOL . $this->_t(3) . "}, \$_" + $filterQuery .= PHP_EOL . Indent::_(4) . "}"; + $filterQuery .= PHP_EOL . Indent::_(3) . "}, \$_" . $filter['code'] . ");"; - $filterQuery .= PHP_EOL . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " Filter by the " - . ucwords($filter['code']) . " Array."; + $filterQuery .= PHP_EOL . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Filter by the " + . ucwords((string) $filter['code']) . " Array."; - $filterQuery .= PHP_EOL . $this->_t(3) + $filterQuery .= PHP_EOL . Indent::_(3) . "\$query->where('" . $a . "." . $filter['code'] . " IN (' . implode(',', \$_" . $filter['code'] . ") . ')');"; - $filterQuery .= PHP_EOL . $this->_t(2) . "}"; + $filterQuery .= PHP_EOL . Indent::_(2) . "}"; return $filterQuery; } @@ -16459,7 +15417,7 @@ class Interpretation extends Fields $behaviors[$matchName] = $targetBehavior; $defaults[$matchName] = $targetDefault; $toggleSwitch[$matchName] - = ($condition['target_behavior'] + = ($condition['target_behavior'] == 1 || $condition['target_behavior'] == 2) ? true : false; @@ -16468,7 +15426,7 @@ class Interpretation extends Fields // set function array $functions[$uniqueVar][0] = $matchName; $matchNames[$matchName] - = $condition['match_name']; + = $condition['match_name']; // get the select value $getValue[$matchName] = $this->getValueScript( $condition['match_type'], @@ -16507,20 +15465,20 @@ class Interpretation extends Fields // set function array $functions[$uniqueVar][] = $relationName; $matchNames[$relationName] - = $relation['match_name']; + = $relation['match_name']; // get the relation option $relationOptions = $this->getOptionsScript( $relation['match_type'], $relation['match_options'] ); $getValue[$relationName] - = $this->getValueScript( + = $this->getValueScript( $relation['match_type'], $relation['match_name'], $condition['match_extends'], $uniqueVar ); $ifValue[$relationName] - = $this->ifValueScript( + = $this->ifValueScript( $relationName, $relation['match_behavior'], $relation['match_type'], @@ -16536,7 +15494,7 @@ class Interpretation extends Fields $behaviors[$matchName] = $targetBehavior; $defaults[$matchName] = $targetDefault; $toggleSwitch[$matchName] - = ($condition['target_behavior'] + = ($condition['target_behavior'] == 1 || $condition['target_behavior'] == 2) ? true : false; @@ -16579,7 +15537,7 @@ class Interpretation extends Fields if (ArrayHelper::check($functions)) { // now build the initial script - $initial .= "//" . $this->setLine(__LINE__) . " Initial Script" + $initial .= "//" . Line::_(__Line__, __Class__) . " Initial Script" . PHP_EOL . "jQuery(document).ready(function()"; $initial .= PHP_EOL . "{"; foreach ($functions as $function => $matchKeys) @@ -16604,31 +15562,19 @@ class Interpretation extends Fields $l_function, $l_matchKeys, $getValue ); - if (isset($this->setScriptMediaSwitch) - && ArrayHelper::check( - $this->setScriptMediaSwitch - ) - && in_array( - $matchTypeKey, $this->setScriptMediaSwitch - )) + if (CFactory::_('Compiler.Builder.Script.Media.Switch')->inArray($matchTypeKey)) { $modal .= $funcCall['code']; } else { - if (isset($this->setScriptUserSwitch) - && ArrayHelper::check( - $this->setScriptUserSwitch - ) - && in_array( - $matchTypeKey, $this->setScriptUserSwitch - )) + if (CFactory::_('Compiler.Builder.Script.User.Switch')->inArray($matchTypeKey)) { $name = $name . '_id'; } - $listener .= PHP_EOL . "//" . $this->setLine( - __LINE__ + $listener .= PHP_EOL . "//" . Line::_( + __LINE__,__CLASS__ ) . " #jform_" . $name . " listeners for " . $l_matchKey . " function"; $listener .= PHP_EOL . "jQuery('#jform_" . $name @@ -16640,7 +15586,7 @@ class Interpretation extends Fields . "jQuery('#adminForm').on('change', '#jform_" . $name . "',function (e)"; $listener .= PHP_EOL . "{"; - $listener .= PHP_EOL . $this->_t(1) + $listener .= PHP_EOL . Indent::_(1) . "e.preventDefault();"; $listener .= $funcCall['code']; $listener .= PHP_EOL . "});" . PHP_EOL; @@ -16650,9 +15596,9 @@ class Interpretation extends Fields if (StringHelper::check($modal)) { $listener .= PHP_EOL . "window.SqueezeBox.initialize({"; - $listener .= PHP_EOL . $this->_t(1) . "onClose:function(){"; + $listener .= PHP_EOL . Indent::_(1) . "onClose:function(){"; $listener .= $modal; - $listener .= PHP_EOL . $this->_t(1) . "}"; + $listener .= PHP_EOL . Indent::_(1) . "}"; $listener .= PHP_EOL . "});" . PHP_EOL; } @@ -16672,7 +15618,7 @@ class Interpretation extends Fields { $addArray = true; } - $func .= PHP_EOL . "//" . $this->setLine(__LINE__) + $func .= PHP_EOL . "//" . Line::_(__Line__, __Class__) . " the " . $f_function . " function"; $func .= PHP_EOL . "function " . $f_function . "("; $fucounter = 0; @@ -16698,52 +15644,52 @@ class Interpretation extends Fields foreach ($f_matchKeys as $a_matchKey) { $name = $matchNames[$a_matchKey]; - $func .= PHP_EOL . $this->_t(1) . "if (isSet(" + $func .= PHP_EOL . Indent::_(1) . "if (isSet(" . $a_matchKey . ") && " . $a_matchKey . ".constructor !== Array)" . PHP_EOL - . $this->_t(1) . "{" . PHP_EOL . $this->_t(2) + . Indent::_(1) . "{" . PHP_EOL . Indent::_(2) . "var temp_" . $f_function . " = " - . $a_matchKey . ";" . PHP_EOL . $this->_t(2) + . $a_matchKey . ";" . PHP_EOL . Indent::_(2) . "var " . $a_matchKey . " = [];" . PHP_EOL - . $this->_t(2) . $a_matchKey . ".push(temp_" - . $f_function . ");" . PHP_EOL . $this->_t(1) + . Indent::_(2) . $a_matchKey . ".push(temp_" + . $f_function . ");" . PHP_EOL . Indent::_(1) . "}"; - $func .= PHP_EOL . $this->_t(1) . "else if (!isSet(" - . $a_matchKey . "))" . PHP_EOL . $this->_t(1) + $func .= PHP_EOL . Indent::_(1) . "else if (!isSet(" + . $a_matchKey . "))" . PHP_EOL . Indent::_(1) . "{"; - $func .= PHP_EOL . $this->_t(2) . "var " + $func .= PHP_EOL . Indent::_(2) . "var " . $a_matchKey . " = [];"; - $func .= PHP_EOL . $this->_t(1) . "}"; - $func .= PHP_EOL . $this->_t(1) . "var " . $name + $func .= PHP_EOL . Indent::_(1) . "}"; + $func .= PHP_EOL . Indent::_(1) . "var " . $name . " = " . $a_matchKey . ".some(" . $a_matchKey . "_SomeFunc);" . PHP_EOL; // setup the map function - $map .= PHP_EOL . "//" . $this->setLine(__LINE__) + $map .= PHP_EOL . "//" . Line::_(__Line__, __Class__) . " the " . $f_function . " Some function"; $map .= PHP_EOL . "function " . $a_matchKey . "_SomeFunc(" . $a_matchKey . ")"; $map .= PHP_EOL . "{"; - $map .= PHP_EOL . $this->_t(1) . "//" - . $this->setLine(__LINE__) + $map .= PHP_EOL . Indent::_(1) . "//" + . Line::_(__Line__, __Class__) . " set the function logic"; - $map .= PHP_EOL . $this->_t(1) . "if ("; + $map .= PHP_EOL . Indent::_(1) . "if ("; $if = $ifValue[$a_matchKey]; if (StringHelper::check($if)) { $map .= $if; } $map .= ")"; - $map .= PHP_EOL . $this->_t(1) . "{"; - $map .= PHP_EOL . $this->_t(2) . "return true;"; - $map .= PHP_EOL . $this->_t(1) . "}" . PHP_EOL - . $this->_t(1) . "return false;"; + $map .= PHP_EOL . Indent::_(1) . "{"; + $map .= PHP_EOL . Indent::_(2) . "return true;"; + $map .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL + . Indent::_(1) . "return false;"; $map .= PHP_EOL . "}" . PHP_EOL; } - $func .= PHP_EOL . PHP_EOL . $this->_t(1) . "//" - . $this->setLine(__LINE__) + $func .= PHP_EOL . PHP_EOL . Indent::_(1) . "//" + . Line::_(__Line__, __Class__) . " set this function logic"; - $func .= PHP_EOL . $this->_t(1) . "if ("; + $func .= PHP_EOL . Indent::_(1) . "if ("; // set if counter $aifcounter = 0; foreach ($f_matchKeys as $af_matchKey) @@ -16759,14 +15705,14 @@ class Interpretation extends Fields } $aifcounter++; } - $func .= ")" . PHP_EOL . $this->_t(1) . "{"; + $func .= ")" . PHP_EOL . Indent::_(1) . "{"; } else { - $func .= PHP_EOL . $this->_t(1) . "//" . $this->setLine( - __LINE__ + $func .= PHP_EOL . Indent::_(1) . "//" . Line::_( + __LINE__,__CLASS__ ) . " set the function logic"; - $func .= PHP_EOL . $this->_t(1) . "if ("; + $func .= PHP_EOL . Indent::_(1) . "if ("; // set if counter $ifcounter = 0; foreach ($f_matchKeys as $f_matchKey) @@ -16785,7 +15731,7 @@ class Interpretation extends Fields $ifcounter++; } } - $func .= ")" . PHP_EOL . $this->_t(1) . "{"; + $func .= ")" . PHP_EOL . Indent::_(1) . "{"; } // get the controles $controls = $targetControls[$f_matchKeys[0]]; @@ -16807,8 +15753,8 @@ class Interpretation extends Fields // check if this is a toggle switch if ($toggleSwitch[$f_matchKeys[0]]) { - $func .= PHP_EOL . $this->_t(1) . "}" . PHP_EOL - . $this->_t(1) . "else" . PHP_EOL . $this->_t(1) + $func .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL + . Indent::_(1) . "else" . PHP_EOL . Indent::_(1) . "{"; // load the default behavior foreach ($controls as $target => $action) @@ -16822,7 +15768,7 @@ class Interpretation extends Fields } } } - $func .= PHP_EOL . $this->_t(1) . "}" . PHP_EOL . "}" + $func .= PHP_EOL . Indent::_(1) . "}" . PHP_EOL . "}" . PHP_EOL . $map; } // add the needed validation to file @@ -16834,69 +15780,69 @@ class Interpretation extends Fields $validation .= PHP_EOL . "// update fields required"; $validation .= PHP_EOL . "function updateFieldRequired(name, status) {"; - $validation .= PHP_EOL . $this->_t(1) + $validation .= PHP_EOL . Indent::_(1) . "// check if not_required exist"; - $validation .= PHP_EOL . $this->_t(1) + $validation .= PHP_EOL . Indent::_(1) . "if (jQuery('#jform_not_required').length > 0) {"; - $validation .= PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . Indent::_(2) . "var not_required = jQuery('#jform_not_required').val().split(\",\");"; - $validation .= PHP_EOL . PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . PHP_EOL . Indent::_(2) . "if(status == 1)"; - $validation .= PHP_EOL . $this->_t(2) . "{"; - $validation .= PHP_EOL . $this->_t(3) + $validation .= PHP_EOL . Indent::_(2) . "{"; + $validation .= PHP_EOL . Indent::_(3) . "not_required.push(name);"; - $validation .= PHP_EOL . $this->_t(2) . "}"; - $validation .= PHP_EOL . $this->_t(2) . "else"; - $validation .= PHP_EOL . $this->_t(2) . "{"; - $validation .= PHP_EOL . $this->_t(3) + $validation .= PHP_EOL . Indent::_(2) . "}"; + $validation .= PHP_EOL . Indent::_(2) . "else"; + $validation .= PHP_EOL . Indent::_(2) . "{"; + $validation .= PHP_EOL . Indent::_(3) . "not_required = removeFieldFromNotRequired(not_required, name);"; - $validation .= PHP_EOL . $this->_t(2) . "}"; - $validation .= PHP_EOL . PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . Indent::_(2) . "}"; + $validation .= PHP_EOL . PHP_EOL . Indent::_(2) . "jQuery('#jform_not_required').val(fixNotRequiredArray(not_required).toString());"; - $validation .= PHP_EOL . $this->_t(1) . "}"; + $validation .= PHP_EOL . Indent::_(1) . "}"; $validation .= PHP_EOL . "}" . PHP_EOL; $validation .= PHP_EOL . "// remove field from not_required"; $validation .= PHP_EOL . "function removeFieldFromNotRequired(array, what) {"; - $validation .= PHP_EOL . $this->_t(1) + $validation .= PHP_EOL . Indent::_(1) . "return array.filter(function(element){"; - $validation .= PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . Indent::_(2) . "return element !== what;"; - $validation .= PHP_EOL . $this->_t(1) . "});"; + $validation .= PHP_EOL . Indent::_(1) . "});"; $validation .= PHP_EOL . "}" . PHP_EOL; $validation .= PHP_EOL . "// fix not required array"; $validation .= PHP_EOL . "function fixNotRequiredArray(array) {"; - $validation .= PHP_EOL . $this->_t(1) . "var seen = {};"; - $validation .= PHP_EOL . $this->_t(1) + $validation .= PHP_EOL . Indent::_(1) . "var seen = {};"; + $validation .= PHP_EOL . Indent::_(1) . "return removeEmptyFromNotRequiredArray(array).filter(function(item) {"; - $validation .= PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . Indent::_(2) . "return seen.hasOwnProperty(item) ? false : (seen[item] = true);"; - $validation .= PHP_EOL . $this->_t(1) . "});"; + $validation .= PHP_EOL . Indent::_(1) . "});"; $validation .= PHP_EOL . "}" . PHP_EOL; $validation .= PHP_EOL . "// remove empty from not_required array"; $validation .= PHP_EOL . "function removeEmptyFromNotRequiredArray(array) {"; - $validation .= PHP_EOL . $this->_t(1) + $validation .= PHP_EOL . Indent::_(1) . "return array.filter(function (el) {"; - $validation .= PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . Indent::_(2) . "// remove ( 侀_侀) as well - lol"; - $validation .= PHP_EOL . $this->_t(2) + $validation .= PHP_EOL . Indent::_(2) . "return (el.length > 0 && '侀_侀' !== el);"; - $validation .= PHP_EOL . $this->_t(1) . "});"; + $validation .= PHP_EOL . Indent::_(1) . "});"; $validation .= PHP_EOL . "}" . PHP_EOL; } // set the isSet function $isSet = PHP_EOL . "// the isSet function"; $isSet .= PHP_EOL . "function isSet(val)"; $isSet .= PHP_EOL . "{"; - $isSet .= PHP_EOL . $this->_t(1) + $isSet .= PHP_EOL . Indent::_(1) . "if ((val != undefined) && (val != null) && 0 !== val.length){"; - $isSet .= PHP_EOL . $this->_t(2) . "return true;"; - $isSet .= PHP_EOL . $this->_t(1) . "}"; - $isSet .= PHP_EOL . $this->_t(1) . "return false;"; + $isSet .= PHP_EOL . Indent::_(2) . "return true;"; + $isSet .= PHP_EOL . Indent::_(1) . "}"; + $isSet .= PHP_EOL . Indent::_(1) . "return false;"; $isSet .= PHP_EOL . "}"; } // load to this buket @@ -16908,18 +15854,17 @@ class Interpretation extends Fields { $fileScript = ''; } - $fileScript .= $this->getCustomScriptBuilder( + $fileScript .= CFactory::_('Customcode.Dispenser')->get( 'view_file', $nameSingleCode, PHP_EOL . PHP_EOL, null, true, '' ); // add custom script to footer - if (isset($this->customScriptBuilder['view_footer'][$nameSingleCode]) + if (isset(CFactory::_('Customcode.Dispenser')->hub['view_footer'][$nameSingleCode]) && StringHelper::check( - $this->customScriptBuilder['view_footer'][$nameSingleCode] + CFactory::_('Customcode.Dispenser')->hub['view_footer'][$nameSingleCode] )) { - $customFooterScript = PHP_EOL . PHP_EOL . $this->setPlaceholders( - $this->customScriptBuilder['view_footer'][$nameSingleCode], - $this->placeholders + $customFooterScript = PHP_EOL . PHP_EOL . CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['view_footer'][$nameSingleCode] ); if (strpos($customFooterScript, 'name_list_code; // add custom script to list view JS file - if (($list_fileScript = $this->getCustomScriptBuilder( + if (($list_fileScript = CFactory::_('Customcode.Dispenser')->get( 'views_file', $nameSingleCode, PHP_EOL . PHP_EOL, null, true, false )) !== false && StringHelper::check($list_fileScript)) { // get dates - $_created = $this->getCreatedDate($viewArray); - $_modified = $this->getLastModifiedDate($viewArray); + $_created = CFactory::_('Model.Createdate')->get($viewArray); + $_modified = CFactory::_('Model.Modifieddate')->get($viewArray); // add file to view - $_target = array($this->target => $nameListCode); - $_config = array($this->hhh . 'CREATIONDATE' - . $this->hhh => $_created, - $this->hhh . 'BUILDDATE' - . $this->hhh => $_modified, - $this->hhh . 'VERSION' - . $this->hhh => $viewArray['settings']->version); - $this->buildDynamique($_target, 'javascript_file', false, $_config); + $_target = array(CFactory::_('Config')->build_target => $nameListCode); + $_config = array(Placefix::_h('CREATIONDATE') => $_created, + Placefix::_h('BUILDDATE') => $_modified, + Placefix::_h('VERSION') => $viewArray['settings']->version); + CFactory::_('Utilities.Structure')->build($_target, 'javascript_file', false, $_config); // set path - $_path = '/administrator/components/com_' . $this->componentCodeName + $_path = '/administrator/components/com_' . CFactory::_('Config')->component_code_name . '/assets/js/' . $nameListCode . '.js'; // load the file to the list view - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_ADD_JAVASCRIPT_FILE' . $this->hhh] - = PHP_EOL . PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ - ) . " Add List View JavaScript File" . PHP_EOL . $this->_t(2) - . $this->setIncludeLibScript($_path); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_ADD_JAVASCRIPT_FILE', PHP_EOL . PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " Add List View JavaScript File" . PHP_EOL . Indent::_(2) + . $this->setIncludeLibScript($_path) + ); } else { $list_fileScript = ''; - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_ADD_JAVASCRIPT_FILE' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_ADD_JAVASCRIPT_FILE', ''); } - // minfy the script - if ($this->minify && isset($list_fileScript) + // minify the script + if (CFactory::_('Config')->get('minify', 0) && isset($list_fileScript) && StringHelper::check($list_fileScript)) { - // minify the fielScript javscript - $minifier = new JS; - $minifier->add($list_fileScript); - $list_fileScript = $minifier->minify(); + // minify the fileScript javascript + $list_fileScript = Minify::js($list_fileScript); } - // minfy the script - if ($this->minify && isset($fileScript) + // minify the script + if (CFactory::_('Config')->get('minify', 0) && isset($fileScript) && StringHelper::check($fileScript)) { - // minify the fielScript javscript - $minifier = new JS; - $minifier->add($fileScript); - $fileScript = $minifier->minify(); + // minify the fileScript javascript + $fileScript = Minify::js($fileScript); } - // minfy the script - if ($this->minify && isset($footerScript) + // minify the script + if (CFactory::_('Config')->get('minify', 0) && isset($footerScript) && StringHelper::check($footerScript)) { - // minify the footerScript javscript - $minifier = new JS; - $minifier->add($footerScript); - $footerScript = $minifier->minify(); + // minify the footerScript javascript + $footerScript = Minify::js($footerScript); } // make sure there is script to add if (isset($list_fileScript) @@ -17047,7 +15980,7 @@ class Interpretation extends Fields . PHP_EOL . '"; $this->viewScriptBuilder[$nameSingleCode]['footerScript'] - = $footerScript; + = $footerScript; } } @@ -17061,13 +15994,13 @@ class Interpretation extends Fields $value = $getValue[$matchKey]; if ($value['isArray']) { - $initial .= PHP_EOL . $this->_t(1) . $value['get']; + $initial .= PHP_EOL . Indent::_(1) . $value['get']; $funcsets[] = $matchKey; $array = true; } else { - $initial .= PHP_EOL . $this->_t(1) . $value['get']; + $initial .= PHP_EOL . Indent::_(1) . $value['get']; $funcsets[] = $matchKey; } } @@ -17075,7 +16008,7 @@ class Interpretation extends Fields // make sure that the function is loaded only once if (ArrayHelper::check($funcsets)) { - $initial .= PHP_EOL . $this->_t(1) . $function . "("; + $initial .= PHP_EOL . Indent::_(1) . $function . "("; $initial .= implode(',', $funcsets); $initial .= ");" . PHP_EOL; } @@ -17120,7 +16053,7 @@ class Interpretation extends Fields if (in_array($target['name'], $currentTargets)) { $this->targetRelationControl[$view][$target['name']] - = array($relation['match_name'], + = array($relation['match_name'], $condition['match_name']); $found = true; break; @@ -17208,7 +16141,7 @@ class Interpretation extends Fields } // set target type $targetTypeSufix = ""; - if (ComponentbuilderHelper::fieldCheck( + if (CFactory::_('Field.Groups')->check( $target['type'], 'spacer' )) { @@ -17229,13 +16162,13 @@ class Interpretation extends Fields $targetType = "#jform_"; } // set the target behavior - $bucket[$target['name']]['behavior'] = PHP_EOL . $this->_t( + $bucket[$target['name']]['behavior'] = PHP_EOL . Indent::_( 2 ) . "jQuery('" . $targetType . $target['name'] . $targetTypeSufix . "').closest('.control-group')." . $targetBehavior . "();"; // set the target default - $bucket[$target['name']]['default'] = PHP_EOL . $this->_t(2) + $bucket[$target['name']]['default'] = PHP_EOL . Indent::_(2) . "jQuery('" . $targetType . $target['name'] . $targetTypeSufix . "').closest('.control-group')." . $targetDefault . "();"; @@ -17245,112 +16178,112 @@ class Interpretation extends Fields if ($toggleSwitch) { $hide = PHP_EOL - . $this->_t(2) . "//" . $this->setLine(__LINE__) + . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " remove required attribute from " . $target['name'] . " field"; $hide .= PHP_EOL - . $this->_t(2) . "if (!jform_" . $unique + . Indent::_(2) . "if (!jform_" . $unique . "_required)"; $hide .= PHP_EOL - . $this->_t(2) . "{"; + . Indent::_(2) . "{"; $hide .= PHP_EOL - . $this->_t(3) . "updateFieldRequired('" + . Indent::_(3) . "updateFieldRequired('" . $target['name'] . "',1);"; $hide .= PHP_EOL - . $this->_t(3) . "jQuery('#jform_" + . Indent::_(3) . "jQuery('#jform_" . $target['name'] . "').removeAttr('required');"; $hide .= PHP_EOL - . $this->_t(3) . "jQuery('#jform_" + . Indent::_(3) . "jQuery('#jform_" . $target['name'] . "').removeAttr('aria-required');"; $hide .= PHP_EOL - . $this->_t(3) . "jQuery('#jform_" + . Indent::_(3) . "jQuery('#jform_" . $target['name'] . "').removeClass('required');"; $hide .= PHP_EOL - . $this->_t(3) . "jform_" . $unique + . Indent::_(3) . "jform_" . $unique . "_required = true;"; $hide .= PHP_EOL - . $this->_t(2) . "}"; + . Indent::_(2) . "}"; $bucket[$target['name']]['hide'] = $hide; // the show required function $show = PHP_EOL - . $this->_t(2) . "//" . $this->setLine(__LINE__) + . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " add required attribute to " . $target['name'] . " field"; $show .= PHP_EOL - . $this->_t(2) . "if (jform_" . $unique + . Indent::_(2) . "if (jform_" . $unique . "_required)"; $show .= PHP_EOL - . $this->_t(2) . "{"; + . Indent::_(2) . "{"; $show .= PHP_EOL - . $this->_t(3) . "updateFieldRequired('" + . Indent::_(3) . "updateFieldRequired('" . $target['name'] . "',0);"; $show .= PHP_EOL - . $this->_t(3) . "jQuery('#jform_" + . Indent::_(3) . "jQuery('#jform_" . $target['name'] . "').prop('required','required');"; $show .= PHP_EOL - . $this->_t(3) . "jQuery('#jform_" + . Indent::_(3) . "jQuery('#jform_" . $target['name'] . "').attr('aria-required',true);"; $show .= PHP_EOL - . $this->_t(3) . "jQuery('#jform_" + . Indent::_(3) . "jQuery('#jform_" . $target['name'] . "').addClass('required');"; $show .= PHP_EOL - . $this->_t(3) . "jform_" . $unique + . Indent::_(3) . "jform_" . $unique . "_required = false;"; $show .= PHP_EOL - . $this->_t(2) . "}"; + . Indent::_(2) . "}"; $bucket[$target['name']]['show'] = $show; } else { $hide = PHP_EOL - . $this->_t(2) . "//" . $this->setLine(__LINE__) + . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " remove required attribute from " . $target['name'] . " field"; $hide .= PHP_EOL - . $this->_t(2) . "updateFieldRequired('" + . Indent::_(2) . "updateFieldRequired('" . $target['name'] . "',1);"; $hide .= PHP_EOL - . $this->_t(2) . "jQuery('#jform_" + . Indent::_(2) . "jQuery('#jform_" . $target['name'] . "').removeAttr('required');"; $hide .= PHP_EOL - . $this->_t(2) . "jQuery('#jform_" + . Indent::_(2) . "jQuery('#jform_" . $target['name'] . "').removeAttr('aria-required');"; $hide .= PHP_EOL - . $this->_t(2) . "jQuery('#jform_" + . Indent::_(2) . "jQuery('#jform_" . $target['name'] . "').removeClass('required');"; $hide .= PHP_EOL - . $this->_t(2) . "jform_" . $unique + . Indent::_(2) . "jform_" . $unique . "_required = true;" . PHP_EOL; $bucket[$target['name']]['hide'] = $hide; // the show required function $show = PHP_EOL - . $this->_t(2) . "//" . $this->setLine(__LINE__) + . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " add required attribute to " . $target['name'] . " field"; $show .= PHP_EOL - . $this->_t(2) . "updateFieldRequired('" + . Indent::_(2) . "updateFieldRequired('" . $target['name'] . "',0);"; $show .= PHP_EOL - . $this->_t(2) . "jQuery('#jform_" + . Indent::_(2) . "jQuery('#jform_" . $target['name'] . "').prop('required','required');"; $show .= PHP_EOL - . $this->_t(2) . "jQuery('#jform_" + . Indent::_(2) . "jQuery('#jform_" . $target['name'] . "').attr('aria-required',true);"; $show .= PHP_EOL - . $this->_t(2) . "jQuery('#jform_" + . Indent::_(2) . "jQuery('#jform_" . $target['name'] . "').addClass('required');"; $show .= PHP_EOL - . $this->_t(2) . "jform_" . $unique + . Indent::_(2) . "jform_" . $unique . "_required = false;" . PHP_EOL; $bucket[$target['name']]['show'] = $show; } @@ -17379,9 +16312,9 @@ class Interpretation extends Fields { case 1: // Is // only 4 list/radio/checkboxes - if (ComponentbuilderHelper::fieldCheck($type, 'list') - || ComponentbuilderHelper::fieldCheck($type, 'dynamic') - || !ComponentbuilderHelper::fieldCheck($type)) + if (CFactory::_('Field.Groups')->check($type, 'list') + || CFactory::_('Field.Groups')->check($type, 'dynamic') + || !CFactory::_('Field.Groups')->check($type)) { if (ArrayHelper::check($options)) { @@ -17412,9 +16345,9 @@ class Interpretation extends Fields break; case 2: // Is Not // only 4 list/radio/checkboxes - if (ComponentbuilderHelper::fieldCheck($type, 'list') - || ComponentbuilderHelper::fieldCheck($type, 'dynamic') - || !ComponentbuilderHelper::fieldCheck($type)) + if (CFactory::_('Field.Groups')->check($type, 'list') + || CFactory::_('Field.Groups')->check($type, 'dynamic') + || !CFactory::_('Field.Groups')->check($type)) { if (ArrayHelper::check($options)) { @@ -17445,9 +16378,9 @@ class Interpretation extends Fields break; case 3: // Any Selection // only 4 list/radio/checkboxes/dynamic_list - if (ComponentbuilderHelper::fieldCheck($type, 'list') - || ComponentbuilderHelper::fieldCheck($type, 'dynamic') - || !ComponentbuilderHelper::fieldCheck($type)) + if (CFactory::_('Field.Groups')->check($type, 'list') + || CFactory::_('Field.Groups')->check($type, 'dynamic') + || !CFactory::_('Field.Groups')->check($type)) { if (ArrayHelper::check($options)) { @@ -17473,11 +16406,7 @@ class Interpretation extends Fields else { $userFix = ''; - if (isset($this->setScriptUserSwitch) - && ArrayHelper::check( - $this->setScriptUserSwitch - ) - && in_array($type, $this->setScriptUserSwitch)) + if (CFactory::_('Compiler.Builder.Script.User.Switch')->inArray($type)) { // TODO this needs a closer look, a bit buggy $userFix = " && " . $value . " != 0"; @@ -17488,21 +16417,21 @@ class Interpretation extends Fields break; case 4: // Active (not empty) // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { $string .= 'isSet(' . $value . ')'; } break; case 5: // Unactive (empty) // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { $string .= '!isSet(' . $value . ')'; } break; case 6: // Key Word All (case-sensitive) // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check( $options['keywords'] @@ -17530,7 +16459,7 @@ class Interpretation extends Fields break; case 7: // Key Word Any (case-sensitive) // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check( $options['keywords'] @@ -17558,7 +16487,7 @@ class Interpretation extends Fields break; case 8: // Key Word All (case-insensitive) // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check( $options['keywords'] @@ -17590,7 +16519,7 @@ class Interpretation extends Fields break; case 9: // Key Word Any (case-insensitive) // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check( $options['keywords'] @@ -17622,7 +16551,7 @@ class Interpretation extends Fields break; case 10: // Min Length // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check($options)) { @@ -17640,7 +16569,7 @@ class Interpretation extends Fields break; case 11: // Max Length // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check($options)) { @@ -17658,7 +16587,7 @@ class Interpretation extends Fields break; case 12: // Exact Length // only 4 text_field - if (ComponentbuilderHelper::fieldCheck($type, 'text')) + if (CFactory::_('Field.Groups')->check($type, 'text')) { if (ArrayHelper::check($options)) { @@ -17688,12 +16617,12 @@ class Interpretation extends Fields $buket = array(); if (StringHelper::check($options)) { - if (ComponentbuilderHelper::fieldCheck($type, 'list') - || ComponentbuilderHelper::fieldCheck($type, 'dynamic') - || !ComponentbuilderHelper::fieldCheck($type)) + if (CFactory::_('Field.Groups')->check($type, 'list') + || CFactory::_('Field.Groups')->check($type, 'dynamic') + || !CFactory::_('Field.Groups')->check($type)) { $optionsArray = array_map( - 'trim', (array) explode(PHP_EOL, $options) + 'trim', (array) explode(PHP_EOL, (string) $options) ); if (!ArrayHelper::check($optionsArray)) { @@ -17714,7 +16643,7 @@ class Interpretation extends Fields } } } - elseif (ComponentbuilderHelper::fieldCheck($type, 'text')) + elseif (CFactory::_('Field.Groups')->check($type, 'text')) { // check to get the key words if set $keywords = GetHelper::between( @@ -17722,10 +16651,10 @@ class Interpretation extends Fields ); if (StringHelper::check($keywords)) { - if (strpos($keywords, ',') !== false) + if (strpos((string) $keywords, ',') !== false) { $keywords = array_map( - 'trim', (array) explode(',', $keywords) + 'trim', (array) explode(',', (string) $keywords) ); foreach ($keywords as $keyword) { @@ -17734,7 +16663,7 @@ class Interpretation extends Fields } else { - $buket['keywords'][] = trim($keywords); + $buket['keywords'][] = trim((string) $keywords); } } // check to ket string length if set @@ -17762,14 +16691,14 @@ class Interpretation extends Fields $keyName = $name . '_' . $unique; if ($type === 'checkboxes' || $extends === 'checkboxes') { - $select = "var " . $keyName . " = [];" . PHP_EOL . $this->_t(1) + $select = "var " . $keyName . " = [];" . PHP_EOL . Indent::_(1) . "jQuery('#jform_" . $name . " input[type=checkbox]').each(function()" . PHP_EOL - . $this->_t(1) . "{" . PHP_EOL . $this->_t(2) - . "if (jQuery(this).is(':checked'))" . PHP_EOL . $this->_t(2) - . "{" . PHP_EOL . $this->_t(3) . $keyName - . ".push(jQuery(this).prop('value'));" . PHP_EOL . $this->_t(2) - . "}" . PHP_EOL . $this->_t(1) . "});"; + . Indent::_(1) . "{" . PHP_EOL . Indent::_(2) + . "if (jQuery(this).is(':checked'))" . PHP_EOL . Indent::_(2) + . "{" . PHP_EOL . Indent::_(3) . $keyName + . ".push(jQuery(this).prop('value'));" . PHP_EOL . Indent::_(2) + . "}" . PHP_EOL . Indent::_(1) . "});"; $isArray = true; } elseif ($type === 'checkbox') @@ -17782,25 +16711,23 @@ class Interpretation extends Fields $select = 'var ' . $keyName . ' = jQuery("#jform_' . $name . ' input[type=\'radio\']:checked").val();'; } - elseif (isset($this->setScriptUserSwitch) - && ArrayHelper::check($this->setScriptUserSwitch) - && in_array($type, $this->setScriptUserSwitch)) + elseif (CFactory::_('Compiler.Builder.Script.User.Switch')->inArray($type)) { // this is only since 3.3.4 $select = 'var ' . $keyName . ' = jQuery("#jform_' . $name . '_id").val();'; } elseif ($type === 'list' - || ComponentbuilderHelper::fieldCheck( + || CFactory::_('Field.Groups')->check( $type, 'dynamic' ) - || !ComponentbuilderHelper::fieldCheck($type)) + || !CFactory::_('Field.Groups')->check($type)) { $select = 'var ' . $keyName . ' = jQuery("#jform_' . $name . '").val();'; $isArray = true; } - elseif (ComponentbuilderHelper::fieldCheck($type, 'text')) + elseif (CFactory::_('Field.Groups')->check($type, 'text')) { $select = 'var ' . $keyName . ' = jQuery("#jform_' . $name . '").val();'; @@ -17850,60 +16777,60 @@ class Interpretation extends Fields $this->validationFixBuilder[$view] )) { - $fix .= PHP_EOL . PHP_EOL . $this->_t(1) . "/**"; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $fix .= PHP_EOL . Indent::_(1) . " * Method to validate the form data."; - $fix .= PHP_EOL . $this->_t(1) . " *"; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . " *"; + $fix .= PHP_EOL . Indent::_(1) . " * @param JForm \$form The form to validate against."; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . " * @param array \$data The data to validate."; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . " * @param string \$group The name of the field group to validate."; - $fix .= PHP_EOL . $this->_t(1) . " *"; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . " *"; + $fix .= PHP_EOL . Indent::_(1) . " * @return mixed Array of filtered data if valid, false otherwise."; - $fix .= PHP_EOL . $this->_t(1) . " *"; - $fix .= PHP_EOL . $this->_t(1) . " * @see JFormRule"; - $fix .= PHP_EOL . $this->_t(1) . " * @see JFilterInput"; - $fix .= PHP_EOL . $this->_t(1) . " * @since 12.2"; - $fix .= PHP_EOL . $this->_t(1) . " */"; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . " *"; + $fix .= PHP_EOL . Indent::_(1) . " * @see JFormRule"; + $fix .= PHP_EOL . Indent::_(1) . " * @see JFilterInput"; + $fix .= PHP_EOL . Indent::_(1) . " * @since 12.2"; + $fix .= PHP_EOL . Indent::_(1) . " */"; + $fix .= PHP_EOL . Indent::_(1) . "public function validate(\$form, \$data, \$group = null)"; - $fix .= PHP_EOL . $this->_t(1) . "{"; - $fix .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . "{"; + $fix .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if the not_required field is set"; - $fix .= PHP_EOL . $this->_t(2) + $fix .= PHP_EOL . Indent::_(2) . "if (isset(\$data['not_required']) && " . $Component . "Helper::checkString(\$data['not_required']))"; - $fix .= PHP_EOL . $this->_t(2) . "{"; - $fix .= PHP_EOL . $this->_t(3) + $fix .= PHP_EOL . Indent::_(2) . "{"; + $fix .= PHP_EOL . Indent::_(3) . "\$requiredFields = (array) explode(',',(string) \$data['not_required']);"; - $fix .= PHP_EOL . $this->_t(3) + $fix .= PHP_EOL . Indent::_(3) . "\$requiredFields = array_unique(\$requiredFields);"; - $fix .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " now change the required field attributes value"; - $fix .= PHP_EOL . $this->_t(3) + $fix .= PHP_EOL . Indent::_(3) . "foreach (\$requiredFields as \$requiredField)"; - $fix .= PHP_EOL . $this->_t(3) . "{"; - $fix .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(3) . "{"; + $fix .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " make sure there is a string value"; - $fix .= PHP_EOL . $this->_t(4) . "if (" . $Component + $fix .= PHP_EOL . Indent::_(4) . "if (" . $Component . "Helper::checkString(\$requiredField))"; - $fix .= PHP_EOL . $this->_t(4) . "{"; - $fix .= PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(4) . "{"; + $fix .= PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " change to false"; - $fix .= PHP_EOL . $this->_t(5) + $fix .= PHP_EOL . Indent::_(5) . "\$form->setFieldAttribute(\$requiredField, 'required', 'false');"; - $fix .= PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " also clear the data set"; - $fix .= PHP_EOL . $this->_t(5) . "\$data[\$requiredField] = '';"; - $fix .= PHP_EOL . $this->_t(4) . "}"; - $fix .= PHP_EOL . $this->_t(3) . "}"; - $fix .= PHP_EOL . $this->_t(2) . "}"; - $fix .= PHP_EOL . $this->_t(2) + $fix .= PHP_EOL . Indent::_(5) . "\$data[\$requiredField] = '';"; + $fix .= PHP_EOL . Indent::_(4) . "}"; + $fix .= PHP_EOL . Indent::_(3) . "}"; + $fix .= PHP_EOL . Indent::_(2) . "}"; + $fix .= PHP_EOL . Indent::_(2) . "return parent::validate(\$form, \$data, \$group);"; - $fix .= PHP_EOL . $this->_t(1) . "}"; + $fix .= PHP_EOL . Indent::_(1) . "}"; } return $fix; @@ -17912,12 +16839,12 @@ class Interpretation extends Fields public function setAjaxToke(&$view) { $fix = ''; - if (isset($this->customScriptBuilder['token'][$view]) - && $this->customScriptBuilder['token'][$view]) + if (isset(CFactory::_('Customcode.Dispenser')->hub['token'][$view]) + && CFactory::_('Customcode.Dispenser')->hub['token'][$view]) { - $fix .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Add Ajax Token"; - $fix .= PHP_EOL . $this->_t(2) + $fix .= PHP_EOL . Indent::_(2) . "\$this->document->addScriptDeclaration(\"var token = '\".JSession::getFormToken().\"';\");"; } @@ -17927,14 +16854,14 @@ class Interpretation extends Fields public function setRegisterAjaxTask($target) { $tasks = ''; - if (isset($this->customScriptBuilder[$target]['ajax_controller']) + if (isset(CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_controller']) && ArrayHelper::check( - $this->customScriptBuilder[$target]['ajax_controller'] + CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_controller'] )) { $taskArray = array(); foreach ( - $this->customScriptBuilder[$target]['ajax_controller'] as $view + CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_controller'] as $view ) { foreach ($view as $task) @@ -17946,7 +16873,7 @@ class Interpretation extends Fields { foreach ($taskArray as $name) { - $tasks .= PHP_EOL . $this->_t(2) . "\$this->registerTask('" + $tasks .= PHP_EOL . Indent::_(2) . "\$this->registerTask('" . $name . "', 'ajax');"; } } @@ -17958,9 +16885,9 @@ class Interpretation extends Fields public function setAjaxInputReturn($target) { $cases = ''; - if (isset($this->customScriptBuilder[$target]['ajax_controller']) + if (isset(CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_controller']) && ArrayHelper::check( - $this->customScriptBuilder[$target]['ajax_controller'] + CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_controller'] )) { $input = array(); @@ -17969,7 +16896,7 @@ class Interpretation extends Fields $getModel = array(); $userCheck = array(); foreach ( - $this->customScriptBuilder[$target]['ajax_controller'] as $view + CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_controller'] as $view ) { foreach ($view as $task) @@ -17981,9 +16908,8 @@ class Interpretation extends Fields $valueArray[$task['task_name']][] = "\$" . $task['value_name'] . "Value"; $getModel[$task['task_name']] - = "\$result = \$this->getModel('ajax')->" - . $task['method_name'] . "(" . $this->bbb . "valueArray" - . $this->ddd . ");"; + = "\$result = \$this->getModel('ajax')->" + . $task['method_name'] . "(" . Placefix::_("valueArray") . ");"; // check if null or zero is allowed if (!isset($task['allow_zero']) || 1 != $task['allow_zero']) { @@ -18007,18 +16933,18 @@ class Interpretation extends Fields { foreach ($getModel as $task => $getMethod) { - $cases .= PHP_EOL . $this->_t(4) . "case '" . $task . "':"; - $cases .= PHP_EOL . $this->_t(5) . "try"; - $cases .= PHP_EOL . $this->_t(5) . "{"; + $cases .= PHP_EOL . Indent::_(4) . "case '" . $task . "':"; + $cases .= PHP_EOL . Indent::_(5) . "try"; + $cases .= PHP_EOL . Indent::_(5) . "{"; foreach ($input[$task] as $string) { - $cases .= PHP_EOL . $this->_t(6) . $string; + $cases .= PHP_EOL . Indent::_(6) . $string; } // set the values $values = implode(', ', $valueArray[$task]); // set the values to method $getMethod = str_replace( - $this->bbb . 'valueArray' . $this->ddd, $values, + Placefix::_('valueArray'), $values, $getMethod ); // check if we have some values to check @@ -18028,59 +16954,59 @@ class Interpretation extends Fields // set if string $ifvalues = implode(' && ', $ifArray[$task]); // add to case - $cases .= PHP_EOL . $this->_t(6) . "if(" . $ifvalues + $cases .= PHP_EOL . Indent::_(6) . "if(" . $ifvalues . ")"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) . $getMethod; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(6) . "else"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) . "\$result = false;"; - $cases .= PHP_EOL . $this->_t(6) . "}"; + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . $getMethod; + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(6) . "else"; + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "\$result = false;"; + $cases .= PHP_EOL . Indent::_(6) . "}"; } else { - $cases .= PHP_EOL . $this->_t(6) . $getMethod; + $cases .= PHP_EOL . Indent::_(6) . $getMethod; } // continue the build - $cases .= PHP_EOL . $this->_t(6) + $cases .= PHP_EOL . Indent::_(6) . "if(\$callback)"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "echo \$callback . \"(\".json_encode(\$result).\");\";"; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(6) . "elseif(\$returnRaw)"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(6) . "elseif(\$returnRaw)"; + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "echo json_encode(\$result);"; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(6) . "else"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(6) . "else"; + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "echo \"(\".json_encode(\$result).\");\";"; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(5) . "}"; - $cases .= PHP_EOL . $this->_t(5) . "catch(Exception \$e)"; - $cases .= PHP_EOL . $this->_t(5) . "{"; - $cases .= PHP_EOL . $this->_t(6) + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(5) . "}"; + $cases .= PHP_EOL . Indent::_(5) . "catch(Exception \$e)"; + $cases .= PHP_EOL . Indent::_(5) . "{"; + $cases .= PHP_EOL . Indent::_(6) . "if(\$callback)"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "echo \$callback.\"(\".json_encode(\$e).\");\";"; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(6) + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(6) . "elseif(\$returnRaw)"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "echo json_encode(\$e);"; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(6) . "else"; - $cases .= PHP_EOL . $this->_t(6) . "{"; - $cases .= PHP_EOL . $this->_t(7) + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(6) . "else"; + $cases .= PHP_EOL . Indent::_(6) . "{"; + $cases .= PHP_EOL . Indent::_(7) . "echo \"(\".json_encode(\$e).\");\";"; - $cases .= PHP_EOL . $this->_t(6) . "}"; - $cases .= PHP_EOL . $this->_t(5) . "}"; - $cases .= PHP_EOL . $this->_t(4) . "break;"; + $cases .= PHP_EOL . Indent::_(6) . "}"; + $cases .= PHP_EOL . Indent::_(5) . "}"; + $cases .= PHP_EOL . Indent::_(4) . "break;"; } } } @@ -18091,20 +17017,20 @@ class Interpretation extends Fields public function setAjaxModelMethods($target) { $methods = ''; - if (isset($this->customScriptBuilder[$target]['ajax_model']) + if (isset(CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_model']) && ArrayHelper::check( - $this->customScriptBuilder[$target]['ajax_model'] + CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_model'] )) { foreach ( - $this->customScriptBuilder[$target]['ajax_model'] as $view => + CFactory::_('Customcode.Dispenser')->hub[$target]['ajax_model'] as $view => $method ) { - $methods .= PHP_EOL . PHP_EOL . $this->_t(1) . "//" - . $this->setLine(__LINE__) . " Used in " . $view . PHP_EOL; - $methods .= $this->setPlaceholders( - $method, $this->placeholders + $methods .= PHP_EOL . PHP_EOL . Indent::_(1) . "//" + . Line::_(__Line__, __Class__) . " Used in " . $view . PHP_EOL; + $methods .= CFactory::_('Placeholder')->update_( + $method ); } } @@ -18124,23 +17050,19 @@ class Interpretation extends Fields public function setFilterFieldHelper(&$nameSingleCode, &$nameListCode) { // the old filter type uses these functions - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { // set the function or file path (2 = topbar) $funtion_path = true; - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 2) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 2) { $funtion_path = false; } $function = array(); // set component name - $component = $this->componentCodeName; - $Component = ucfirst($component); - foreach ($this->filterBuilder[$nameListCode] as $filter) + $component = CFactory::_('Config')->component_code_name; + $Component = ucfirst((string) $component); + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { if ($filter['type'] != 'category' && ArrayHelper::check($filter['custom']) @@ -18149,267 +17071,261 @@ class Interpretation extends Fields // add if this is a function path if ($funtion_path) { - $function[] = PHP_EOL . $this->_t(1) + $function[] = PHP_EOL . Indent::_(1) . "protected function getThe" . $filter['function'] . StringHelper::safe( $filter['custom']['text'], 'F' ) . "Selections()"; - $function[] = $this->_t(1) . "{"; + $function[] = Indent::_(1) . "{"; } - $function[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $function[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Get a db connection."; - $function[] = $this->_t(2) . "\$db = JFactory::getDbo();"; - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) + $function[] = Indent::_(2) . "\$db = JFactory::getDbo();"; + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Create a new query object."; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query = \$db->getQuery(true);"; - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Select the text."; - $function[] = $this->_t(2) + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Select the text."; + $function[] = Indent::_(2) . "\$query->select(\$db->quoteName(array('a." . $filter['custom']['id'] . "','a." . $filter['custom']['text'] . "')));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->from(\$db->quoteName('" . $filter['custom']['table'] . "', 'a'));"; - $function[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $function[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get the targeted groups"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$groups= JComponentHelper::getParams('com_" . $component . "')->get('" . $filter['type'] . "');"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "if (!empty(\$groups) && count((array) \$groups) > 0)"; - $function[] = $this->_t(2) . "{"; - $function[] = $this->_t(3) + $function[] = Indent::_(2) . "{"; + $function[] = Indent::_(3) . "\$query->join('LEFT', \$db->quoteName('#__user_usergroup_map', 'group') . ' ON (' . \$db->quoteName('group.user_id') . ' = ' . \$db->quoteName('a.id') . ')');"; - $function[] = $this->_t(3) + $function[] = Indent::_(3) . "\$query->where('group.group_id IN (' . implode(',', \$groups) . ')');"; - $function[] = $this->_t(2) . "}"; - $function[] = $this->_t(2) . "\$query->order('a." + $function[] = Indent::_(2) . "}"; + $function[] = Indent::_(2) . "\$query->order('a." . $filter['custom']['text'] . " ASC');"; - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Reset the query using our newly populated query object."; - $function[] = $this->_t(2) . "\$db->setQuery(\$query);"; - $function[] = PHP_EOL . $this->_t(2) + $function[] = Indent::_(2) . "\$db->setQuery(\$query);"; + $function[] = PHP_EOL . Indent::_(2) . "\$results = \$db->loadObjectList();"; - $function[] = $this->_t(2) . "\$_filter = array();"; + $function[] = Indent::_(2) . "\$_filter = array();"; // if this is not a multi field if (!$funtion_path && $filter['multi'] == 1) { - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$_filter[] = JHtml::_('select.option', '', '- Select ' . JText:" . ":_('" . $filter['lang'] . "') . ' -');"; } - $function[] = $this->_t(2) . "if (\$results)"; - $function[] = $this->_t(2) . "{"; - $function[] = $this->_t(3) + $function[] = Indent::_(2) . "if (\$results)"; + $function[] = Indent::_(2) . "{"; + $function[] = Indent::_(3) . "foreach (\$results as \$result)"; - $function[] = $this->_t(3) . "{"; - $function[] = $this->_t(4) + $function[] = Indent::_(3) . "{"; + $function[] = Indent::_(4) . "\$_filter[] = JHtml::_('select.option', \$result->" . $filter['custom']['id'] . ", \$result->" . $filter['custom']['text'] . ");"; - $function[] = $this->_t(3) . "}"; - $function[] = $this->_t(2) . "}"; - $function[] = $this->_t(2) . "return \$_filter;"; + $function[] = Indent::_(3) . "}"; + $function[] = Indent::_(2) . "}"; + $function[] = Indent::_(2) . "return \$_filter;"; // add if this is a function path if ($funtion_path) { - $function[] = $this->_t(1) . "}"; + $function[] = Indent::_(1) . "}"; } /* else { - $function[] = PHP_EOL.$this->_t(1) . "protected function getThe".$filter['function'].StringHelper::safe($filter['custom']['text'],'F')."Selections()"; - $function[] = $this->_t(1) . "{"; - $function[] = $this->_t(2) . "//".$this->setLine(__LINE__)." Get a db connection."; - $function[] = $this->_t(2) . "\$db = JFactory::getDbo();"; - $function[] = PHP_EOL.$this->_t(2) . "//".$this->setLine(__LINE__)." Select the text."; - $function[] = $this->_t(2) . "\$query = \$db->getQuery(true);"; - $function[] = PHP_EOL.$this->_t(2) . "//".$this->setLine(__LINE__)." Select the text."; - $function[] = $this->_t(2) . "\$query->select(\$db->quoteName(array('".$filter['custom']['id']."','".$filter['custom']['text']."')));"; - $function[] = $this->_t(2) . "\$query->from(\$db->quoteName('".$filter['custom']['table']."'));"; - $function[] = $this->_t(2) . "\$query->where(\$db->quoteName('published') . ' = 1');"; - $function[] = $this->_t(2) . "\$query->order(\$db->quoteName('".$filter['custom']['text']."') . ' ASC');"; - $function[] = PHP_EOL.$this->_t(2) . "//".$this->setLine(__LINE__)." Reset the query using our newly populated query object."; - $function[] = $this->_t(2) . "\$db->setQuery(\$query);"; - $function[] = PHP_EOL.$this->_t(2) . "\$results = \$db->loadObjectList();"; - $function[] = PHP_EOL.$this->_t(2) . "if (\$results)"; - $function[] = $this->_t(2) . "{"; - $function[] = $this->_t(3) . "\$filter = array();"; - $function[] = $this->_t(3) . "\$batch = array();"; - $function[] = $this->_t(3) . "foreach (\$results as \$result)"; - $function[] = $this->_t(3) . "{"; + $function[] = PHP_EOL.Indent::_(1) . "protected function getThe".$filter['function'].StringHelper::safe($filter['custom']['text'],'F')."Selections()"; + $function[] = Indent::_(1) . "{"; + $function[] = Indent::_(2) . "//".Line::_(__Line__, __Class__)." Get a db connection."; + $function[] = Indent::_(2) . "\$db = JFactory::getDbo();"; + $function[] = PHP_EOL.Indent::_(2) . "//".Line::_(__Line__, __Class__)." Select the text."; + $function[] = Indent::_(2) . "\$query = \$db->getQuery(true);"; + $function[] = PHP_EOL.Indent::_(2) . "//".Line::_(__Line__, __Class__)." Select the text."; + $function[] = Indent::_(2) . "\$query->select(\$db->quoteName(array('".$filter['custom']['id']."','".$filter['custom']['text']."')));"; + $function[] = Indent::_(2) . "\$query->from(\$db->quoteName('".$filter['custom']['table']."'));"; + $function[] = Indent::_(2) . "\$query->where(\$db->quoteName('published') . ' = 1');"; + $function[] = Indent::_(2) . "\$query->order(\$db->quoteName('".$filter['custom']['text']."') . ' ASC');"; + $function[] = PHP_EOL.Indent::_(2) . "//".Line::_(__Line__, __Class__)." Reset the query using our newly populated query object."; + $function[] = Indent::_(2) . "\$db->setQuery(\$query);"; + $function[] = PHP_EOL.Indent::_(2) . "\$results = \$db->loadObjectList();"; + $function[] = PHP_EOL.Indent::_(2) . "if (\$results)"; + $function[] = Indent::_(2) . "{"; + $function[] = Indent::_(3) . "\$filter = array();"; + $function[] = Indent::_(3) . "\$batch = array();"; + $function[] = Indent::_(3) . "foreach (\$results as \$result)"; + $function[] = Indent::_(3) . "{"; if ($filter['custom']['text'] === 'user') { - $function[] = $this->_t(4) . "\$filter[] = JHtml::_('select.option', \$result->".$filter['custom']['text'].", JFactory::getUser(\$result->".$filter['custom']['text'].")->name);"; - $function[] = $this->_t(4) . "\$batch[] = JHtml::_('select.option', \$result->".$filter['custom']['id'].", JFactory::getUser(\$result->".$filter['custom']['text'].")->name);"; + $function[] = Indent::_(4) . "\$filter[] = JHtml::_('select.option', \$result->".$filter['custom']['text'].", JFactory::getUser(\$result->".$filter['custom']['text'].")->name);"; + $function[] = Indent::_(4) . "\$batch[] = JHtml::_('select.option', \$result->".$filter['custom']['id'].", JFactory::getUser(\$result->".$filter['custom']['text'].")->name);"; } else { - $function[] = $this->_t(4) . "\$filter[] = JHtml::_('select.option', \$result->".$filter['custom']['text'].", \$result->".$filter['custom']['text'].");"; - $function[] = $this->_t(4) . "\$batch[] = JHtml::_('select.option', \$result->".$filter['custom']['id'].", \$result->".$filter['custom']['text'].");"; + $function[] = Indent::_(4) . "\$filter[] = JHtml::_('select.option', \$result->".$filter['custom']['text'].", \$result->".$filter['custom']['text'].");"; + $function[] = Indent::_(4) . "\$batch[] = JHtml::_('select.option', \$result->".$filter['custom']['id'].", \$result->".$filter['custom']['text'].");"; } - $function[] = $this->_t(3) . "}"; - $function[] = $this->_t(3) . "return array('filter' => \$filter, 'batch' => \$batch);"; - $function[] = $this->_t(2) . "}"; - $function[] = $this->_t(2) . "return false;"; - $function[] = $this->_t(1) . "}"; + $function[] = Indent::_(3) . "}"; + $function[] = Indent::_(3) . "return array('filter' => \$filter, 'batch' => \$batch);"; + $function[] = Indent::_(2) . "}"; + $function[] = Indent::_(2) . "return false;"; + $function[] = Indent::_(1) . "}"; } */ } elseif ($filter['type'] != 'category' && !ArrayHelper::check($filter['custom'])) { $translation = false; - if (isset($this->selectionTranslationFixBuilder[$nameListCode]) - && ArrayHelper::check( - $this->selectionTranslationFixBuilder[$nameListCode] - ) - && array_key_exists( - $filter['code'], - $this->selectionTranslationFixBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Selection.Translation')-> + exists($nameListCode . '.' . $filter['code'])) { $translation = true; } // add if this is a function path if ($funtion_path) { - $function[] = PHP_EOL . $this->_t(1) + $function[] = PHP_EOL . Indent::_(1) . "protected function getThe" . $filter['function'] . "Selections()"; - $function[] = $this->_t(1) . "{"; - $function[] = $this->_t(2) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(1) . "{"; + $function[] = Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Get a db connection."; } else { - $function[] = "//" . $this->setLine(__LINE__) + $function[] = "//" . Line::_(__Line__, __Class__) . " Get a db connection."; } - $function[] = $this->_t(2) . "\$db = JFactory::getDbo();"; - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) + $function[] = Indent::_(2) . "\$db = JFactory::getDbo();"; + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Create a new query object."; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query = \$db->getQuery(true);"; // check if usergroup as we change to an object query if ($filter['type'] === 'usergroup') { - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Select the text."; - $function[] = $this->_t(2) + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Select the text."; + $function[] = Indent::_(2) . "\$query->select(\$db->quoteName('g." . $filter['code'] . "', 'id'));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->select(\$db->quoteName('ug.title', 'title'));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->from(\$db->quoteName('#__" . $component . "_" . $filter['database'] . "', 'g'));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->join('LEFT', \$db->quoteName('#__usergroups', 'ug') . ' ON (' . (\$db->quoteName('g." . $filter['code'] . "') . ' = ' . \$db->quoteName('ug.id') . ')'));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->order(\$db->quoteName('title') . ' ASC');"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->group(\$db->quoteName('ug.id'));"; - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Reset the query using our newly populated query object."; - $function[] = $this->_t(2) . "\$db->setQuery(\$query);"; - $function[] = PHP_EOL . $this->_t(2) - . "\$results = \$db->loadObjectList();"; + $function[] = Indent::_(2) . "\$db->setQuery(\$query);"; + $function[] = PHP_EOL . Indent::_(2) + . "\$_results = \$db->loadObjectList();"; } else { - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Select the text."; - $function[] = $this->_t(2) + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Select the text."; + $function[] = Indent::_(2) . "\$query->select(\$db->quoteName('" . $filter['code'] . "'));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->from(\$db->quoteName('#__" . $component . "_" . $filter['database'] . "'));"; - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$query->order(\$db->quoteName('" . $filter['code'] . "') . ' ASC');"; - $function[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) + $function[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Reset the query using our newly populated query object."; - $function[] = $this->_t(2) . "\$db->setQuery(\$query);"; - $function[] = PHP_EOL . $this->_t(2) - . "\$results = \$db->loadColumn();"; + $function[] = Indent::_(2) . "\$db->setQuery(\$query);"; + $function[] = PHP_EOL . Indent::_(2) + . "\$_results = \$db->loadColumn();"; } - $function[] = $this->_t(2) . "\$_filter = array();"; + $function[] = Indent::_(2) . "\$_filter = array();"; // if this is not a multi field if (!$funtion_path && $filter['multi'] == 1) { - $function[] = $this->_t(2) + $function[] = Indent::_(2) . "\$_filter[] = JHtml::_('select.option', '', '- ' . JText:" . ":_('" . $filter['lang_select'] . "') . ' -');"; } - $function[] = PHP_EOL . $this->_t(2) . "if (\$results)"; - $function[] = $this->_t(2) . "{"; + $function[] = PHP_EOL . Indent::_(2) . "if (\$_results)"; + $function[] = Indent::_(2) . "{"; // check if translated value is used if ($funtion_path && $translation) { - $function[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " get model"; - $function[] = $this->_t(3) - . "\$model = \$this->getModel();"; + $function[] = Indent::_(3) + . "\$_model = \$this->getModel();"; } elseif ($translation) { - $function[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " get " . $nameListCode . "model"; - $function[] = $this->_t(3) - . "\$model = " . $Component . "Helper::getModel('" + $function[] = Indent::_(3) + . "\$_model = " . $Component . "Helper::getModel('" . $nameListCode . "');"; } // check if usergroup as we change to an object query if ($filter['type'] !== 'usergroup') { - $function[] = $this->_t(3) - . "\$results = array_unique(\$results);"; + $function[] = Indent::_(3) + . "\$_results = array_unique(\$_results);"; } - $function[] = $this->_t(3) . "foreach (\$results as \$" + $function[] = Indent::_(3) . "foreach (\$_results as \$" . $filter['code'] . ")"; - $function[] = $this->_t(3) . "{"; + $function[] = Indent::_(3) . "{"; // check if translated value is used if ($translation) { - $function[] = $this->_t(4) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Translate the " . $filter['code'] . " selection"; - $function[] = $this->_t(4) - . "\$text = \$model->selectionTranslation(\$" + $function[] = Indent::_(4) + . "\$_text = \$_model->selectionTranslation(\$" . $filter['code'] . ",'" . $filter['code'] . "');"; - $function[] = $this->_t(4) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Now add the " . $filter['code'] . " and its text to the options array"; - $function[] = $this->_t(4) + $function[] = Indent::_(4) . "\$_filter[] = JHtml::_('select.option', \$" - . $filter['code'] . ", JText:" . ":_(\$text));"; + . $filter['code'] . ", JText:" . ":_(\$_text));"; } elseif ($filter['type'] === 'user') { - $function[] = $this->_t(4) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Now add the " . $filter['code'] . " and its text to the options array"; - $function[] = $this->_t(4) + $function[] = Indent::_(4) . "\$_filter[] = JHtml::_('select.option', \$" . $filter['code'] . ", JFactory::getUser(\$" . $filter['code'] . ")->name);"; @@ -18418,34 +17334,34 @@ class Interpretation extends Fields { if ($filter['type'] === 'usergroup') { - $function[] = $this->_t(4) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Now add the " . $filter['code'] . " and its text to the options array"; - $function[] = $this->_t(4) + $function[] = Indent::_(4) . "\$_filter[] = JHtml::_('select.option', \$" . $filter['code'] . "->id, \$" . $filter['code'] . "->title);"; } else { - $function[] = $this->_t(4) . "//" . $this->setLine( - __LINE__ + $function[] = Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Now add the " . $filter['code'] . " and its text to the options array"; - $function[] = $this->_t(4) + $function[] = Indent::_(4) . "\$_filter[] = JHtml::_('select.option', \$" . $filter['code'] . ", \$" . $filter['code'] . ");"; } } - $function[] = $this->_t(3) . "}"; - $function[] = $this->_t(2) . "}"; - $function[] = $this->_t(2) . "return \$_filter;"; + $function[] = Indent::_(3) . "}"; + $function[] = Indent::_(2) . "}"; + $function[] = Indent::_(2) . "return \$_filter;"; // add if this is a function path if ($funtion_path) { - $function[] = $this->_t(1) . "}"; + $function[] = Indent::_(1) . "}"; } } // we check if this is a multi field @@ -18460,9 +17376,9 @@ class Interpretation extends Fields $filter['custom'] )['JFORM_TYPE_PHP']; // check for the [JHtml::_('select.option', '',] code - if (strpos($field_code, "JHtml::_('select.option', '',") + if (strpos((string) $field_code, "JHtml::_('select.option', '',") !== false - && strpos($field_code, '($this->multiple === false)') + && strpos((string) $field_code, '($this->multiple === false)') === false) { // for now we just give an error message (don't fix it) @@ -18471,11 +17387,11 @@ class Interpretation extends Fields 'Error' ); $field_url - = '"index.php?option=com_componentbuilder&view=fields&task=field.edit&id=' + = '"index.php?option=com_componentbuilder&view=fields&task=field.edit&id=' . $filter['id'] . '" target="_blank"'; $field_fix - = "
if (\$this->multiple === false) { // <-- this if statement is needed";
-						$field_fix .= PHP_EOL . $this->_t(1)
+							= "
if (\$this->multiple === false) { // <-- this if statement is needed";
+						$field_fix .= PHP_EOL . Indent::_(1)
 							. "\$options[] = JHtml::_('select.option', '', 'Select an option'); // <-- the empty option";
 						$field_fix .= PHP_EOL . "}
"; $this->app->enqueueMessage( @@ -18516,44 +17432,43 @@ class Interpretation extends Fields public function setUniqueFields(&$view) { $fields = array(); - $fields[] = PHP_EOL . PHP_EOL . $this->_t(1) . "/**"; - $fields[] = $this->_t(1) + $fields[] = PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $fields[] = Indent::_(1) . " * Method to get the unique fields of this table."; - $fields[] = $this->_t(1) . " *"; - $fields[] = $this->_t(1) + $fields[] = Indent::_(1) . " *"; + $fields[] = Indent::_(1) . " * @return mixed An array of field names, boolean false if none is set."; - $fields[] = $this->_t(1) . " *"; - $fields[] = $this->_t(1) . " * @since 3.0"; - $fields[] = $this->_t(1) . " */"; - $fields[] = $this->_t(1) . "protected function getUniqueFields()"; - $fields[] = $this->_t(1) . "{"; - if (isset($this->dbUniqueKeys[$view]) - && ArrayHelper::check($this->dbUniqueKeys[$view])) + $fields[] = Indent::_(1) . " *"; + $fields[] = Indent::_(1) . " * @since 3.0"; + $fields[] = Indent::_(1) . " */"; + $fields[] = Indent::_(1) . "protected function getUniqueFields()"; + $fields[] = Indent::_(1) . "{"; + if (CFactory::_('Compiler.Builder.Database.Unique.Keys')->exists($view)) { // if guid should also be added - if (isset($this->dbUniqueGuid[$view])) + if (CFactory::_('Compiler.Builder.Database.Unique.Guid')->exists($view)) { - $fields[] = $this->_t(2) . "return array('" . implode( - "','", $this->dbUniqueKeys[$view] + $fields[] = Indent::_(2) . "return array('" . implode( + "','", CFactory::_('Compiler.Builder.Database.Unique.Keys')->get($view) ) . "', 'guid');"; } else { - $fields[] = $this->_t(2) . "return array('" . implode( - "','", $this->dbUniqueKeys[$view] + $fields[] = Indent::_(2) . "return array('" . implode( + "','", CFactory::_('Compiler.Builder.Database.Unique.Keys')->get($view) ) . "');"; } } // if only GUID is found - elseif (isset($this->dbUniqueGuid[$view])) + elseif (CFactory::_('Compiler.Builder.Database.Unique.Guid')->exists($view)) { - $fields[] = $this->_t(2) . "return array('guid');"; + $fields[] = Indent::_(2) . "return array('guid');"; } else { - $fields[] = $this->_t(2) . "return false;"; + $fields[] = Indent::_(2) . "return false;"; } - $fields[] = $this->_t(1) . "}"; + $fields[] = Indent::_(1) . "}"; // return the unique fields return implode(PHP_EOL, $fields); @@ -18581,18 +17496,13 @@ class Interpretation extends Fields // add the category filter stuff $this->setCategorySidebarFilterHelper($fieldFilters, $nameListCode); // check if filter fields are added (1 = sidebar) - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 1 - && isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 1 + && CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { // get component name - $Component = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh]; + $Component = CFactory::_('Compiler.Builder.Content.One')->get('Component'); // load the rest of the filters - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { if ($filter['type'] != 'category' && ArrayHelper::check($filter['custom']) @@ -18608,53 +17518,53 @@ class Interpretation extends Fields $type = StringHelper::safe( $filter['custom']['type'], 'F' ); - $fieldFilters[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Set " . $CodeName + $fieldFilters[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Set " . $CodeName . " Selection"; - $fieldFilters[] = $this->_t(2) . "\$this->" . $codeName + $fieldFilters[] = Indent::_(2) . "\$this->" . $codeName . "Options = JFormHelper::loadFieldType('" . $type . "')->options;"; - $fieldFilters[] = $this->_t(2) . "//" . $this->setLine( - __LINE__ + $fieldFilters[] = Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " We do some sanitation for " . $CodeName . " filter"; - $fieldFilters[] = $this->_t(2) . "if (" . $Component + $fieldFilters[] = Indent::_(2) . "if (" . $Component . "Helper::checkArray(\$this->" . $codeName . "Options) &&"; - $fieldFilters[] = $this->_t(3) . "isset(\$this->" + $fieldFilters[] = Indent::_(3) . "isset(\$this->" . $codeName . "Options[0]->value) &&"; - $fieldFilters[] = $this->_t(3) . "!" . $Component + $fieldFilters[] = Indent::_(3) . "!" . $Component . "Helper::checkString(\$this->" . $codeName . "Options[0]->value))"; - $fieldFilters[] = $this->_t(2) . "{"; - $fieldFilters[] = $this->_t(3) . "unset(\$this->" + $fieldFilters[] = Indent::_(2) . "{"; + $fieldFilters[] = Indent::_(3) . "unset(\$this->" . $codeName . "Options[0]);"; - $fieldFilters[] = $this->_t(2) . "}"; - $fieldFilters[] = $this->_t(2) . "//" . $this->setLine( - __LINE__ + $fieldFilters[] = Indent::_(2) . "}"; + $fieldFilters[] = Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Only load " . $CodeName . " filter if it has values"; - $fieldFilters[] = $this->_t(2) . "if (" . $Component + $fieldFilters[] = Indent::_(2) . "if (" . $Component . "Helper::checkArray(\$this->" . $codeName . "Options))"; - $fieldFilters[] = $this->_t(2) . "{"; - $fieldFilters[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fieldFilters[] = Indent::_(2) . "{"; + $fieldFilters[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " " . $CodeName . " Filter"; - $fieldFilters[] = $this->_t(3) . "JHtmlSidebar::addFilter("; - $fieldFilters[] = $this->_t(4) . "'- Select ' . JText:" + $fieldFilters[] = Indent::_(3) . "JHtmlSidebar::addFilter("; + $fieldFilters[] = Indent::_(4) . "'- Select ' . JText:" . ":_('" . $filter['lang'] . "') . ' -',"; - $fieldFilters[] = $this->_t(4) . "'filter_" + $fieldFilters[] = Indent::_(4) . "'filter_" . $filter['code'] . "',"; - $fieldFilters[] = $this->_t(4) + $fieldFilters[] = Indent::_(4) . "JHtml::_('select.options', \$this->" . $codeName . "Options, 'value', 'text', \$this->state->get('filter." . $filter['code'] . "'))"; - $fieldFilters[] = $this->_t(3) . ");"; - $fieldFilters[] = $this->_t(2) . "}"; + $fieldFilters[] = Indent::_(3) . ");"; + $fieldFilters[] = Indent::_(2) . "}"; } elseif ($filter['type'] != 'category') { @@ -18675,53 +17585,53 @@ class Interpretation extends Fields $functionName = "\$this->getThe" . $filter['function'] . "Selections();"; } - $fieldFilters[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Set " . $Codename + $fieldFilters[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Set " . $Codename . " Selection"; - $fieldFilters[] = $this->_t(2) . "\$this->" + $fieldFilters[] = Indent::_(2) . "\$this->" . $filter['code'] . "Options = " . $functionName; - $fieldFilters[] = $this->_t(2) . "//" . $this->setLine( - __LINE__ + $fieldFilters[] = Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " We do some sanitation for " . $Codename . " filter"; - $fieldFilters[] = $this->_t(2) . "if (" . $Component + $fieldFilters[] = Indent::_(2) . "if (" . $Component . "Helper::checkArray(\$this->" . $filter['code'] . "Options) &&"; - $fieldFilters[] = $this->_t(3) . "isset(\$this->" + $fieldFilters[] = Indent::_(3) . "isset(\$this->" . $filter['code'] . "Options[0]->value) &&"; - $fieldFilters[] = $this->_t(3) . "!" . $Component + $fieldFilters[] = Indent::_(3) . "!" . $Component . "Helper::checkString(\$this->" . $filter['code'] . "Options[0]->value))"; - $fieldFilters[] = $this->_t(2) . "{"; - $fieldFilters[] = $this->_t(3) . "unset(\$this->" + $fieldFilters[] = Indent::_(2) . "{"; + $fieldFilters[] = Indent::_(3) . "unset(\$this->" . $filter['code'] . "Options[0]);"; - $fieldFilters[] = $this->_t(2) . "}"; - $fieldFilters[] = $this->_t(2) . "//" . $this->setLine( - __LINE__ + $fieldFilters[] = Indent::_(2) . "}"; + $fieldFilters[] = Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Only load " . $Codename . " filter if it has values"; - $fieldFilters[] = $this->_t(2) . "if (" . $Component + $fieldFilters[] = Indent::_(2) . "if (" . $Component . "Helper::checkArray(\$this->" . $filter['code'] . "Options))"; - $fieldFilters[] = $this->_t(2) . "{"; - $fieldFilters[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fieldFilters[] = Indent::_(2) . "{"; + $fieldFilters[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " " . $Codename . " Filter"; - $fieldFilters[] = $this->_t(3) . "JHtmlSidebar::addFilter("; - $fieldFilters[] = $this->_t(4) . "'- Select '.JText:" + $fieldFilters[] = Indent::_(3) . "JHtmlSidebar::addFilter("; + $fieldFilters[] = Indent::_(4) . "'- Select '.JText:" . ":_('" . $filter['lang'] . "').' -',"; - $fieldFilters[] = $this->_t(4) . "'filter_" + $fieldFilters[] = Indent::_(4) . "'filter_" . $filter['code'] . "',"; - $fieldFilters[] = $this->_t(4) + $fieldFilters[] = Indent::_(4) . "JHtml::_('select.options', \$this->" . $filter['code'] . "Options, 'value', 'text', \$this->state->get('filter." . $filter['code'] . "'))"; - $fieldFilters[] = $this->_t(3) . ");"; + $fieldFilters[] = Indent::_(3) . ");"; - $fieldFilters[] = $this->_t(2) . "}"; + $fieldFilters[] = Indent::_(2) . "}"; } } } @@ -18750,38 +17660,34 @@ class Interpretation extends Fields ) { // add the default filters if we are on the old filter paths (1 = sidebar) - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 1) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 1) { // set batch - $filter[] = PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $filter[] = PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Only load publish filter if state change is allowed"; - $filter[] = $this->_t(2) + $filter[] = Indent::_(2) . "if (\$this->canState)"; - $filter[] = $this->_t(2) . "{"; - $filter[] = $this->_t(3) . "JHtmlSidebar::addFilter("; - $filter[] = $this->_t(4) . "JText:" + $filter[] = Indent::_(2) . "{"; + $filter[] = Indent::_(3) . "JHtmlSidebar::addFilter("; + $filter[] = Indent::_(4) . "JText:" . ":_('JOPTION_SELECT_PUBLISHED'),"; - $filter[] = $this->_t(4) . "'filter_published',"; - $filter[] = $this->_t(4) + $filter[] = Indent::_(4) . "'filter_published',"; + $filter[] = Indent::_(4) . "JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', \$this->state->get('filter.published'), true)"; - $filter[] = $this->_t(3) . ");"; - $filter[] = $this->_t(2) . "}"; + $filter[] = Indent::_(3) . ");"; + $filter[] = Indent::_(2) . "}"; // check if view has access - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - ) - && !isset($this->fieldsNames[$nameSingleCode]['access'])) + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode) + && !CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.access')) { - $filter[] = PHP_EOL . $this->_t(2) . "JHtmlSidebar::addFilter("; - $filter[] = $this->_t(3) . "JText:" + $filter[] = PHP_EOL . Indent::_(2) . "JHtmlSidebar::addFilter("; + $filter[] = Indent::_(3) . "JText:" . ":_('JOPTION_SELECT_ACCESS'),"; - $filter[] = $this->_t(3) . "'filter_access',"; - $filter[] = $this->_t(3) + $filter[] = Indent::_(3) . "'filter_access',"; + $filter[] = Indent::_(3) . "JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', \$this->state->get('filter.access'))"; - $filter[] = $this->_t(2) . ");"; + $filter[] = Indent::_(2) . ");"; } } } @@ -18798,28 +17704,22 @@ class Interpretation extends Fields protected function setCategorySidebarFilterHelper(&$filter, &$nameListCode) { // add the category filter if we are on the old filter paths (1 = sidebar) - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 1 - && isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - ) - && isset($this->categoryBuilder[$nameListCode]['extension']) - && isset($this->categoryBuilder[$nameListCode]['filter']) - && $this->categoryBuilder[$nameListCode]['filter'] >= 1) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 1 + && CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.extension") + && CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.filter", 0) >= 1) { // set filter - $filter[] = PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Category Filter."; - $filter[] = $this->_t(2) . "JHtmlSidebar::addFilter("; - $filter[] = $this->_t(3) . "JText:" + $filter[] = PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Category Filter."; + $filter[] = Indent::_(2) . "JHtmlSidebar::addFilter("; + $filter[] = Indent::_(3) . "JText:" . ":_('JOPTION_SELECT_CATEGORY'),"; - $filter[] = $this->_t(3) . "'filter_category_id',"; - $filter[] = $this->_t(3) + $filter[] = Indent::_(3) . "'filter_category_id',"; + $filter[] = Indent::_(3) . "JHtml::_('select.options', JHtml::_('category.options', '" - . $this->categoryBuilder[$nameListCode]['extension'] + . CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension") . "'), 'value', 'text', \$this->state->get('filter.category_id'))"; - $filter[] = $this->_t(2) . ");"; + $filter[] = Indent::_(2) . ");"; } } @@ -18841,24 +17741,19 @@ class Interpretation extends Fields // add the category filter stuff $this->setCategoryBatchHelper($fieldBatch, $nameListCode); // check if we have other batch options to add - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { // check if we should add some help to get the values (2 = topbar) $get_values = false; - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 2) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 2) { // since the old path is not used, we need to add those values here $get_values = true; } // get component name - $Component = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh]; + $Component = CFactory::_('Compiler.Builder.Content.One')->get('Component'); // load the rest of the batch options - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { if ($filter['type'] != 'category' && ArrayHelper::check($filter['custom']) @@ -18871,58 +17766,58 @@ class Interpretation extends Fields . StringHelper::safe( $filter['custom']['text'], 'F' ); - $fieldBatch[] = PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $fieldBatch[] = PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Only load " . $CodeName . " batch if create, edit, and batch is allowed"; - $fieldBatch[] = $this->_t(2) + $fieldBatch[] = Indent::_(2) . "if (\$this->canBatch && \$this->canCreate && \$this->canEdit)"; - $fieldBatch[] = $this->_t(2) . "{"; + $fieldBatch[] = Indent::_(2) . "{"; // add the get values here if ($get_values) { $type = StringHelper::safe( $filter['custom']['type'], 'F' ); - $fieldBatch[] = $this->_t(3) . "//" - . $this->setLine(__LINE__) . " Set " . $CodeName + $fieldBatch[] = Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Set " . $CodeName . " Selection"; - $fieldBatch[] = $this->_t(3) . "\$this->" . $codeName + $fieldBatch[] = Indent::_(3) . "\$this->" . $codeName . "Options = JFormHelper::loadFieldType('" . $type . "')->options;"; - $fieldBatch[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fieldBatch[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " We do some sanitation for " . $CodeName . " filter"; - $fieldBatch[] = $this->_t(3) . "if (" . $Component + $fieldBatch[] = Indent::_(3) . "if (" . $Component . "Helper::checkArray(\$this->" . $codeName . "Options) &&"; - $fieldBatch[] = $this->_t(4) . "isset(\$this->" + $fieldBatch[] = Indent::_(4) . "isset(\$this->" . $codeName . "Options[0]->value) &&"; - $fieldBatch[] = $this->_t(4) . "!" . $Component + $fieldBatch[] = Indent::_(4) . "!" . $Component . "Helper::checkString(\$this->" . $codeName . "Options[0]->value))"; - $fieldBatch[] = $this->_t(3) . "{"; - $fieldBatch[] = $this->_t(4) . "unset(\$this->" + $fieldBatch[] = Indent::_(3) . "{"; + $fieldBatch[] = Indent::_(4) . "unset(\$this->" . $codeName . "Options[0]);"; - $fieldBatch[] = $this->_t(3) . "}"; + $fieldBatch[] = Indent::_(3) . "}"; } - $fieldBatch[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fieldBatch[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " " . $CodeName . " Batch Selection"; - $fieldBatch[] = $this->_t(3) + $fieldBatch[] = Indent::_(3) . "JHtmlBatch_::addListSelection("; - $fieldBatch[] = $this->_t(4) . "'- Keep Original '.JText:" + $fieldBatch[] = Indent::_(4) . "'- Keep Original '.JText:" . ":_('" . $filter['lang'] . "').' -',"; - $fieldBatch[] = $this->_t(4) . "'batch[" . $filter['code'] + $fieldBatch[] = Indent::_(4) . "'batch[" . $filter['code'] . "]',"; - $fieldBatch[] = $this->_t(4) + $fieldBatch[] = Indent::_(4) . "JHtml::_('select.options', \$this->" . $codeName . "Options, 'value', 'text')"; - $fieldBatch[] = $this->_t(3) . ");"; - $fieldBatch[] = $this->_t(2) . "}"; + $fieldBatch[] = Indent::_(3) . ");"; + $fieldBatch[] = Indent::_(2) . "}"; } elseif ($filter['type'] != 'category') { @@ -18930,55 +17825,55 @@ class Interpretation extends Fields $filter['code'], 'W' ); - $fieldBatch[] = PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $fieldBatch[] = PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Only load " . $CodeName . " batch if create, edit, and batch is allowed"; - $fieldBatch[] = $this->_t(2) + $fieldBatch[] = Indent::_(2) . "if (\$this->canBatch && \$this->canCreate && \$this->canEdit)"; - $fieldBatch[] = $this->_t(2) . "{"; + $fieldBatch[] = Indent::_(2) . "{"; // add the get values here if ($get_values) { - $fieldBatch[] = $this->_t(3) . "//" - . $this->setLine(__LINE__) . " Set " . $CodeName + $fieldBatch[] = Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Set " . $CodeName . " Selection"; - $fieldBatch[] = $this->_t(3) . "\$this->" + $fieldBatch[] = Indent::_(3) . "\$this->" . $filter['code'] . "Options = JFormHelper::loadFieldType('" . $filter['filter_type'] . "')->options;"; - $fieldBatch[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fieldBatch[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " We do some sanitation for " . $CodeName . " filter"; - $fieldBatch[] = $this->_t(3) . "if (" . $Component + $fieldBatch[] = Indent::_(3) . "if (" . $Component . "Helper::checkArray(\$this->" . $filter['code'] . "Options) &&"; - $fieldBatch[] = $this->_t(4) . "isset(\$this->" + $fieldBatch[] = Indent::_(4) . "isset(\$this->" . $filter['code'] . "Options[0]->value) &&"; - $fieldBatch[] = $this->_t(4) . "!" . $Component + $fieldBatch[] = Indent::_(4) . "!" . $Component . "Helper::checkString(\$this->" . $filter['code'] . "Options[0]->value))"; - $fieldBatch[] = $this->_t(3) . "{"; - $fieldBatch[] = $this->_t(4) . "unset(\$this->" + $fieldBatch[] = Indent::_(3) . "{"; + $fieldBatch[] = Indent::_(4) . "unset(\$this->" . $filter['code'] . "Options[0]);"; - $fieldBatch[] = $this->_t(3) . "}"; + $fieldBatch[] = Indent::_(3) . "}"; } - $fieldBatch[] = $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fieldBatch[] = Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " " . $CodeName . " Batch Selection"; - $fieldBatch[] = $this->_t(3) + $fieldBatch[] = Indent::_(3) . "JHtmlBatch_::addListSelection("; - $fieldBatch[] = $this->_t(4) . "'- Keep Original '.JText:" + $fieldBatch[] = Indent::_(4) . "'- Keep Original '.JText:" . ":_('" . $filter['lang'] . "').' -',"; - $fieldBatch[] = $this->_t(4) . "'batch[" . $filter['code'] + $fieldBatch[] = Indent::_(4) . "'batch[" . $filter['code'] . "]',"; - $fieldBatch[] = $this->_t(4) + $fieldBatch[] = Indent::_(4) . "JHtml::_('select.options', \$this->" . $filter['code'] . "Options, 'value', 'text')"; - $fieldBatch[] = $this->_t(3) . ");"; - $fieldBatch[] = $this->_t(2) . "}"; + $fieldBatch[] = Indent::_(3) . ");"; + $fieldBatch[] = Indent::_(2) . "}"; } } } @@ -19004,45 +17899,43 @@ class Interpretation extends Fields protected function setDefaultBatchHelper(&$batch, &$nameSingleCode) { // set component name + $COPMONENT = CFactory::_('Component')->get('name_code'); $COPMONENT = StringHelper::safe( - $this->componentData->name_code, 'U' + $COPMONENT, 'U' ); // set batch - $batch[] = PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $batch[] = PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Only load published batch if state and batch is allowed"; - $batch[] = $this->_t(2) + $batch[] = Indent::_(2) . "if (\$this->canState && \$this->canBatch)"; - $batch[] = $this->_t(2) . "{"; - $batch[] = $this->_t(3) . "JHtmlBatch_::addListSelection("; - $batch[] = $this->_t(4) . "JText:" . ":_('COM_" . $COPMONENT + $batch[] = Indent::_(2) . "{"; + $batch[] = Indent::_(3) . "JHtmlBatch_::addListSelection("; + $batch[] = Indent::_(4) . "JText:" . ":_('COM_" . $COPMONENT . "_KEEP_ORIGINAL_STATE'),"; - $batch[] = $this->_t(4) . "'batch[published]',"; - $batch[] = $this->_t(4) + $batch[] = Indent::_(4) . "'batch[published]',"; + $batch[] = Indent::_(4) . "JHtml::_('select.options', JHtml::_('jgrid.publishedOptions', array('all' => false)), 'value', 'text', '', true)"; - $batch[] = $this->_t(3) . ");"; - $batch[] = $this->_t(2) . "}"; + $batch[] = Indent::_(3) . ");"; + $batch[] = Indent::_(2) . "}"; // check if view has access - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - ) - && !isset($this->fieldsNames[$nameSingleCode]['access'])) + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode) + && !CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.access')) { - $batch[] = PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $batch[] = PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Only load access batch if create, edit and batch is allowed"; - $batch[] = $this->_t(2) + $batch[] = Indent::_(2) . "if (\$this->canBatch && \$this->canCreate && \$this->canEdit)"; - $batch[] = $this->_t(2) . "{"; - $batch[] = $this->_t(3) . "JHtmlBatch_::addListSelection("; - $batch[] = $this->_t(4) . "JText:" . ":_('COM_" . $COPMONENT + $batch[] = Indent::_(2) . "{"; + $batch[] = Indent::_(3) . "JHtmlBatch_::addListSelection("; + $batch[] = Indent::_(4) . "JText:" . ":_('COM_" . $COPMONENT . "_KEEP_ORIGINAL_ACCESS'),"; - $batch[] = $this->_t(4) . "'batch[access]',"; - $batch[] = $this->_t(4) + $batch[] = Indent::_(4) . "'batch[access]',"; + $batch[] = Indent::_(4) . "JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text')"; - $batch[] = $this->_t(3) . ");"; - $batch[] = $this->_t(2) . "}"; + $batch[] = Indent::_(3) . ");"; + $batch[] = Indent::_(2) . "}"; } } @@ -19057,45 +17950,37 @@ class Interpretation extends Fields */ protected function setCategoryBatchHelper(&$batch, &$nameListCode) { - if (isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - ) - && isset($this->categoryBuilder[$nameListCode]['extension'])) + if (CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.extension")) { // set component name - $COPMONENT = StringHelper::safe( - $this->componentData->name_code, 'U' - ); + $COPMONENT = CFactory::_('Component')->get('name_code'); + $COPMONENT = StringHelper::safe($COPMONENT, 'U'); // set filter - $batch[] = PHP_EOL . $this->_t(2) + $batch[] = PHP_EOL . Indent::_(2) . "if (\$this->canBatch && \$this->canCreate && \$this->canEdit)"; - $batch[] = $this->_t(2) . "{"; - $batch[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $batch[] = Indent::_(2) . "{"; + $batch[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Category Batch selection."; - $batch[] = $this->_t(3) . "JHtmlBatch_::addListSelection("; - $batch[] = $this->_t(4) . "JText:" . ":_('COM_" . $COPMONENT + $batch[] = Indent::_(3) . "JHtmlBatch_::addListSelection("; + $batch[] = Indent::_(4) . "JText:" . ":_('COM_" . $COPMONENT . "_KEEP_ORIGINAL_CATEGORY'),"; - $batch[] = $this->_t(4) . "'batch[category]',"; - $batch[] = $this->_t(4) + $batch[] = Indent::_(4) . "'batch[category]',"; + $batch[] = Indent::_(4) . "JHtml::_('select.options', JHtml::_('category.options', '" - . $this->categoryBuilder[$nameListCode]['extension'] + . CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension") . "'), 'value', 'text')"; - $batch[] = $this->_t(3) . ");"; - $batch[] = $this->_t(2) . "}"; + $batch[] = Indent::_(3) . ");"; + $batch[] = Indent::_(2) . "}"; } } public function setRouterCategoryViews($nameSingleCode, $nameListCode) { - if (isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.extension")) { - // get the actual extention - $_extension = $this->categoryBuilder[$nameListCode]['extension']; - $_extension = explode('.', $_extension); + // get the actual extension + $_extension = CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension"); + $_extension = explode('.', (string) $_extension); // set component name if (ArrayHelper::check($_extension)) { @@ -19103,86 +17988,58 @@ class Interpretation extends Fields } else { - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; } // check if category has another name - if (isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews = $this->catOtherName[$nameListCode]['views']; - $otherView = $this->catOtherName[$nameListCode]['view']; - } - else - { - $otherViews = $nameListCode; - $otherView = $nameSingleCode; - } + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); + $otherView = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.view', $nameSingleCode); // set the OtherView value - $this->fileContentDynamic['category' . $otherView][$this->hhh - . 'otherview' . $this->hhh] - = $otherView; + CFactory::_('Compiler.Builder.Content.Multi')->set('category' . $otherView . '|otherview', $otherView); // load the category helper details in not already loaded - if (!isset( - $this->fileContentDynamic['category' . $otherView][$this->hhh - . 'view' . $this->hhh] - )) + if (!CFactory::_('Compiler.Builder.Content.Multi')->exists('category' . $otherView . '|view')) { // lets also set the category helper for this view $target = array('site' => 'category' . $otherView); - $this->buildDynamique($target, 'category'); + CFactory::_('Utilities.Structure')->build($target, 'category'); // insure the file gets updated - $this->fileContentDynamic['category' . $otherView][$this->hhh - . 'view' . $this->hhh] - = $otherView; - $this->fileContentDynamic['category' . $otherView][$this->hhh - . 'View' . $this->hhh] - = ucfirst($otherView); - $this->fileContentDynamic['category' . $otherView][$this->hhh - . 'views' . $this->hhh] - = $otherViews; - $this->fileContentDynamic['category' . $otherView][$this->hhh - . 'Views' . $this->hhh] - = ucfirst($otherViews); + CFactory::_('Compiler.Builder.Content.Multi')->set('category' . $otherView . '|view', $otherView); + CFactory::_('Compiler.Builder.Content.Multi')->set('category' . $otherView . '|View', ucfirst((string) $otherView)); + CFactory::_('Compiler.Builder.Content.Multi')->set('category' . $otherView . '|views', $otherViews); + CFactory::_('Compiler.Builder.Content.Multi')->set('category' . $otherView . '|Views', ucfirst((string) $otherViews)); // set script to global helper file $includeHelper = array(); - $includeHelper[] = "\n//" . $this->setLine(__LINE__) + $includeHelper[] = "\n//" . Line::_(__Line__, __Class__) . "Insure this view category file is loaded."; - $includeHelper[] = "\$classname = '" . ucfirst($component) - . ucfirst($otherView) . "Categories';"; + $includeHelper[] = "\$classname = '" . ucfirst((string) $component) + . ucfirst((string) $otherView) . "Categories';"; $includeHelper[] = "if (!class_exists(\$classname))"; $includeHelper[] = "{"; - $includeHelper[] = $this->_t(1) + $includeHelper[] = Indent::_(1) . "\$path = JPATH_SITE . '/components/com_" . $component . "/helpers/category" . $otherView . ".php';"; - $includeHelper[] = $this->_t(1) . "if (is_file(\$path))"; - $includeHelper[] = $this->_t(1) . "{"; - $includeHelper[] = $this->_t(2) . "include_once \$path;"; - $includeHelper[] = $this->_t(1) . "}"; + $includeHelper[] = Indent::_(1) . "if (is_file(\$path))"; + $includeHelper[] = Indent::_(1) . "{"; + $includeHelper[] = Indent::_(2) . "include_once \$path;"; + $includeHelper[] = Indent::_(1) . "}"; $includeHelper[] = "}"; - $this->fileContentStatic[$this->hhh . 'CATEGORY_CLASS_TREES' - . $this->hhh] - .= implode("\n", $includeHelper); + CFactory::_('Compiler.Builder.Content.One')->add('CATEGORY_CLASS_TREES', implode("\n", $includeHelper)); } // return category view string - if (isset( - $this->fileContentStatic[$this->hhh - . 'ROUTER_CATEGORY_VIEWS' . $this->hhh] - ) + if (CFactory::_('Compiler.Builder.Content.One')->exists('ROUTER_CATEGORY_VIEWS') && StringHelper::check( - $this->fileContentStatic[$this->hhh - . 'ROUTER_CATEGORY_VIEWS' . $this->hhh] + CFactory::_('Compiler.Builder.Content.One')->get('ROUTER_CATEGORY_VIEWS') )) { - return "," . PHP_EOL . $this->_t(3) . '"' - . $this->categoryBuilder[$nameListCode]['extension'] + return "," . PHP_EOL . Indent::_(3) . '"' + . CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension") . '" => "' . $otherView . '"'; } else { - return PHP_EOL . $this->_t(3) . '"' - . $this->categoryBuilder[$nameListCode]['extension'] + return PHP_EOL . Indent::_(3) . '"' + . CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension") . '" => "' . $otherView . '"'; } } @@ -19194,153 +18051,109 @@ class Interpretation extends Fields { $allow = array(); // set component name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; // prepare custom permission script - $customAllow = $this->getCustomScriptBuilder( + $customAllow = CFactory::_('Customcode.Dispenser')->get( 'php_allowadd', $nameSingleCode, '', null, true ); - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } // check if item has category - if (0) //isset($this->categoryBuilder[$nameListCode]) && ArrayHelper::check($this->categoryBuilder[$nameListCode])) <-- remove category from check + if (0) //CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}")) <-- remove category from check { // check if category has another name - if ($coreLoad && isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews = $this->catOtherName[$nameListCode]['views']; - $otherView = $this->catOtherName[$nameListCode]['view']; - } - else - { - $otherViews = $nameListCode; - $otherView = $nameSingleCode; - } + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); + $otherView = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.view', $nameSingleCode); // setup the category script - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get the user object"; - $allow[] = $this->_t(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "\$user = JFactory::getUser();"; // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $otherView, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($otherView, 'core.access')) { - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Access check."; - $allow[] = $this->_t(2) . "\$access = \$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "');"; - $allow[] = $this->_t(2) . "if (!\$access)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "return false;"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(2) . "\$access = \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($otherView, 'core.access') + . "', 'com_" . $component . "');"; + $allow[] = Indent::_(2) . "if (!\$access)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "return false;"; + $allow[] = Indent::_(2) . "}"; } - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "\$categoryId = ArrayHelper::getValue(\$data, 'catid', \$this->input->getInt('filter_category_id'), 'int');"; - $allow[] = $this->_t(2) . "\$allow = null;"; - $allow[] = PHP_EOL . $this->_t(2) . "if (\$categoryId)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "\$allow = null;"; + $allow[] = PHP_EOL . Indent::_(2) . "if (\$categoryId)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " If the category has been passed in the URL check it."; - $allow[] = $this->_t(3) + $allow[] = Indent::_(3) . "\$allow = \$user->authorise('core.create', \$this->option . '." . $otherView . ".category.' . \$categoryId);"; - $allow[] = $this->_t(2) . "}"; - $allow[] = PHP_EOL . $this->_t(2) . "if (\$allow === null)"; - $allow[] = $this->_t(2) . "{"; + $allow[] = Indent::_(2) . "}"; + $allow[] = PHP_EOL . Indent::_(2) . "if (\$allow === null)"; + $allow[] = Indent::_(2) . "{"; // check if the item has permissions. - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.access')) { // setup the default script - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(3) . "return \$user->authorise('" - . $core['core.create'] . "', \$this->option);"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(3) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') + . "', \$this->option);"; } else { // setup the default script - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(3) . "return parent::allowAdd(\$data);"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(3) . "return parent::allowAdd(\$data);"; } - $allow[] = $this->_t(2) . "}"; - $allow[] = $this->_t(2) . "else"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "return \$allow;"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(2) . "}"; + $allow[] = Indent::_(2) . "else"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "return \$allow;"; + $allow[] = Indent::_(2) . "}"; } else { - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Get user object."; - $allow[] = $this->_t(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "\$user = JFactory::getUser();"; // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.access')) { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Access check."; - $allow[] = $this->_t(2) . "\$access = \$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "');"; - $allow[] = $this->_t(2) . "if (!\$access)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "return false;"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(2) . "\$access = \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.access') + . "', 'com_" . $component . "');"; + $allow[] = Indent::_(2) . "if (!\$access)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "return false;"; + $allow[] = Indent::_(2) . "}"; } // load custom permission script $allow[] = $customAllow; // check if the item has permissions. - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.create')) { // setup the default script - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(2) . "return \$user->authorise('" - . $core['core.create'] . "', \$this->option);"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(2) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') + . "', \$this->option);"; } else { // setup the default script - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(2) . "return parent::allowAdd(\$data);"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(2) . "return parent::allowAdd(\$data);"; } } @@ -19351,354 +18164,202 @@ class Interpretation extends Fields { $allow = array(); // set component name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; // prepare custom permission script - $customAllow = $this->getCustomScriptBuilder( + $customAllow = CFactory::_('Customcode.Dispenser')->get( 'php_allowedit', $nameSingleCode, '', null, true ); - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } - if (isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}")) { // check if category has another name - if ($coreLoad && isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews = $this->catOtherName[$nameListCode]['views']; - $otherView = $this->catOtherName[$nameListCode]['view']; - } - else - { - $otherViews = $nameListCode; - $otherView = $nameSingleCode; - } + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); + $otherView = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.view', $nameSingleCode); // setup the category script - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get user object."; - $allow[] = $this->_t(2) . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get record id."; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "\$recordId = (int) isset(\$data[\$key]) ? \$data[\$key] : 0;"; // load custom permission script $allow[] = $customAllow; // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $otherView, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($otherView, 'core.access')) { - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Access check."; - $allow[] = $this->_t(2) . "\$access = (\$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "." - . $otherView + $allow[] = Indent::_(2) . "\$access = (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($otherView, 'core.access') + . "', 'com_" . $component . "." . $otherView . ".' . (int) \$recordId) && \$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "'));"; - $allow[] = $this->_t(2) . "if (!\$access)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "return false;"; - $allow[] = $this->_t(2) . "}"; + . CFactory::_('Compiler.Creator.Permission')->getGlobal($otherView, 'core.access') + . "', 'com_" . $component . "'));"; + $allow[] = Indent::_(2) . "if (!\$access)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "return false;"; + $allow[] = Indent::_(2) . "}"; } - $allow[] = PHP_EOL . $this->_t(2) . "if (\$recordId)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "if (\$recordId)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " The record has been set. Check the record permissions."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder[$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit']] - ) - && in_array( - $otherView, $this->permissionBuilder[$core['core.edit']] - )) - { - $allow[] = $this->_t(3) . "\$permission = \$user->authorise('" - . $core['core.edit'] . "', 'com_" . $component . "." - . $otherView . ".' . (int) \$recordId);"; - } - else - { - $allow[] = $this->_t(3) - . "\$permission = \$user->authorise('core.edit', 'com_" - . $component . "." . $otherView . ".' . (int) \$recordId);"; - } - $allow[] = $this->_t(3) . "if (!\$permission)"; - $allow[] = $this->_t(3) . "{"; + $allow[] = Indent::_(3) . "\$permission = \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($otherView, 'core.edit') . "', 'com_" . $component . "." + . $otherView . ".' . (int) \$recordId);"; + $allow[] = Indent::_(3) . "if (!\$permission)"; + $allow[] = Indent::_(3) . "{"; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.own']) - && isset($this->permissionBuilder[$core['core.edit.own']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.own']] - ) - && in_array( - $otherView, $this->permissionBuilder[$core['core.edit.own']] - )) - { - $allow[] = $this->_t(4) . "if (\$user->authorise('" - . $core['core.edit.own'] . "', 'com_" . $component . "." - . $otherView . ".' . \$recordId))"; - } - else - { - $allow[] = $this->_t(4) - . "if (\$user->authorise('core.edit.own', 'com_" - . $component . "." . $otherView . ".' . \$recordId))"; - } - $allow[] = $this->_t(4) . "{"; - $allow[] = $this->_t(5) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "if (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($otherView, 'core.edit.own') . "', 'com_" . $component . "." + . $otherView . ".' . \$recordId))"; + $allow[] = Indent::_(4) . "{"; + $allow[] = Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " Fallback on edit.own. Now test the owner is the user."; - $allow[] = $this->_t(5) + $allow[] = Indent::_(5) . "\$ownerId = (int) isset(\$data['created_by']) ? \$data['created_by'] : 0;"; - $allow[] = $this->_t(5) . "if (empty(\$ownerId))"; - $allow[] = $this->_t(5) . "{"; - $allow[] = $this->_t(6) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(5) . "if (empty(\$ownerId))"; + $allow[] = Indent::_(5) . "{"; + $allow[] = Indent::_(6) . "//" . Line::_(__Line__, __Class__) . " Need to do a lookup from the model."; - $allow[] = $this->_t(6) + $allow[] = Indent::_(6) . "\$record = \$this->getModel()->getItem(\$recordId);"; - $allow[] = PHP_EOL . $this->_t(6) . "if (empty(\$record))"; - $allow[] = $this->_t(6) . "{"; - $allow[] = $this->_t(7) . "return false;"; - $allow[] = $this->_t(6) . "}"; - $allow[] = $this->_t(6) . "\$ownerId = \$record->created_by;"; - $allow[] = $this->_t(5) . "}"; - $allow[] = PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(6) . "if (empty(\$record))"; + $allow[] = Indent::_(6) . "{"; + $allow[] = Indent::_(7) . "return false;"; + $allow[] = Indent::_(6) . "}"; + $allow[] = Indent::_(6) . "\$ownerId = \$record->created_by;"; + $allow[] = Indent::_(5) . "}"; + $allow[] = PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " If the owner matches 'me' then do the test."; - $allow[] = $this->_t(5) . "if (\$ownerId == \$user->id)"; - $allow[] = $this->_t(5) . "{"; + $allow[] = Indent::_(5) . "if (\$ownerId == \$user->id)"; + $allow[] = Indent::_(5) . "{"; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.own']) - && isset($this->permissionBuilder['global'][$core['core.edit.own']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit.own']] - ) - && in_array( - $otherView, - $this->permissionBuilder['global'][$core['core.edit.own']] - )) + $allow[] = Indent::_(6) . "if (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($otherView, 'core.edit.own') . "', 'com_" . $component . "'))"; + $allow[] = Indent::_(6) . "{"; + $allow[] = Indent::_(7) . "return true;"; + $allow[] = Indent::_(6) . "}"; + $allow[] = Indent::_(5) . "}"; + $allow[] = Indent::_(4) . "}"; + $allow[] = Indent::_(4) . "return false;"; + $allow[] = Indent::_(3) . "}"; +// $allow[] = PHP_EOL.Indent::_(3) . "\$categoryId = (int) isset(\$data['catid']) ? \$data['catid']: \$this->getModel()->getItem(\$recordId)->catid;"; <-- remove category from check +// $allow[] = PHP_EOL.Indent::_(3) . "if (\$categoryId)"; +// $allow[] = Indent::_(3) . "{"; +// $allow[] = Indent::_(4) . "//".Line::_(__Line__, __Class__)." The category has been set. Check the category permissions."; +// $allow[] = Indent::_(4) . "\$catpermission = \$user->authorise('core.edit', \$this->option . '.".$otherView.".category.' . \$categoryId);"; +// $allow[] = Indent::_(4) . "if (!\$catpermission && !is_null(\$catpermission))"; +// $allow[] = Indent::_(4) . "{"; +// $allow[] = Indent::_(5) . "return false;"; +// $allow[] = Indent::_(4) . "}"; +// $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; + if (CFactory::_('Compiler.Creator.Permission')->globalExist($otherView, 'core.edit')) { - $allow[] = $this->_t(6) . "if (\$user->authorise('" - . $core['core.edit.own'] . "', 'com_" . $component . "'))"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " Since there is no permission, revert to the component permissions."; + $allow[] = Indent::_(2) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($otherView, 'core.edit') . "', \$this->option);"; } else { - $allow[] = $this->_t(6) - . "if (\$user->authorise('core.edit.own', 'com_" - . $component . "'))"; - } - $allow[] = $this->_t(6) . "{"; - $allow[] = $this->_t(7) . "return true;"; - $allow[] = $this->_t(6) . "}"; - $allow[] = $this->_t(5) . "}"; - $allow[] = $this->_t(4) . "}"; - $allow[] = $this->_t(4) . "return false;"; - $allow[] = $this->_t(3) . "}"; -// $allow[] = PHP_EOL.$this->_t(3) . "\$categoryId = (int) isset(\$data['catid']) ? \$data['catid']: \$this->getModel()->getItem(\$recordId)->catid;"; <-- remove category from check -// $allow[] = PHP_EOL.$this->_t(3) . "if (\$categoryId)"; -// $allow[] = $this->_t(3) . "{"; -// $allow[] = $this->_t(4) . "//".$this->setLine(__LINE__)." The category has been set. Check the category permissions."; -// $allow[] = $this->_t(4) . "\$catpermission = \$user->authorise('core.edit', \$this->option . '.".$otherView.".category.' . \$categoryId);"; -// $allow[] = $this->_t(4) . "if (!\$catpermission && !is_null(\$catpermission))"; -// $allow[] = $this->_t(4) . "{"; -// $allow[] = $this->_t(5) . "return false;"; -// $allow[] = $this->_t(4) . "}"; -// $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder['global'][$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit']] - ) - && in_array( - $otherView, - $this->permissionBuilder['global'][$core['core.edit']] - )) - { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Since there is no permission, revert to the component permissions."; - $allow[] = $this->_t(2) . "return \$user->authorise('" - . $core['core.edit'] . "', \$this->option);"; - } - else - { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " Since there is no permission, revert to the component permissions."; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "return parent::allowEdit(\$data, \$key);"; } } else { // setup the category script - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get user object."; - $allow[] = $this->_t(2) . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " get record id."; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "\$recordId = (int) isset(\$data[\$key]) ? \$data[\$key] : 0;"; // load custom permission script $allow[] = $customAllow; // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder[$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.access']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.access')) { - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Access check."; - $allow[] = $this->_t(2) . "\$access = (\$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "." + $allow[] = Indent::_(2) . "\$access = (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.access') . "', 'com_" . $component . "." . $nameSingleCode - . ".' . (int) \$recordId) && \$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "'));"; - $allow[] = $this->_t(2) . "if (!\$access)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "return false;"; - $allow[] = $this->_t(2) . "}"; + . ".' . (int) \$recordId) && \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.access') . "', 'com_" . $component . "'));"; + $allow[] = Indent::_(2) . "if (!\$access)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "return false;"; + $allow[] = Indent::_(2) . "}"; } - $allow[] = PHP_EOL . $this->_t(2) . "if (\$recordId)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "if (\$recordId)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " The record has been set. Check the record permissions."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder[$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit']] - )) - { - $allow[] = $this->_t(3) . "\$permission = \$user->authorise('" - . $core['core.edit'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$recordId);"; - } - else - { - $allow[] = $this->_t(3) - . "\$permission = \$user->authorise('core.edit', 'com_" - . $component . "." . $nameSingleCode - . ".' . (int) \$recordId);"; - } - $allow[] = $this->_t(3) . "if (!\$permission)"; - $allow[] = $this->_t(3) . "{"; + $allow[] = Indent::_(3) . "\$permission = \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit') . "', 'com_" . $component . "." + . $nameSingleCode . ".' . (int) \$recordId);"; + $allow[] = Indent::_(3) . "if (!\$permission)"; + $allow[] = Indent::_(3) . "{"; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.own']) - && isset($this->permissionBuilder[$core['core.edit.own']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.own']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.own']] - )) - { - $allow[] = $this->_t(4) . "if (\$user->authorise('" - . $core['core.edit.own'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . \$recordId))"; - } - else - { - $allow[] = $this->_t(4) - . "if (\$user->authorise('core.edit.own', 'com_" - . $component . "." . $nameSingleCode - . ".' . \$recordId))"; - } - $allow[] = $this->_t(4) . "{"; - $allow[] = $this->_t(5) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "if (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.own') . "', 'com_" . $component . "." + . $nameSingleCode . ".' . \$recordId))"; + $allow[] = Indent::_(4) . "{"; + $allow[] = Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " Now test the owner is the user."; - $allow[] = $this->_t(5) + $allow[] = Indent::_(5) . "\$ownerId = (int) isset(\$data['created_by']) ? \$data['created_by'] : 0;"; - $allow[] = $this->_t(5) . "if (empty(\$ownerId))"; - $allow[] = $this->_t(5) . "{"; - $allow[] = $this->_t(6) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(5) . "if (empty(\$ownerId))"; + $allow[] = Indent::_(5) . "{"; + $allow[] = Indent::_(6) . "//" . Line::_(__Line__, __Class__) . " Need to do a lookup from the model."; - $allow[] = $this->_t(6) + $allow[] = Indent::_(6) . "\$record = \$this->getModel()->getItem(\$recordId);"; - $allow[] = PHP_EOL . $this->_t(6) . "if (empty(\$record))"; - $allow[] = $this->_t(6) . "{"; - $allow[] = $this->_t(7) . "return false;"; - $allow[] = $this->_t(6) . "}"; - $allow[] = $this->_t(6) . "\$ownerId = \$record->created_by;"; - $allow[] = $this->_t(5) . "}"; - $allow[] = PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(6) . "if (empty(\$record))"; + $allow[] = Indent::_(6) . "{"; + $allow[] = Indent::_(7) . "return false;"; + $allow[] = Indent::_(6) . "}"; + $allow[] = Indent::_(6) . "\$ownerId = \$record->created_by;"; + $allow[] = Indent::_(5) . "}"; + $allow[] = PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " If the owner matches 'me' then allow."; - $allow[] = $this->_t(5) . "if (\$ownerId == \$user->id)"; - $allow[] = $this->_t(5) . "{"; + $allow[] = Indent::_(5) . "if (\$ownerId == \$user->id)"; + $allow[] = Indent::_(5) . "{"; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.own']) - && isset($this->permissionBuilder['global'][$core['core.edit.own']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit.own']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit.own']] - )) + $allow[] = Indent::_(6) . "if (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit.own') . "', 'com_" . $component . "'))"; + $allow[] = Indent::_(6) . "{"; + $allow[] = Indent::_(7) . "return true;"; + $allow[] = Indent::_(6) . "}"; + $allow[] = Indent::_(5) . "}"; + $allow[] = Indent::_(4) . "}"; + $allow[] = Indent::_(4) . "return false;"; + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.edit')) { - $allow[] = $this->_t(6) . "if (\$user->authorise('" - . $core['core.edit.own'] . "', 'com_" . $component . "'))"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " Since there is no permission, revert to the component permissions."; + $allow[] = Indent::_(2) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit') . "', \$this->option);"; } else { - $allow[] = $this->_t(6) - . "if (\$user->authorise('core.edit.own', 'com_" - . $component . "'))"; - } - $allow[] = $this->_t(6) . "{"; - $allow[] = $this->_t(7) . "return true;"; - $allow[] = $this->_t(6) . "}"; - $allow[] = $this->_t(5) . "}"; - $allow[] = $this->_t(4) . "}"; - $allow[] = $this->_t(4) . "return false;"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder['global'][$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit']] - )) - { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Since there is no permission, revert to the component permissions."; - $allow[] = $this->_t(2) . "return \$user->authorise('" - . $core['core.edit'] . "', \$this->option);"; - } - else - { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " Since there is no permission, revert to the component permissions."; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "return parent::allowEdit(\$data, \$key);"; } } @@ -19709,369 +18370,280 @@ class Interpretation extends Fields public function setJmodelAdminGetForm($nameSingleCode, $nameListCode) { // set component name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; // allways load these $getForm = array(); - $getForm[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if xpath was set in options"; - $getForm[] = $this->_t(2) . "\$xpath = false;"; - $getForm[] = $this->_t(2) . "if (isset(\$options['xpath']))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "\$xpath = \$options['xpath'];"; - $getForm[] = $this->_t(3) . "unset(\$options['xpath']);"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "\$xpath = false;"; + $getForm[] = Indent::_(2) . "if (isset(\$options['xpath']))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$xpath = \$options['xpath'];"; + $getForm[] = Indent::_(3) . "unset(\$options['xpath']);"; + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " check if clear form was set in options"; - $getForm[] = $this->_t(2) . "\$clear = false;"; - $getForm[] = $this->_t(2) . "if (isset(\$options['clear']))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "\$clear = \$options['clear'];"; - $getForm[] = $this->_t(3) . "unset(\$options['clear']);"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "\$clear = false;"; + $getForm[] = Indent::_(2) . "if (isset(\$options['clear']))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$clear = \$options['clear'];"; + $getForm[] = Indent::_(3) . "unset(\$options['clear']);"; + $getForm[] = Indent::_(2) . "}"; + $getForm[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Get the form."; - $getForm[] = $this->_t(2) . "\$form = \$this->loadForm('com_" + $getForm[] = Indent::_(2) . "\$form = \$this->loadForm('com_" . $component . "." . $nameSingleCode . "', '" . $nameSingleCode . "', \$options, \$clear, \$xpath);"; - $getForm[] = PHP_EOL . $this->_t(2) . "if (empty(\$form))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "return false;"; - $getForm[] = $this->_t(2) . "}"; + $getForm[] = PHP_EOL . Indent::_(2) . "if (empty(\$form))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "return false;"; + $getForm[] = Indent::_(2) . "}"; // load license locker - if ($this->componentData->add_license - && $this->componentData->license_type == 3 - && isset( - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'BOOLMETHOD' . $this->hhh] - )) + if (CFactory::_('Component')->get('add_license') && CFactory::_('Component')->get('license_type') == 3 + && CFactory::_('Compiler.Builder.Content.Multi')->exists($nameSingleCode . '|BOOLMETHOD')) { $getForm[] = $this->checkStatmentLicenseLocked( - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'BOOLMETHOD' . $this->hhh] + CFactory::_('Compiler.Builder.Content.Multi')->get($nameSingleCode . '|BOOLMETHOD', '') ); } - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } - if (0) //isset($this->categoryBuilder[$nameListCode]) && ArrayHelper::check($this->categoryBuilder[$nameListCode])) <-- remove category from check + if (0) //CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}")) <-- remove category from check { // check if category has another name - if ($coreLoad && isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews = $this->catOtherName[$nameListCode]['views']; - $otherView = $this->catOtherName[$nameListCode]['view']; - } - else - { - $otherViews = $nameListCode; - $otherView = $nameSingleCode; - } + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); + $otherView = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.view', $nameSingleCode); // setup the category script - $getForm[] = PHP_EOL . $this->_t(2) + $getForm[] = PHP_EOL . Indent::_(2) . "\$jinput = JFactory::getApplication()->input;"; - $getForm[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " The front end calls this model and uses a_id to avoid id clashes so we need to check for that first."; - $getForm[] = $this->_t(2) . "if (\$jinput->get('a_id'))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(2) . "if (\$jinput->get('a_id'))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$id = \$jinput->get('a_id', 0, 'INT');"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " The back end uses id so we use that the rest of the time and set it to 0 by default."; - $getForm[] = $this->_t(2) . "else"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "\$id = \$jinput->get('id', 0, 'INT');"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "else"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$id = \$jinput->get('id', 0, 'INT');"; + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Determine correct permissions to check."; - $getForm[] = $this->_t(2) . "if (\$this->getState('" + $getForm[] = Indent::_(2) . "if (\$this->getState('" . $nameSingleCode . ".id'))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "\$id = \$this->getState('" + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$id = \$this->getState('" . $nameSingleCode . ".id');"; - $getForm[] = PHP_EOL . $this->_t(3) . "\$catid = 0;"; - $getForm[] = $this->_t(3) + $getForm[] = PHP_EOL . Indent::_(3) . "\$catid = 0;"; + $getForm[] = Indent::_(3) . "if (isset(\$this->getItem(\$id)->catid))"; - $getForm[] = $this->_t(3) . "{"; - $getForm[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "{"; + $getForm[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " set category id"; - $getForm[] = $this->_t(4) + $getForm[] = Indent::_(4) . "\$catid = \$this->getItem(\$id)->catid;"; - $getForm[] = PHP_EOL . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Existing record. Can only edit in selected categories."; - $getForm[] = $this->_t(4) + $getForm[] = Indent::_(4) . "\$form->setFieldAttribute('catid', 'action', 'core.edit');"; - $getForm[] = PHP_EOL . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Existing record. Can only edit own items in selected categories."; - $getForm[] = $this->_t(4) + $getForm[] = Indent::_(4) . "\$form->setFieldAttribute('catid', 'action', 'core.edit.own');"; - $getForm[] = $this->_t(3) . "}"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "else"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "}"; + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "else"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " New record. Can only create in selected categories."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('catid', 'action', 'core.create');"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = PHP_EOL . $this->_t(2) + $getForm[] = Indent::_(2) . "}"; + $getForm[] = PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; - $getForm[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Check for existing item."; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on Edit State access controls."; // get the other view - $otherView = $this->catCodeBuilder[$nameSingleCode]['view']; + $otherView = CFactory::_('Compiler.Builder.Category.Code')->getString("{$nameSingleCode}.view", 'error'); // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder[$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.state']] - )) - { - $getForm[] = $this->_t(2) - . "if (\$id != 0 && (!\$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) - . "|| (isset(\$catid) && \$catid != 0 && !\$user->authorise('core.edit.state', 'com_" - . $component . "." . $otherView - . ".category.' . (int) \$catid))"; - $getForm[] = $this->_t(3) - . "|| (\$id == 0 && !\$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component - . "')))"; - } - else - { - $getForm[] = $this->_t(2) - . "if (\$id != 0 && (!\$user->authorise('core.edit.state', 'com_" - . $component . "." . $nameSingleCode - . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) - . "|| (isset(\$catid) && \$catid != 0 && !\$user->authorise('core.edit.state', 'com_" - . $component . "." . $otherView - . ".category.' . (int) \$catid))"; - $getForm[] = $this->_t(3) - . "|| (\$id == 0 && !\$user->authorise('core.edit.state', 'com_" - . $component . "')))"; - } - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) + . "if (\$id != 0 && (!\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') + . "', 'com_" . $component . "." + . $nameSingleCode . ".' . (int) \$id))"; + $getForm[] = Indent::_(3) + . "|| (isset(\$catid) && \$catid != 0 && !\$user->authorise('core.edit.state', 'com_" + . $component . "." . $otherView + . ".category.' . (int) \$catid))"; + $getForm[] = Indent::_(3) + . "|| (\$id == 0 && !\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') + . "', 'com_" . $component . "')))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('ordering', 'disabled', 'true');"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('published', 'disabled', 'true');"; - $getForm[] = PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Disable fields while saving."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('ordering', 'filter', 'unset');"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('published', 'filter', 'unset');"; - $getForm[] = $this->_t(2) . "}"; + $getForm[] = Indent::_(2) . "}"; } else { - $getForm[] = PHP_EOL . $this->_t(2) + $getForm[] = PHP_EOL . Indent::_(2) . "\$jinput = JFactory::getApplication()->input;"; - $getForm[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " The front end calls this model and uses a_id to avoid id clashes so we need to check for that first."; - $getForm[] = $this->_t(2) . "if (\$jinput->get('a_id'))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(2) . "if (\$jinput->get('a_id'))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$id = \$jinput->get('a_id', 0, 'INT');"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " The back end uses id so we use that the rest of the time and set it to 0 by default."; - $getForm[] = $this->_t(2) . "else"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "\$id = \$jinput->get('id', 0, 'INT');"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = PHP_EOL . $this->_t(2) + $getForm[] = Indent::_(2) . "else"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "\$id = \$jinput->get('id', 0, 'INT');"; + $getForm[] = Indent::_(2) . "}"; + $getForm[] = PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; - $getForm[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $getForm[] = PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Check for existing item."; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on Edit State access controls."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder[$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.state']] - )) - { - $getForm[] = $this->_t(2) - . "if (\$id != 0 && (!\$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) - . "|| (\$id == 0 && !\$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component - . "')))"; - } - else - { - $getForm[] = $this->_t(2) - . "if (\$id != 0 && (!\$user->authorise('core.edit.state', 'com_" - . $component . "." . $nameSingleCode - . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) - . "|| (\$id == 0 && !\$user->authorise('core.edit.state', 'com_" - . $component . "')))"; - } - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) + . "if (\$id != 0 && (!\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') . "', 'com_" . $component . "." + . $nameSingleCode . ".' . (int) \$id))"; + $getForm[] = Indent::_(3) + . "|| (\$id == 0 && !\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') . "', 'com_" . $component + . "')))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('ordering', 'disabled', 'true');"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('published', 'disabled', 'true');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('ordering', 'filter', 'unset');"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('published', 'filter', 'unset');"; - $getForm[] = $this->_t(2) . "}"; + $getForm[] = Indent::_(2) . "}"; } - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " If this is a new item insure the greated by is set."; - $getForm[] = $this->_t(2) . "if (0 == \$id)"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "if (0 == \$id)"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Set the created_by to this user"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setValue('created_by', null, \$user->id);"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on Edit Creaded By access controls."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.created_by']) - && isset($this->permissionBuilder[$core['core.edit.created_by']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.created_by']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.created_by']] - )) + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.edit.created_by')) { - $getForm[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" - . $core['core.edit.created_by'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" - . $core['core.edit.created_by'] . "', 'com_" . $component - . "')))"; + $getForm[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.created_by') + . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; + $getForm[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.created_by') + . "', 'com_" . $component . "')))"; } else { - $getForm[] = $this->_t(2) - . "if (!\$user->authorise('core.edit.created_by', 'com_" - . $component . "'))"; + $getForm[] = Indent::_(2) + . "if (!\$user->authorise('core.edit.created_by', 'com_" . $component . "'))"; } - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('created_by', 'disabled', 'true');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('created_by', 'readonly', 'true');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('created_by', 'filter', 'unset');"; - $getForm[] = $this->_t(2) . "}"; - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "}"; + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on Edit Creaded Date access controls."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.created']) - && isset($this->permissionBuilder[$core['core.edit.created']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.created']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.created']] - )) + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.edit.created')) { - $getForm[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" - . $core['core.edit.created'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" - . $core['core.edit.created'] . "', 'com_" . $component . "')))"; + $getForm[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.created') + . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; + $getForm[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.created') + . "', 'com_" . $component . "')))"; } else { - $getForm[] = $this->_t(2) + $getForm[] = Indent::_(2) . "if (!\$user->authorise('core.edit.created', 'com_" . $component . "'))"; } - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('created', 'disabled', 'true');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('created', 'filter', 'unset');"; - $getForm[] = $this->_t(2) . "}"; + $getForm[] = Indent::_(2) . "}"; // check if the item has access permissions. - if ($coreLoad && isset($core['core.edit.access']) - && isset($this->permissionBuilder[$core['core.edit.access']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.access']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.edit.access')) { - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on Edit Access 'access' controls."; - $getForm[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" - . $core['core.edit.access'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$id))"; - $getForm[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" - . $core['core.edit.access'] . "', 'com_" . $component . "')))"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.access') + . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; + $getForm[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.access') + . "', 'com_" . $component . "')))"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('access', 'disabled', 'true');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$form->setFieldAttribute('access', 'filter', 'unset');"; - $getForm[] = $this->_t(2) . "}"; + $getForm[] = Indent::_(2) . "}"; } // handel the fields permissions if (isset($this->permissionFields[$nameSingleCode]) @@ -20117,40 +18689,40 @@ class Interpretation extends Fields } } // add the redirect trick to set the field of origin - $getForm[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Only load these values if no id is found"; - $getForm[] = $this->_t(2) . "if (0 == \$id)"; - $getForm[] = $this->_t(2) . "{"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(2) . "if (0 == \$id)"; + $getForm[] = Indent::_(2) . "{"; + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Set redirected view name"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$redirectedView = \$jinput->get('ref', null, 'STRING');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Set field name (or fall back to view name)"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$redirectedField = \$jinput->get('field', \$redirectedView, 'STRING');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Set redirected view id"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$redirectedId = \$jinput->get('refid', 0, 'INT');"; - $getForm[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Set field id (or fall back to redirected view id)"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "\$redirectedValue = \$jinput->get('field_id', \$redirectedId, 'INT');"; - $getForm[] = $this->_t(3) + $getForm[] = Indent::_(3) . "if (0 != \$redirectedValue && \$redirectedField)"; - $getForm[] = $this->_t(3) . "{"; - $getForm[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $getForm[] = Indent::_(3) . "{"; + $getForm[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Now set the local-redirected field default value"; - $getForm[] = $this->_t(4) + $getForm[] = Indent::_(4) . "\$form->setValue(\$redirectedField, null, \$redirectedValue);"; - $getForm[] = $this->_t(3) . "}"; + $getForm[] = Indent::_(3) . "}"; // load custom script if found - $getForm[] = $this->_t(2) . "}" . $this->getCustomScriptBuilder( + $getForm[] = Indent::_(2) . "}" . CFactory::_('Customcode.Dispenser')->get( 'php_getform', $nameSingleCode, PHP_EOL ); // setup the default script - $getForm[] = $this->_t(2) . "return \$form;"; + $getForm[] = Indent::_(2) . "return \$form;"; return implode(PHP_EOL, $getForm); } @@ -20160,52 +18732,52 @@ class Interpretation extends Fields ) { // only for fields that can be edited - if (!ComponentbuilderHelper::fieldCheck($fieldType, 'spacer')) + if (!CFactory::_('Field.Groups')->check($fieldType, 'spacer')) { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on Edit " . StringHelper::safe($fieldName, 'W') . " access controls."; - $allow[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" + $allow[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" . $nameSingleCode . ".edit." . $fieldName . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; - $allow[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" + $allow[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" . $nameSingleCode . ".edit." . $fieldName . "', 'com_" . $component . "')))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $allow[] = $this->_t(3) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(3) . "\$form->setFieldAttribute('" . $fieldName . "', 'disabled', 'true');"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable fields for display."; - $allow[] = $this->_t(3) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(3) . "\$form->setFieldAttribute('" . $fieldName . "', 'readonly', 'true');"; if ('radio' === $fieldType || 'repeatable' === $fieldType) { - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Disable radio button for display."; - $allow[] = $this->_t(3) + $allow[] = Indent::_(3) . "\$class = \$form->getFieldAttribute('" . $fieldName . "', 'class', '');"; - $allow[] = $this->_t(3) . "\$form->setFieldAttribute('" + $allow[] = Indent::_(3) . "\$form->setFieldAttribute('" . $fieldName . "', 'class', \$class.' disabled no-click');"; } - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " If there is no value continue."; - $allow[] = $this->_t(3) . "if (!\$form->getValue('" . $fieldName + $allow[] = Indent::_(3) . "if (!\$form->getValue('" . $fieldName . "'))"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $allow[] = $this->_t(4) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(4) . "\$form->setFieldAttribute('" . $fieldName . "', 'filter', 'unset');"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $allow[] = $this->_t(4) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(4) . "\$form->setFieldAttribute('" . $fieldName . "', 'required', 'false');"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; } } @@ -20213,94 +18785,94 @@ class Interpretation extends Fields $fieldName, $fieldType, $component ) { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the from the form based on " . StringHelper::safe($fieldName, 'W') . " access controls."; - $allow[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" + $allow[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" . $nameSingleCode . ".access." . $fieldName . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; - $allow[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" + $allow[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" . $nameSingleCode . ".access." . $fieldName . "', 'com_" . $component . "')))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Remove the field"; - $allow[] = $this->_t(3) . "\$form->removeField('" . $fieldName . "');"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(3) . "\$form->removeField('" . $fieldName . "');"; + $allow[] = Indent::_(2) . "}"; } protected function setPermissionViewFields(&$allow, $nameSingleCode, $fieldName, $fieldType, $component ) { - if (ComponentbuilderHelper::fieldCheck($fieldType, 'spacer')) + if (CFactory::_('Field.Groups')->check($fieldType, 'spacer')) { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on View " . StringHelper::safe($fieldName, 'W') . " access controls."; - $allow[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" + $allow[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" . $nameSingleCode . ".view." . $fieldName . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; - $allow[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" + $allow[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" . $nameSingleCode . ".view." . $fieldName . "', 'com_" . $component . "')))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Remove the field"; - $allow[] = $this->_t(3) . "\$form->removeField('" . $fieldName + $allow[] = Indent::_(3) . "\$form->removeField('" . $fieldName . "');"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(2) . "}"; } else { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Modify the form based on View " . StringHelper::safe($fieldName, 'W') . " access controls."; - $allow[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" + $allow[] = Indent::_(2) . "if (\$id != 0 && (!\$user->authorise('" . $nameSingleCode . ".view." . $fieldName . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$id))"; - $allow[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" + $allow[] = Indent::_(3) . "|| (\$id == 0 && !\$user->authorise('" . $nameSingleCode . ".view." . $fieldName . "', 'com_" . $component . "')))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Make the field hidded."; - $allow[] = $this->_t(3) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(3) . "\$form->setFieldAttribute('" . $fieldName . "', 'type', 'hidden');"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " If there is no value continue."; - $allow[] = $this->_t(3) . "if (!(\$val = \$form->getValue('" + $allow[] = Indent::_(3) . "if (!(\$val = \$form->getValue('" . $fieldName . "')))"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $allow[] = $this->_t(4) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(4) . "\$form->setFieldAttribute('" . $fieldName . "', 'filter', 'unset');"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Disable fields while saving."; - $allow[] = $this->_t(4) . "\$form->setFieldAttribute('" . $fieldName + $allow[] = Indent::_(4) . "\$form->setFieldAttribute('" . $fieldName . "', 'required', 'false');"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Make sure"; - $allow[] = $this->_t(4) . "\$form->setValue('" . $fieldName + $allow[] = Indent::_(4) . "\$form->setValue('" . $fieldName . "', null, '');"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(3) . "elseif (" . ucfirst($component) + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(3) . "elseif (" . ucfirst((string) $component) . "Helper::checkArray(\$val))"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " We have to unset then (TODO)"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Hiddend field can not handel array value"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Even if we convert to json we get an error"; - $allow[] = $this->_t(4) . "\$form->removeField('" . $fieldName + $allow[] = Indent::_(4) . "\$form->removeField('" . $fieldName . "');"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; } } @@ -20308,52 +18880,39 @@ class Interpretation extends Fields { $allow = array(); // set component name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; // prepare custom permission script - $customAllow = $this->getCustomScriptBuilder( - 'php_allowedit', $nameSingleCode, $this->_t(2) + $customAllow = CFactory::_('Customcode.Dispenser')->get( + 'php_allowedit', $nameSingleCode, Indent::_(2) . "\$recordId = (int) isset(\$data[\$key]) ? \$data[\$key] : 0;" . PHP_EOL ); - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } // check if the item has permissions. - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder[$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit']] - ) - && in_array( - $nameSingleCode, $this->permissionBuilder[$core['core.edit']] - )) + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.edit')) { - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check specific edit permission then general edit permission."; - $allow[] = $this->_t(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "\$user = JFactory::getUser();"; // load custom permission script $allow[] = $customAllow; - $allow[] = $this->_t(2) . "return \$user->authorise('" - . $core['core.edit'] . "', 'com_" . $component . "." - . $nameSingleCode + $allow[] = Indent::_(2) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit') + . "', 'com_" . $component . "." . $nameSingleCode . ".'. ((int) isset(\$data[\$key]) ? \$data[\$key] : 0)) or \$user->authorise('" - . $core['core.edit'] . "', 'com_" . $component . "');"; + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit') + . "', 'com_" . $component . "');"; } else { - $allow[] = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check specific edit permission then general edit permission."; if (StringHelper::check($customAllow)) { - $allow[] = $this->_t(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "\$user = JFactory::getUser();"; } // load custom permission script $allow[] = $customAllow; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "return JFactory::getUser()->authorise('core.edit', 'com_" . $component . "." . $nameSingleCode . ".'. ((int) isset(\$data[\$key]) ? \$data[\$key] : 0)) or parent::allowEdit(\$data, \$key);"; @@ -20366,119 +18925,55 @@ class Interpretation extends Fields { $allow = array(); // set component name - $component = $this->componentCodeName; - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } - if (0) //isset($this->categoryBuilder[$nameListCode]) && ArrayHelper::check($this->categoryBuilder[$nameListCode])) <-- remove category from check + $component = CFactory::_('Config')->component_code_name; + if (0) //CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}")) <-- remove category from check { // check if category has another name - if ($coreLoad && isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews = $this->catOtherName[$nameListCode]['views']; - $otherView = $this->catOtherName[$nameListCode]['view']; - } - else - { - $otherViews = $nameListCode; - $otherView = $nameSingleCode; - } + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); + $otherView = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.view', $nameSingleCode); // setup the category script - $allow[] = PHP_EOL . $this->_t(2) . "if (!empty(\$record->id))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "if (\$record->published != -2)"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "return;"; - $allow[] = $this->_t(3) . "}"; - $allow[] = PHP_EOL . $this->_t(3) . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(3) + $allow[] = PHP_EOL . Indent::_(2) . "if (!empty(\$record->id))"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "if (\$record->published != -2)"; + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "return;"; + $allow[] = Indent::_(3) . "}"; + $allow[] = PHP_EOL . Indent::_(3) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(3) . "\$allow = \$user->authorise('core.delete', 'com_" . $component . "." . $otherView . ".category.' . (int) \$record->catid);"; // check if the item has permissions. - if ($coreLoad - && isset($this->permissionBuilder[$core['core.delete']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.delete']] - ) - && in_array( - $otherView, $this->permissionBuilder[$core['core.delete']] - )) - { - $allow[] = PHP_EOL . $this->_t(3) . "if (\$allow)"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) - . " The record has been set. Check the record permissions."; - $allow[] = $this->_t(4) . "return \$user->authorise('" - . $core['core.delete'] . "', 'com_" . $component . "." - . $otherView . ".' . (int) \$record->id);"; - $allow[] = $this->_t(3) . "}"; - } - else - { - $allow[] = PHP_EOL . $this->_t(3) . "if (\$allow)"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) - . " The record has been set. Check the record permissions."; - $allow[] = $this->_t(4) - . "return \$user->authorise('core.delete', 'com_" - . $component . "." . $otherView - . ".' . (int) \$record->id);"; - $allow[] = $this->_t(3) . "}"; - } - $allow[] = $this->_t(3) . "return \$allow;"; - $allow[] = $this->_t(2) . "}"; - $allow[] = $this->_t(2) . "return false;"; + $allow[] = PHP_EOL . Indent::_(3) . "if (\$allow)"; + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " The record has been set. Check the record permissions."; + $allow[] = Indent::_(4) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($otherView, 'core.delete') . "', 'com_" . $component . "." + . $otherView . ".' . (int) \$record->id);"; + $allow[] = Indent::_(3) . "}"; } else { // setup the default script - $allow[] = PHP_EOL . $this->_t(2) . "if (!empty(\$record->id))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "if (\$record->published != -2)"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "return;"; - $allow[] = $this->_t(3) . "}"; + $allow[] = PHP_EOL . Indent::_(2) . "if (!empty(\$record->id))"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "if (\$record->published != -2)"; + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "return;"; + $allow[] = Indent::_(3) . "}"; // check if the item has permissions. - if ($coreLoad - && (isset($core['core.delete']) - && isset($this->permissionBuilder[$core['core.delete']])) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.delete']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.delete']] - )) - { - $allow[] = PHP_EOL . $this->_t(3) - . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) - . " The record has been set. Check the record permissions."; - $allow[] = $this->_t(3) . "return \$user->authorise('" - . $core['core.delete'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$record->id);"; - } - else - { - $allow[] = PHP_EOL . $this->_t(3) - . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) - . " The record has been set. Check the record permissions."; - $allow[] = $this->_t(3) - . "return \$user->authorise('core.delete', 'com_" - . $component . "." . $nameSingleCode - . ".' . (int) \$record->id);"; - } - $allow[] = $this->_t(2) . "}"; - $allow[] = $this->_t(2) . "return false;"; + $allow[] = PHP_EOL . Indent::_(3) + . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " The record has been set. Check the record permissions."; + $allow[] = Indent::_(3) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.delete') . "', 'com_" . $component . "." + . $nameSingleCode . ".' . (int) \$record->id);"; + $allow[] = Indent::_(2) . "}"; + $allow[] = Indent::_(2) . "return false;"; } return implode(PHP_EOL, $allow); @@ -20490,163 +18985,96 @@ class Interpretation extends Fields { $allow = array(); // set component name - $component = $this->componentCodeName; - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } - if (0) // isset($this->categoryBuilder[$nameListCode]) && ArrayHelper::check($this->categoryBuilder[$nameListCode])) <-- remove category from check + $component = CFactory::_('Config')->component_code_name; + if (0) //CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}")) <-- remove category from check { // check if category has another name - if (isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews = $this->catOtherName[$nameListCode]['views']; - $otherView = $this->catOtherName[$nameListCode]['view']; - } - else - { - $otherViews = $nameListCode; - $otherView = $nameSingleCode; - } - $allow[] = PHP_EOL . $this->_t(2) . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(2) + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); + $otherView = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.view', $nameSingleCode); + + $allow[] = PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "\$recordId = (!empty(\$record->id)) ? \$record->id : 0;"; - $allow[] = PHP_EOL . $this->_t(2) . "if (\$recordId)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "if (\$recordId)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " The record has been set. Check the record permissions."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder[$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.state']] - )) - { - $allow[] = $this->_t(3) . "\$permission = \$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$recordId);"; - } - else - { - $allow[] = $this->_t(3) - . "\$permission = \$user->authorise('core.edit.state', 'com_" - . $component . "." . $nameSingleCode - . ".' . (int) \$recordId);"; - } - $allow[] = $this->_t(3) + $allow[] = Indent::_(3) . "\$permission = \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') . "', 'com_" . $component . "." + . $nameSingleCode . ".' . (int) \$recordId);"; + $allow[] = Indent::_(3) . "if (!\$permission && !is_null(\$permission))"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "return false;"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "return false;"; + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; // setup the category script - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check against the category."; - $allow[] = $this->_t(2) . "if (!empty(\$record->catid))"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) + $allow[] = Indent::_(2) . "if (!empty(\$record->catid))"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "\$catpermission = \$user->authorise('core.edit.state', 'com_" . $component . "." . $otherView . ".category.' . (int) \$record->catid);"; - $allow[] = $this->_t(3) + $allow[] = Indent::_(3) . "if (!\$catpermission && !is_null(\$catpermission))"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "return false;"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder[$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.state']] - )) + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "return false;"; + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.edit.state')) { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(2) . "return \$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component - . "');"; + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(2) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') + . "', 'com_" . $component . "');"; } else { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(2) . "return parent::canEditState(\$record);"; } } else { // setup the default script - $allow[] = PHP_EOL . $this->_t(2) . "\$user = JFactory::getUser();"; - $allow[] = $this->_t(2) + $allow[] = PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; + $allow[] = Indent::_(2) . "\$recordId = (!empty(\$record->id)) ? \$record->id : 0;"; - $allow[] = PHP_EOL . $this->_t(2) . "if (\$recordId)"; - $allow[] = $this->_t(2) . "{"; - $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) + $allow[] = PHP_EOL . Indent::_(2) . "if (\$recordId)"; + $allow[] = Indent::_(2) . "{"; + $allow[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " The record has been set. Check the record permissions."; // check if the item has permissions. - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder[$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.edit.state']] - )) - { - $allow[] = $this->_t(3) . "\$permission = \$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component . "." - . $nameSingleCode . ".' . (int) \$recordId);"; - } - else - { - $allow[] = $this->_t(3) - . "\$permission = \$user->authorise('core.edit.state', 'com_" - . $component . "." . $nameSingleCode - . ".' . (int) \$recordId);"; - } - $allow[] = $this->_t(3) + $allow[] = Indent::_(3) . "\$permission = \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.edit.state') + . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$recordId);"; + $allow[] = Indent::_(3) . "if (!\$permission && !is_null(\$permission))"; - $allow[] = $this->_t(3) . "{"; - $allow[] = $this->_t(4) . "return false;"; - $allow[] = $this->_t(3) . "}"; - $allow[] = $this->_t(2) . "}"; - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder['global'][$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit.state']] - )) + $allow[] = Indent::_(3) . "{"; + $allow[] = Indent::_(4) . "return false;"; + $allow[] = Indent::_(3) . "}"; + $allow[] = Indent::_(2) . "}"; + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.edit.state')) { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(2) . "return \$user->authorise('" - . $core['core.edit.state'] . "', 'com_" . $component + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(2) . "return \$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit.state') . "', 'com_" . $component . "');"; } else { - $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) - . " In the absense of better information, revert to the component permissions."; - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " In the absence of better information, revert to the component permissions."; + $allow[] = Indent::_(2) . "return parent::canEditState(\$record);"; } } @@ -20658,109 +19086,32 @@ class Interpretation extends Fields { $allow = array(); // set component name - $component = $this->componentCodeName; - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } + $component = CFactory::_('Config')->component_code_name; // check if the item has permissions for edit. - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder['global'][$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit']] - )) - { - $allow[] = PHP_EOL . $this->_t(2) - . "\$this->canEdit = \$this->canDo->get('" . $core['core.edit'] - . "');"; - } - else - { - $allow[] = PHP_EOL . $this->_t(2) - . "\$this->canEdit = \$this->canDo->get('core.edit');"; - } + $allow[] = PHP_EOL . Indent::_(2) + . "\$this->canEdit = \$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit') + . "');"; // check if the item has permissions for edit state. - if ($coreLoad && isset($core['core.edit.state']) - && isset($this->permissionBuilder['global'][$core['core.edit.state']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit.state']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit.state']] - )) - { - $allow[] = $this->_t(2) . "\$this->canState = \$this->canDo->get('" - . $core['core.edit.state'] . "');"; - } - else - { - $allow[] = $this->_t(2) - . "\$this->canState = \$this->canDo->get('core.edit.state');"; - } + $allow[] = Indent::_(2) . "\$this->canState = \$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit.state') + . "');"; // check if the item has permissions for create. - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) - { - $allow[] = $this->_t(2) . "\$this->canCreate = \$this->canDo->get('" - . $core['core.create'] . "');"; - } - else - { - $allow[] = $this->_t(2) - . "\$this->canCreate = \$this->canDo->get('core.create');"; - } + $allow[] = Indent::_(2) . "\$this->canCreate = \$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') . "');"; // check if the item has permissions for delete. - if ($coreLoad && isset($core['core.delete']) - && isset($this->permissionBuilder['global'][$core['core.delete']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.delete']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.delete']] - )) - { - $allow[] = $this->_t(2) . "\$this->canDelete = \$this->canDo->get('" - . $core['core.delete'] . "');"; - } - else - { - $allow[] = $this->_t(2) - . "\$this->canDelete = \$this->canDo->get('core.delete');"; - } + $allow[] = Indent::_(2) . "\$this->canDelete = \$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.delete') . "');"; // check if the item has permissions for batch. - if ($coreLoad && isset($core['core.batch']) - && isset($this->permissionBuilder['global']['global'][$core['core.batch']]) - && ArrayHelper::check( - $this->permissionBuilder['global']['global'][$core['core.batch']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global']['global'][$core['core.delete']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.batch')) { - $allow[] = $this->_t(2) . "\$this->canBatch = (\$this->canDo->get('" - . $core['core.batch'] + $allow[] = Indent::_(2) . "\$this->canBatch = (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.batch') . "') && \$this->canDo->get('core.batch'));"; } else { - $allow[] = $this->_t(2) + $allow[] = Indent::_(2) . "\$this->canBatch = \$this->canDo->get('core.batch');"; } @@ -20773,38 +19124,38 @@ class Interpretation extends Fields if ($view != 'component') { // set component name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; // set label $label = 'Permissions in relation to this ' . $view; // set the access fieldset - $access = ""; - $access .= PHP_EOL . $this->_t(1) + $access .= PHP_EOL . Indent::_(1) . '
'; - $access .= PHP_EOL . $this->_t(2) . ""; - $access .= PHP_EOL . $this->_t(2) . '_t(3) . 'name="asset_id"'; - $access .= PHP_EOL . $this->_t(3) . 'type="hidden"'; - $access .= PHP_EOL . $this->_t(3) . 'filter="unset"'; - $access .= PHP_EOL . $this->_t(2) . '/>'; - $access .= PHP_EOL . $this->_t(2) . ""; - $access .= PHP_EOL . $this->_t(2) . '_t(3) . 'name="rules"'; - $access .= PHP_EOL . $this->_t(3) . 'type="rules"'; - $access .= PHP_EOL . $this->_t(3) . 'label="' . $label . '"'; - $access .= PHP_EOL . $this->_t(3) . 'translate_label="false"'; - $access .= PHP_EOL . $this->_t(3) . 'filter="rules"'; - $access .= PHP_EOL . $this->_t(3) . 'validate="rules"'; - $access .= PHP_EOL . $this->_t(3) . 'class="inputbox"'; - $access .= PHP_EOL . $this->_t(3) . 'component="com_' . $component + $access .= PHP_EOL . Indent::_(2) . '_t(3) . 'section="' . $view . '"'; - $access .= PHP_EOL . $this->_t(2) . '/>'; - $access .= PHP_EOL . $this->_t(1) . '
'; + $access .= PHP_EOL . Indent::_(3) . 'section="' . $view . '"'; + $access .= PHP_EOL . Indent::_(2) . '/>'; + $access .= PHP_EOL . Indent::_(1) . ''; } // return access field set @@ -20824,30 +19175,24 @@ class Interpretation extends Fields { // keep track of all fields already added $donelist = array('id' => true, 'search' => true, - 'published' => true, 'access' => true, - 'created_by' => true, 'modified_by' => true); + 'published' => true, 'access' => true, + 'created_by' => true, 'modified_by' => true); // default filter fields $fields = "'a.id','id'"; - $fields .= "," . PHP_EOL . $this->_t(4) . "'a.published','published'"; - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - )) + $fields .= "," . PHP_EOL . Indent::_(4) . "'a.published','published'"; + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode)) { - $fields .= "," . PHP_EOL . $this->_t(4) . "'a.access','access'"; + $fields .= "," . PHP_EOL . Indent::_(4) . "'a.access','access'"; } - $fields .= "," . PHP_EOL . $this->_t(4) . "'a.ordering','ordering'"; - $fields .= "," . PHP_EOL . $this->_t(4) . "'a.created_by','created_by'"; - $fields .= "," . PHP_EOL . $this->_t(4) + $fields .= "," . PHP_EOL . Indent::_(4) . "'a.ordering','ordering'"; + $fields .= "," . PHP_EOL . Indent::_(4) . "'a.created_by','created_by'"; + $fields .= "," . PHP_EOL . Indent::_(4) . "'a.modified_by','modified_by'"; // add the rest of the set filters - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { if (!isset($donelist[$filter['code']])) { @@ -20859,16 +19204,13 @@ class Interpretation extends Fields } } // add the rest of the set filters - if (isset($this->sortBuilder[$nameListCode]) - && ArrayHelper::check( - $this->sortBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Sort')->exists($nameListCode)) { - foreach ($this->sortBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Sort')->get($nameListCode) as $filter) { if (!isset($donelist[$filter['code']])) { - $fields .= $this->getFilterFieldCode( + $fields .= $this->getFilterFieldCode( $filter ); $donelist[$filter['code']] = true; @@ -20892,13 +19234,13 @@ class Interpretation extends Fields // add the category stuff (may still remove these) TODO if ($filter['type'] === 'category') { - $field = "," . PHP_EOL . $this->_t(4) + $field = "," . PHP_EOL . Indent::_(4) . "'c.title','category_title'"; - $field .= "," . PHP_EOL . $this->_t(4) + $field .= "," . PHP_EOL . Indent::_(4) . "'c.id', 'category_id'"; if ($filter['code'] != 'category') { - $field .= "," . PHP_EOL . $this->_t(4) . "'a." + $field .= "," . PHP_EOL . Indent::_(4) . "'a." . $filter['code'] . "','" . $filter['code'] . "'"; } @@ -20918,14 +19260,14 @@ class Interpretation extends Fields $filter['custom']['text'] )) { - $field = "," . PHP_EOL . $this->_t(4) . "'" + $field = "," . PHP_EOL . Indent::_(4) . "'" . $filter['custom']['db'] . "." . $filter['custom']['text'] . "','" . $filter['code'] . "'"; } else { - $field = "," . PHP_EOL . $this->_t(4) . "'a." + $field = "," . PHP_EOL . Indent::_(4) . "'a." . $filter['code'] . "','" . $filter['code'] . "'"; } @@ -20946,35 +19288,31 @@ class Interpretation extends Fields public function setStoredId(&$nameSingleCode, &$nameListCode) { // set component name - $Component = ucwords($this->componentCodeName); + $Component = ucwords((string) CFactory::_('Config')->component_code_name); // keep track of all fields already added $donelist = array('id' => true, 'search' => true, - 'published' => true, 'access' => true, - 'created_by' => true, 'modified_by' => true); + 'published' => true, 'access' => true, + 'created_by' => true, 'modified_by' => true); // set the defaults first - $stored = "//" . $this->setLine(__LINE__) . " Compile the store id."; - $stored .= PHP_EOL . $this->_t(2) + $stored = "//" . Line::_(__Line__, __Class__) . " Compile the store id."; + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.id');"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.search');"; // add this if not already added - if (!isset($this->fieldsNames[$nameSingleCode]['published'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.published')) { - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.published');"; } // add if view calls for it, and not already added - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - ) - && !isset($this->fieldsNames[$nameSingleCode]['access'])) + if (CFactory::_('Compiler.Builder.Access.Switch')->exists($nameSingleCode) + && !CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.access')) { // the side bar option is single - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 1) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 1) { - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.access');"; } else @@ -20984,31 +19322,28 @@ class Interpretation extends Fields $stored .= $this->getStoredIdCodeMulti('access', $Component); } } - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.ordering');"; // add this if not already added - if (!isset($this->fieldsNames[$nameSingleCode]['created_by'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.created_by')) { - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.created_by');"; } // add this if not already added - if (!isset($this->fieldsNames[$nameSingleCode]['modified_by'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.modified_by')) { - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.modified_by');"; } // add the rest of the set filters - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { if (!isset($donelist[$filter['code']])) { - $stored .= $this->getStoredIdCode( + $stored .= $this->getStoredIdCode( $filter, $nameListCode, $Component ); $donelist[$filter['code']] = true; @@ -21016,16 +19351,13 @@ class Interpretation extends Fields } } // add the rest of the set filters - if (isset($this->sortBuilder[$nameListCode]) - && ArrayHelper::check( - $this->sortBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Sort')->exists($nameListCode)) { - foreach ($this->sortBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Sort')->get($nameListCode) as $filter) { if (!isset($donelist[$filter['code']])) { - $stored .= $this->getStoredIdCode( + $stored .= $this->getStoredIdCode( $filter, $nameListCode, $Component ); $donelist[$filter['code']] = true; @@ -21051,16 +19383,15 @@ class Interpretation extends Fields if ($filter['type'] === 'category') { // the side bar option is single (1 = sidebar) - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 1) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 1) { - $stored = PHP_EOL . $this->_t(2) + $stored = PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.category');"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter.category_id');"; if ($filter['code'] != 'category') { - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter." . $filter['code'] . "');"; } @@ -21083,8 +19414,7 @@ class Interpretation extends Fields { // check if this is the topbar filter, and multi option (2 = topbar) if (isset($filter['multi']) && $filter['multi'] == 2 - && isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 2) + && CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 2) { // top bar selection can result in // an array due to multi selection @@ -21094,7 +19424,7 @@ class Interpretation extends Fields } else { - $stored = PHP_EOL . $this->_t(2) + $stored = PHP_EOL . Indent::_(2) . "\$id .= ':' . \$this->getState('filter." . $filter['code'] . "');"; } @@ -21116,33 +19446,33 @@ class Interpretation extends Fields { // top bar selection can result in // an array due to multi selection - $stored = PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $stored = PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Check if the value is an array"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "\$_" . $key . " = \$this->getState('filter." . $key . "');"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "if (" . $Component . "Helper::checkArray(\$_" . $key . "))"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "{"; - $stored .= PHP_EOL . $this->_t(3) + $stored .= PHP_EOL . Indent::_(3) . "\$id .= ':' . implode(':', \$_" . $key . ");"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "}"; - $stored .= PHP_EOL . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $stored .= PHP_EOL . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Check if this is only an number or string"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "elseif (is_numeric(\$_" . $key . ")"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . " || " . $Component . "Helper::checkString(\$_" . $key . "))"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "{"; - $stored .= PHP_EOL . $this->_t(3) + $stored .= PHP_EOL . Indent::_(3) . "\$id .= ':' . \$_" . $key . ";"; - $stored .= PHP_EOL . $this->_t(2) + $stored .= PHP_EOL . Indent::_(2) . "}"; return $stored; @@ -21152,13 +19482,6 @@ class Interpretation extends Fields { // set view name $nameSingleCode = $view['settings']->name_single_code; - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } // check type if ($view['settings']->type == 2) { @@ -21168,18 +19491,18 @@ class Interpretation extends Fields $view['settings']->name_single . ' readonly', 'U' ); // load to lang - $this->setLangContent( - $this->lang, $viewNameLang_readonly, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $viewNameLang_readonly, $view['settings']->name_single . ' :: Readonly' ); // build toolbar $toolBar - = "JFactory::getApplication()->input->set('hidemainmenu', true);"; - $toolBar .= PHP_EOL . $this->_t(2) . "JToolBarHelper::title(JText:" + = "JFactory::getApplication()->input->set('hidemainmenu', true);"; + $toolBar .= PHP_EOL . Indent::_(2) . "JToolBarHelper::title(JText:" . ":_('" . $viewNameLang_readonly . "'), '" . $nameSingleCode . "');"; - $toolBar .= PHP_EOL . $this->_t(2) . "JToolBarHelper::cancel('" + $toolBar .= PHP_EOL . Indent::_(2) . "JToolBarHelper::cancel('" . $nameSingleCode . ".cancel', 'JTOOLBAR_CLOSE');"; } else @@ -21194,279 +19517,169 @@ class Interpretation extends Fields $view['settings']->name_single . ' Edit', 'U' ); // load to lang - $this->setLangContent( - $this->lang, $viewNameLang_new, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $viewNameLang_new, 'A New ' . $view['settings']->name_single ); - $this->setLangContent( - $this->lang, $viewNameLang_edit, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $viewNameLang_edit, 'Editing the ' . $view['settings']->name_single ); // build toolbar $toolBar - = "JFactory::getApplication()->input->set('hidemainmenu', true);"; - $toolBar .= PHP_EOL . $this->_t(2) + = "JFactory::getApplication()->input->set('hidemainmenu', true);"; + $toolBar .= PHP_EOL . Indent::_(2) . "\$user = JFactory::getUser();"; - $toolBar .= PHP_EOL . $this->_t(2) . "\$userId = \$user->id;"; - $toolBar .= PHP_EOL . $this->_t(2) + $toolBar .= PHP_EOL . Indent::_(2) . "\$userId = \$user->id;"; + $toolBar .= PHP_EOL . Indent::_(2) . "\$isNew = \$this->item->id == 0;"; - $toolBar .= PHP_EOL . PHP_EOL . $this->_t(2) + $toolBar .= PHP_EOL . PHP_EOL . Indent::_(2) . "JToolbarHelper::title( JText:" . ":_(\$isNew ? '" . $viewNameLang_new . "' : '" . $viewNameLang_edit . "'), 'pencil-2 article-add');"; - $toolBar .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Built the actions for new and existing records."; - $toolBar .= PHP_EOL . $this->_t(2) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkString(\$this->referral))"; - $toolBar .= PHP_EOL . $this->_t(2) . "{"; - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) - { - $toolBar .= PHP_EOL . $this->_t(3) . "if (\$this->canDo->get('" - . $core['core.create'] . "') && \$isNew)"; - } - else - { - $toolBar .= PHP_EOL . $this->_t(3) - . "if (\$this->canDo->get('core.create') && \$isNew)"; - } - $toolBar .= PHP_EOL . $this->_t(3) . "{"; - $toolBar .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(2) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkString(\$this->referral))"; + $toolBar .= PHP_EOL . Indent::_(2) . "{"; + $toolBar .= PHP_EOL . Indent::_(3) . "if (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') . "') && \$isNew)"; + $toolBar .= PHP_EOL . Indent::_(3) . "{"; + $toolBar .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " We can create the record."; - $toolBar .= PHP_EOL . $this->_t(4) . "JToolBarHelper::save('" + $toolBar .= PHP_EOL . Indent::_(4) . "JToolBarHelper::save('" . $nameSingleCode . ".save', 'JTOOLBAR_SAVE');"; - $toolBar .= PHP_EOL . $this->_t(3) . "}"; - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder['global'][$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit']] - )) - { - $toolBar .= PHP_EOL . $this->_t(3) - . "elseif (\$this->canDo->get('" . $core['core.edit'] - . "'))"; - } - else - { - $toolBar .= PHP_EOL . $this->_t(3) - . "elseif (\$this->canDo->get('core.edit'))"; - } - $toolBar .= PHP_EOL . $this->_t(3) . "{"; - $toolBar .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(3) . "}"; + $toolBar .= PHP_EOL . Indent::_(3) + . "elseif (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit') + . "'))"; + $toolBar .= PHP_EOL . Indent::_(3) . "{"; + $toolBar .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " We can save the record."; - $toolBar .= PHP_EOL . $this->_t(4) . "JToolBarHelper::save('" + $toolBar .= PHP_EOL . Indent::_(4) . "JToolBarHelper::save('" . $nameSingleCode . ".save', 'JTOOLBAR_SAVE');"; - $toolBar .= PHP_EOL . $this->_t(3) . "}"; - $toolBar .= PHP_EOL . $this->_t(3) . "if (\$isNew)"; - $toolBar .= PHP_EOL . $this->_t(3) . "{"; - $toolBar .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(3) . "}"; + $toolBar .= PHP_EOL . Indent::_(3) . "if (\$isNew)"; + $toolBar .= PHP_EOL . Indent::_(3) . "{"; + $toolBar .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Do not creat but cancel."; - $toolBar .= PHP_EOL . $this->_t(4) . "JToolBarHelper::cancel('" + $toolBar .= PHP_EOL . Indent::_(4) . "JToolBarHelper::cancel('" . $nameSingleCode . ".cancel', 'JTOOLBAR_CANCEL');"; - $toolBar .= PHP_EOL . $this->_t(3) . "}"; - $toolBar .= PHP_EOL . $this->_t(3) . "else"; - $toolBar .= PHP_EOL . $this->_t(3) . "{"; - $toolBar .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(3) . "}"; + $toolBar .= PHP_EOL . Indent::_(3) . "else"; + $toolBar .= PHP_EOL . Indent::_(3) . "{"; + $toolBar .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " We can close it."; - $toolBar .= PHP_EOL . $this->_t(4) . "JToolBarHelper::cancel('" + $toolBar .= PHP_EOL . Indent::_(4) . "JToolBarHelper::cancel('" . $nameSingleCode . ".cancel', 'JTOOLBAR_CLOSE');"; - $toolBar .= PHP_EOL . $this->_t(3) . "}"; - $toolBar .= PHP_EOL . $this->_t(2) . "}"; - $toolBar .= PHP_EOL . $this->_t(2) . "else"; - $toolBar .= PHP_EOL . $this->_t(2) . "{"; - $toolBar .= PHP_EOL . $this->_t(3) . "if (\$isNew)"; - $toolBar .= PHP_EOL . $this->_t(3) . "{"; - $toolBar .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(3) . "}"; + $toolBar .= PHP_EOL . Indent::_(2) . "}"; + $toolBar .= PHP_EOL . Indent::_(2) . "else"; + $toolBar .= PHP_EOL . Indent::_(2) . "{"; + $toolBar .= PHP_EOL . Indent::_(3) . "if (\$isNew)"; + $toolBar .= PHP_EOL . Indent::_(3) . "{"; + $toolBar .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " For new records, check the create permission."; - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) - { - $toolBar .= PHP_EOL . $this->_t(4) . "if (\$this->canDo->get('" - . $core['core.create'] . "'))"; - } - else - { - $toolBar .= PHP_EOL . $this->_t(4) - . "if (\$this->canDo->get('core.create'))"; - } - $toolBar .= PHP_EOL . $this->_t(4) . "{"; - $toolBar .= PHP_EOL . $this->_t(5) . "JToolBarHelper::apply('" + $toolBar .= PHP_EOL . Indent::_(4) . "if (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') . "'))"; + $toolBar .= PHP_EOL . Indent::_(4) . "{"; + $toolBar .= PHP_EOL . Indent::_(5) . "JToolBarHelper::apply('" . $nameSingleCode . ".apply', 'JTOOLBAR_APPLY');"; - $toolBar .= PHP_EOL . $this->_t(5) . "JToolBarHelper::save('" + $toolBar .= PHP_EOL . Indent::_(5) . "JToolBarHelper::save('" . $nameSingleCode . ".save', 'JTOOLBAR_SAVE');"; - $toolBar .= PHP_EOL . $this->_t(5) . "JToolBarHelper::custom('" + $toolBar .= PHP_EOL . Indent::_(5) . "JToolBarHelper::custom('" . $nameSingleCode . ".save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false);"; - $toolBar .= PHP_EOL . $this->_t(4) . "};"; - $toolBar .= PHP_EOL . $this->_t(4) . "JToolBarHelper::cancel('" + $toolBar .= PHP_EOL . Indent::_(4) . "};"; + $toolBar .= PHP_EOL . Indent::_(4) . "JToolBarHelper::cancel('" . $nameSingleCode . ".cancel', 'JTOOLBAR_CANCEL');"; - $toolBar .= PHP_EOL . $this->_t(3) . "}"; - $toolBar .= PHP_EOL . $this->_t(3) . "else"; - $toolBar .= PHP_EOL . $this->_t(3) . "{"; - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder['global'][$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit']] - )) - { - $toolBar .= PHP_EOL . $this->_t(4) . "if (\$this->canDo->get('" - . $core['core.edit'] . "'))"; - } - else - { - $toolBar .= PHP_EOL . $this->_t(4) - . "if (\$this->canDo->get('core.edit'))"; - } - $toolBar .= PHP_EOL . $this->_t(4) . "{"; - $toolBar .= PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(3) . "}"; + $toolBar .= PHP_EOL . Indent::_(3) . "else"; + $toolBar .= PHP_EOL . Indent::_(3) . "{"; + $toolBar .= PHP_EOL . Indent::_(4) . "if (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit') . "'))"; + $toolBar .= PHP_EOL . Indent::_(4) . "{"; + $toolBar .= PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " We can save the new record"; - $toolBar .= PHP_EOL . $this->_t(5) . "JToolBarHelper::apply('" + $toolBar .= PHP_EOL . Indent::_(5) . "JToolBarHelper::apply('" . $nameSingleCode . ".apply', 'JTOOLBAR_APPLY');"; - $toolBar .= PHP_EOL . $this->_t(5) . "JToolBarHelper::save('" + $toolBar .= PHP_EOL . Indent::_(5) . "JToolBarHelper::save('" . $nameSingleCode . ".save', 'JTOOLBAR_SAVE');"; - $toolBar .= PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " We can save this record, but check the create permission to see"; - $toolBar .= PHP_EOL . $this->_t(5) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(5) . "//" . Line::_(__Line__, __Class__) . " if we can return to make a new one."; - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) - { - $toolBar .= PHP_EOL . $this->_t(5) . "if (\$this->canDo->get('" - . $core['core.create'] . "'))"; - } - else - { - $toolBar .= PHP_EOL . $this->_t(5) - . "if (\$this->canDo->get('core.create'))"; - } - $toolBar .= PHP_EOL . $this->_t(5) . "{"; - $toolBar .= PHP_EOL . $this->_t(6) . "JToolBarHelper::custom('" + $toolBar .= PHP_EOL . Indent::_(5) . "if (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') . "'))"; + $toolBar .= PHP_EOL . Indent::_(5) . "{"; + $toolBar .= PHP_EOL . Indent::_(6) . "JToolBarHelper::custom('" . $nameSingleCode . ".save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false);"; - $toolBar .= PHP_EOL . $this->_t(5) . "}"; - $toolBar .= PHP_EOL . $this->_t(4) . "}"; - if ($coreLoad && isset($core['core.edit']) - && isset($this->permissionBuilder['global'][$core['core.edit']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.edit']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.edit']] - )) + $toolBar .= PHP_EOL . Indent::_(5) . "}"; + $toolBar .= PHP_EOL . Indent::_(4) . "}"; + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.edit')) { - if ($coreLoad && isset($this->historyBuilder[$nameSingleCode]) - && StringHelper::check( - $this->historyBuilder[$nameSingleCode] - )) + if (CFactory::_('Compiler.Builder.History')->exists($nameSingleCode)) { - $toolBar .= PHP_EOL . $this->_t(4) + $toolBar .= PHP_EOL . Indent::_(4) . "\$canVersion = (\$this->canDo->get('core.version') && \$this->canDo->get('" - . $core['core.version'] . "'));"; - $toolBar .= PHP_EOL . $this->_t(4) + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.version') + . "'));"; + $toolBar .= PHP_EOL . Indent::_(4) . "if (\$this->state->params->get('save_history', 1) && \$this->canDo->get('" - . $core['core.edit'] . "') && \$canVersion)"; - $toolBar .= PHP_EOL . $this->_t(4) . "{"; - $toolBar .= PHP_EOL . $this->_t(5) + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.edit') + . "') && \$canVersion)"; + $toolBar .= PHP_EOL . Indent::_(4) . "{"; + $toolBar .= PHP_EOL . Indent::_(5) . "JToolbarHelper::versions('com_" - . $this->componentCodeName . "." . $nameSingleCode + . CFactory::_('Config')->component_code_name . "." . $nameSingleCode . "', \$this->item->id);"; - $toolBar .= PHP_EOL . $this->_t(4) . "}"; + $toolBar .= PHP_EOL . Indent::_(4) . "}"; } } else { - if ($coreLoad && isset($this->historyBuilder[$nameSingleCode]) - && StringHelper::check( - $this->historyBuilder[$nameSingleCode] - )) + if (CFactory::_('Compiler.Builder.History')->exists($nameSingleCode)) { - $toolBar .= PHP_EOL . $this->_t(4) + $toolBar .= PHP_EOL . Indent::_(4) . "\$canVersion = (\$this->canDo->get('core.version') && \$this->canDo->get('" - . $core['core.version'] . "'));"; - $toolBar .= PHP_EOL . $this->_t(4) + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.version') . "'));"; + $toolBar .= PHP_EOL . Indent::_(4) . "if (\$this->state->params->get('save_history', 1) && \$this->canDo->get('core.edit') && \$canVersion)"; - $toolBar .= PHP_EOL . $this->_t(4) . "{"; - $toolBar .= PHP_EOL . $this->_t(5) + $toolBar .= PHP_EOL . Indent::_(4) . "{"; + $toolBar .= PHP_EOL . Indent::_(5) . "JToolbarHelper::versions('com_" - . $this->componentCodeName . "." . $nameSingleCode + . CFactory::_('Config')->component_code_name . "." . $nameSingleCode . "', \$this->item->id);"; - $toolBar .= PHP_EOL . $this->_t(4) . "}"; + $toolBar .= PHP_EOL . Indent::_(4) . "}"; } } - if ($coreLoad && isset($core['core.create']) - && isset($this->permissionBuilder['global'][$core['core.create']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.create']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.create']] - )) - { - $toolBar .= PHP_EOL . $this->_t(4) . "if (\$this->canDo->get('" - . $core['core.create'] . "'))"; - } - else - { - $toolBar .= PHP_EOL . $this->_t(4) - . "if (\$this->canDo->get('core.create'))"; - } - $toolBar .= PHP_EOL . $this->_t(4) . "{"; - $toolBar .= PHP_EOL . $this->_t(5) . "JToolBarHelper::custom('" + $toolBar .= PHP_EOL . Indent::_(4) . "if (\$this->canDo->get('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.create') . "'))"; + $toolBar .= PHP_EOL . Indent::_(4) . "{"; + $toolBar .= PHP_EOL . Indent::_(5) . "JToolBarHelper::custom('" . $nameSingleCode . ".save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false);"; - $toolBar .= PHP_EOL . $this->_t(4) . "}"; + $toolBar .= PHP_EOL . Indent::_(4) . "}"; // add custom buttons - $toolBar .= $this->setCustomButtons($view, 2, $this->_t(2)); - $toolBar .= PHP_EOL . $this->_t(4) . "JToolBarHelper::cancel('" + $toolBar .= $this->setCustomButtons($view, 2, Indent::_(2)); + $toolBar .= PHP_EOL . Indent::_(4) . "JToolBarHelper::cancel('" . $nameSingleCode . ".cancel', 'JTOOLBAR_CLOSE');"; - $toolBar .= PHP_EOL . $this->_t(3) . "}"; - $toolBar .= PHP_EOL . $this->_t(2) . "}"; - $toolBar .= PHP_EOL . $this->_t(2) . "JToolbarHelper::divider();"; - $toolBar .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $toolBar .= PHP_EOL . Indent::_(3) . "}"; + $toolBar .= PHP_EOL . Indent::_(2) . "}"; + $toolBar .= PHP_EOL . Indent::_(2) . "JToolbarHelper::divider();"; + $toolBar .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " set help url for this view if found"; - $toolBar .= PHP_EOL . $this->_t(2) . "\$this->help_url = " - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::getHelpUrl('" . $nameSingleCode + $toolBar .= PHP_EOL . Indent::_(2) . "\$this->help_url = " + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::getHelpUrl('" . $nameSingleCode . "');"; - $toolBar .= PHP_EOL . $this->_t(2) . "if (" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkString(\$this->help_url))"; - $toolBar .= PHP_EOL . $this->_t(2) . "{"; - $toolBar .= PHP_EOL . $this->_t(3) . "JToolbarHelper::help('" + $toolBar .= PHP_EOL . Indent::_(2) . "if (" + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkString(\$this->help_url))"; + $toolBar .= PHP_EOL . Indent::_(2) . "{"; + $toolBar .= PHP_EOL . Indent::_(3) . "JToolbarHelper::help('" . $this->langPrefix . "_HELP_MANAGER', false, \$this->help_url);"; - $toolBar .= PHP_EOL . $this->_t(2) . "}"; + $toolBar .= PHP_EOL . Indent::_(2) . "}"; } return $toolBar; @@ -21489,24 +19702,20 @@ class Interpretation extends Fields $donelist = array(); // we must add the formSubmited code if new above filters is used (2 = topbar) $new_filter = false; - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 2) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 2) { - $state .= PHP_EOL . PHP_EOL . $this->_t(2) . "//" - . $this->setLine(__LINE__) . " Check if the form was submitted"; - $state .= PHP_EOL . $this->_t(2) . "\$formSubmited" + $state .= PHP_EOL . PHP_EOL . Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Check if the form was submitted"; + $state .= PHP_EOL . Indent::_(2) . "\$formSubmited" . " = \$app->input->post->get('form_submited');"; $new_filter = true; } // add the default populate states (this must be added first) $state .= $this->setDefaultPopulateState($nameSingleCode, $new_filter); // add the filters - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { if (!isset($donelist[$filter['code']])) { @@ -21518,16 +19727,13 @@ class Interpretation extends Fields } } // add the rest of the set filters - if (isset($this->sortBuilder[$nameListCode]) - && ArrayHelper::check( - $this->sortBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Sort')->exists($nameListCode)) { - foreach ($this->sortBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Sort')->get($nameListCode) as $filter) { if (!isset($donelist[$filter['code']])) { - $state .= $this->getPopulateStateFilterCode( + $state .= $this->getPopulateStateFilterCode( $filter, $new_filter ); $donelist[$filter['code']] = true; @@ -21556,37 +19762,37 @@ class Interpretation extends Fields // add category stuff (may still remove these) TODO if (isset($filter['type']) && $filter['type'] === 'category') { - $state .= PHP_EOL . PHP_EOL . $this->_t(2) + $state .= PHP_EOL . PHP_EOL . Indent::_(2) . "\$category = \$app->getUserStateFromRequest(\$this->context . '.filter.category', 'filter_category');"; - $state .= PHP_EOL . $this->_t(2) + $state .= PHP_EOL . Indent::_(2) . "\$this->setState('filter.category', \$category);"; - $state .= PHP_EOL . PHP_EOL . $this->_t(2) + $state .= PHP_EOL . PHP_EOL . Indent::_(2) . "\$categoryId = \$this->getUserStateFromRequest(\$this->context . '.filter.category_id', 'filter_category_id');"; - $state .= PHP_EOL . $this->_t(2) + $state .= PHP_EOL . Indent::_(2) . "\$this->setState('filter.category_id', \$categoryId);"; } // always add the default filter - $state .= PHP_EOL . PHP_EOL . $this->_t(2) . "\$" . $filter['code'] + $state .= PHP_EOL . PHP_EOL . Indent::_(2) . "\$" . $filter['code'] . " = \$this->getUserStateFromRequest(\$this->context . '.filter." . $filter['code'] . "', 'filter_" . $filter['code'] . "'" . $extra . ");"; if ($newFilter) { // add the new filter option - $state .= PHP_EOL . $this->_t(2) + $state .= PHP_EOL . Indent::_(2) . "if (\$formSubmited)"; - $state .= PHP_EOL . $this->_t(2) . "{"; - $state .= PHP_EOL . $this->_t(3) . "\$" . $filter['code'] + $state .= PHP_EOL . Indent::_(2) . "{"; + $state .= PHP_EOL . Indent::_(3) . "\$" . $filter['code'] . " = \$app->input->post->get('" . $filter['code'] . "');"; - $state .= PHP_EOL . $this->_t(3) + $state .= PHP_EOL . Indent::_(3) . "\$this->setState('filter." . $filter['code'] . "', \$" . $filter['code'] . ");"; - $state .= PHP_EOL . $this->_t(2) . "}"; + $state .= PHP_EOL . Indent::_(2) . "}"; } else { // the old filter option - $state .= PHP_EOL . $this->_t(2) + $state .= PHP_EOL . Indent::_(2) . "\$this->setState('filter." . $filter['code'] . "', \$" . $filter['code'] . ");"; } @@ -21609,7 +19815,7 @@ class Interpretation extends Fields // start filter $filter = array('type' => 'text'); // if access is not set add its default filter here - if (!isset($this->fieldsNames[$nameSingleCode]['access'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.access')) { $filter['code'] = "access"; $state .= $this->getPopulateStateFilterCode( @@ -21617,7 +19823,7 @@ class Interpretation extends Fields ); } // if published is not set add its default filter here - if (!isset($this->fieldsNames[$nameSingleCode]['published'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.published')) { $filter['code'] = "published"; $state .= $this->getPopulateStateFilterCode( @@ -21625,7 +19831,7 @@ class Interpretation extends Fields ); } // if created_by is not set add its default filter here - if (!isset($this->fieldsNames[$nameSingleCode]['created_by'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.created_by')) { $filter['code'] = "created_by"; $state .= $this->getPopulateStateFilterCode( @@ -21633,7 +19839,7 @@ class Interpretation extends Fields ); } // if created is not set add its default filter here - if (!isset($this->fieldsNames[$nameSingleCode]['created'])) + if (!CFactory::_('Compiler.Builder.Field.Names')->isString($nameSingleCode . '.created')) { $filter['code'] = "created"; $state .= $this->getPopulateStateFilterCode( @@ -21667,24 +19873,21 @@ class Interpretation extends Fields $donelist = array('ordering', 'published'); // set the default first $fields = "return array("; - $fields .= PHP_EOL . $this->_t(3) . "'a.ordering' => JText:" + $fields .= PHP_EOL . Indent::_(3) . "'a.ordering' => JText:" . ":_('JGRID_HEADING_ORDERING')"; - $fields .= "," . PHP_EOL . $this->_t(3) . "'a.published' => JText:" + $fields .= "," . PHP_EOL . Indent::_(3) . "'a.published' => JText:" . ":_('JSTATUS')"; // add the rest of the set filters - if (isset($this->sortBuilder[$nameListCode]) - && ArrayHelper::check( - $this->sortBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Sort')->exists($nameListCode)) { - foreach ($this->sortBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Sort')->get($nameListCode) as $filter) { if (!in_array($filter['code'], $donelist)) { if ($filter['type'] === 'category') { - $fields .= "," . PHP_EOL . $this->_t(3) + $fields .= "," . PHP_EOL . Indent::_(3) . "'category_title' => JText:" . ":_('" . $filter['lang'] . "')"; } @@ -21692,23 +19895,23 @@ class Interpretation extends Fields $filter['custom'] )) { - $fields .= "," . PHP_EOL . $this->_t(3) . "'" + $fields .= "," . PHP_EOL . Indent::_(3) . "'" . $filter['custom']['db'] . "." . $filter['custom']['text'] . "' => JText:" . ":_('" . $filter['lang'] . "')"; } else { - $fields .= "," . PHP_EOL . $this->_t(3) . "'a." + $fields .= "," . PHP_EOL . Indent::_(3) . "'a." . $filter['code'] . "' => JText:" . ":_('" . $filter['lang'] . "')"; } } } } - $fields .= "," . PHP_EOL . $this->_t(3) . "'a.id' => JText:" + $fields .= "," . PHP_EOL . Indent::_(3) . "'a.id' => JText:" . ":_('JGRID_HEADING_ID')"; - $fields .= PHP_EOL . $this->_t(2) . ");"; + $fields .= PHP_EOL . Indent::_(2) . ");"; // return fields return $fields; @@ -21716,198 +19919,178 @@ class Interpretation extends Fields public function setCheckinCall() { - $call = PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $call = PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Check in items"; - $call .= PHP_EOL . $this->_t(2) . "\$this->checkInNow();" . PHP_EOL; + $call .= PHP_EOL . Indent::_(2) . "\$this->checkInNow();" . PHP_EOL; return $call; } public function setAutoCheckin($view, $component) { - $checkin = PHP_EOL . PHP_EOL . $this->_t(1) . "/**"; - $checkin .= PHP_EOL . $this->_t(1) + $checkin = PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $checkin .= PHP_EOL . Indent::_(1) . " * Build an SQL query to checkin all items left checked out longer then a set time."; - $checkin .= PHP_EOL . $this->_t(1) . " *"; - $checkin .= PHP_EOL . $this->_t(1) . " * @return a bool"; - $checkin .= PHP_EOL . $this->_t(1) . " *"; - $checkin .= PHP_EOL . $this->_t(1) . " */"; - $checkin .= PHP_EOL . $this->_t(1) . "protected function checkInNow()"; - $checkin .= PHP_EOL . $this->_t(1) . "{"; - $checkin .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) + $checkin .= PHP_EOL . Indent::_(1) . " *"; + $checkin .= PHP_EOL . Indent::_(1) . " * @return a bool"; + $checkin .= PHP_EOL . Indent::_(1) . " *"; + $checkin .= PHP_EOL . Indent::_(1) . " */"; + $checkin .= PHP_EOL . Indent::_(1) . "protected function checkInNow()"; + $checkin .= PHP_EOL . Indent::_(1) . "{"; + $checkin .= PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) . " Get set check in time"; - $checkin .= PHP_EOL . $this->_t(2) + $checkin .= PHP_EOL . Indent::_(2) . "\$time = JComponentHelper::getParams('com_" . $component . "')->get('check_in');"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(2) . "if (\$time)"; - $checkin .= PHP_EOL . $this->_t(2) . "{"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $checkin .= PHP_EOL . PHP_EOL . Indent::_(2) . "if (\$time)"; + $checkin .= PHP_EOL . Indent::_(2) . "{"; + $checkin .= PHP_EOL . PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Get a db connection."; - $checkin .= PHP_EOL . $this->_t(3) . "\$db = JFactory::getDbo();"; - $checkin .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $checkin .= PHP_EOL . Indent::_(3) . "\$db = JFactory::getDbo();"; + $checkin .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Reset query."; - $checkin .= PHP_EOL . $this->_t(3) . "\$query = \$db->getQuery(true);"; - $checkin .= PHP_EOL . $this->_t(3) . "\$query->select('*');"; - $checkin .= PHP_EOL . $this->_t(3) + $checkin .= PHP_EOL . Indent::_(3) . "\$query = \$db->getQuery(true);"; + $checkin .= PHP_EOL . Indent::_(3) . "\$query->select('*');"; + $checkin .= PHP_EOL . Indent::_(3) . "\$query->from(\$db->quoteName('#__" . $component . "_" . $view . "'));"; - $checkin .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) + $checkin .= PHP_EOL . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Only select items that are checked out."; - $checkin .= PHP_EOL . $this->_t(3) + $checkin .= PHP_EOL . Indent::_(3) . "\$query->where(\$db->quoteName('checked_out') . '!=0');"; - $this->_t(3) . "//" . $this->setLine(__LINE__) + Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " Query only to see if we have a rows"; - $checkin .= PHP_EOL . $this->_t(3) . "\$db->setQuery(\$query, 0, 1);"; - $checkin .= PHP_EOL . $this->_t(3) . "\$db->execute();"; - $checkin .= PHP_EOL . $this->_t(3) . "if (\$db->getNumRows())"; - $checkin .= PHP_EOL . $this->_t(3) . "{"; - $checkin .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $checkin .= PHP_EOL . Indent::_(3) . "\$db->setQuery(\$query, 0, 1);"; + $checkin .= PHP_EOL . Indent::_(3) . "\$db->execute();"; + $checkin .= PHP_EOL . Indent::_(3) . "if (\$db->getNumRows())"; + $checkin .= PHP_EOL . Indent::_(3) . "{"; + $checkin .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Get Yesterdays date."; - $checkin .= PHP_EOL . $this->_t(4) + $checkin .= PHP_EOL . Indent::_(4) . "\$date = JFactory::getDate()->modify(\$time)->toSql();"; - $checkin .= PHP_EOL . $this->_t(4) . "//" . $this->setLine(__LINE__) + $checkin .= PHP_EOL . Indent::_(4) . "//" . Line::_(__Line__, __Class__) . " Reset query."; - $checkin .= PHP_EOL . $this->_t(4) . "\$query = \$db->getQuery(true);"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $checkin .= PHP_EOL . Indent::_(4) . "\$query = \$db->getQuery(true);"; + $checkin .= PHP_EOL . PHP_EOL . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Fields to update."; - $checkin .= PHP_EOL . $this->_t(4) . "\$fields = array("; - $checkin .= PHP_EOL . $this->_t(5) + $checkin .= PHP_EOL . Indent::_(4) . "\$fields = array("; + $checkin .= PHP_EOL . Indent::_(5) . "\$db->quoteName('checked_out_time') . '=\'0000-00-00 00:00:00\'',"; - $checkin .= PHP_EOL . $this->_t(5) + $checkin .= PHP_EOL . Indent::_(5) . "\$db->quoteName('checked_out') . '=0'"; - $checkin .= PHP_EOL . $this->_t(4) . ");"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $checkin .= PHP_EOL . Indent::_(4) . ");"; + $checkin .= PHP_EOL . PHP_EOL . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Conditions for which records should be updated."; - $checkin .= PHP_EOL . $this->_t(4) . "\$conditions = array("; - $checkin .= PHP_EOL . $this->_t(5) + $checkin .= PHP_EOL . Indent::_(4) . "\$conditions = array("; + $checkin .= PHP_EOL . Indent::_(5) . "\$db->quoteName('checked_out') . '!=0', "; - $checkin .= PHP_EOL . $this->_t(5) + $checkin .= PHP_EOL . Indent::_(5) . "\$db->quoteName('checked_out_time') . '<\''.\$date.'\''"; - $checkin .= PHP_EOL . $this->_t(4) . ");"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $checkin .= PHP_EOL . Indent::_(4) . ");"; + $checkin .= PHP_EOL . PHP_EOL . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Check table."; - $checkin .= PHP_EOL . $this->_t(4) + $checkin .= PHP_EOL . Indent::_(4) . "\$query->update(\$db->quoteName('#__" . $component . "_" . $view . "'))->set(\$fields)->where(\$conditions); "; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(4) + $checkin .= PHP_EOL . PHP_EOL . Indent::_(4) . "\$db->setQuery(\$query);"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(4) . "\$db->execute();"; - $checkin .= PHP_EOL . $this->_t(3) . "}"; - $checkin .= PHP_EOL . $this->_t(2) . "}"; - $checkin .= PHP_EOL . PHP_EOL . $this->_t(2) . "return false;"; - $checkin .= PHP_EOL . $this->_t(1) . "}"; + $checkin .= PHP_EOL . PHP_EOL . Indent::_(4) . "\$db->execute();"; + $checkin .= PHP_EOL . Indent::_(3) . "}"; + $checkin .= PHP_EOL . Indent::_(2) . "}"; + $checkin .= PHP_EOL . PHP_EOL . Indent::_(2) . "return false;"; + $checkin .= PHP_EOL . Indent::_(1) . "}"; return $checkin; } - public function setGetItemsMethodStringFix($nameSingleCode, - $nameListCode, - $Component, $tab = '', $export = false, $all = false - ) + public function setGetItemsMethodStringFix($nameSingleCode, $nameListCode, + $Component, $tab = '', $export = false, $all = false) { // add the fix if this view has the need for it $fix = ''; $forEachStart = ''; $fix_access = ''; // encryption switches - foreach ($this->cryptionTypes as $cryptionType) + foreach (CFactory::_('Config')->cryption_types as $cryptionType) { ${$cryptionType . 'Crypt'} = false; } - // setup correct core target - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } $component = StringHelper::safe($Component); // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder[$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder[$core['core.access']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder[$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->actionExist($nameSingleCode, 'core.access')) { - $fix_access = PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine(__LINE__) + $fix_access = PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " Remove items the user can't access."; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) - . "\$access = (\$user->authorise('" . $core['core.access'] + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) + . "\$access = (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.access') . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$item->id) && \$user->authorise('" - . $core['core.access'] . "', 'com_" . $component . "'));"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + . CFactory::_('Compiler.Creator.Permission')->getAction($nameSingleCode, 'core.access') + . "', 'com_" . $component . "'));"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "if (!\$access)"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "{"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "unset(\$items[\$nr]);"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "continue;"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "}" + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}" . PHP_EOL; } // add the tags if needed - if (isset($this->tagsBuilder[$nameSingleCode])) + if (CFactory::_('Compiler.Builder.Tags')->exists($nameSingleCode)) { - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine( - __LINE__ + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_( + __LINE__,__CLASS__ ) . " Add the tags"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$item->tags = new JHelperTags;"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$item->tags->getTagIds("; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$item->id, 'com_" - . $this->fileContentStatic[$this->hhh . 'component' - . $this->hhh] . ".$nameSingleCode'"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . ");"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + . CFactory::_('Compiler.Builder.Content.One')->get('component') . ".$nameSingleCode'"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . ");"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "if (\$item->tags->tags)"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "{"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$item->tags = implode(', ',"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "\$item->tags->getTagNames("; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(6) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(6) . "explode(',', \$item->tags->tags)"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) . ")"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . ");"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "}"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . ")"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . ");"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "else"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "{"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$item->tags = '';"; - $fix_access .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "}"; + $fix_access .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}"; } // get the correct array if ($export || $all) { - $methodName = 'getItemsMethodEximportStringFixBuilder'; + $action_ = 'Eximport'; } else { - $methodName = 'getItemsMethodListStringFixBuilder'; + $action_ = 'List'; } // load the relations before modeling - if (isset($this->fieldRelations[$nameListCode]) - && ArrayHelper::check( - $this->fieldRelations[$nameListCode] - )) + if (($field_relations = + CFactory::_('Compiler.Builder.Field.Relations')->get($nameListCode)) !== null) { - foreach ( - $this->fieldRelations[$nameListCode] as $field_id => $fields - ) + foreach ($field_relations as $field_id => $fields) { foreach ($fields as $area => $field) { @@ -21921,12 +20104,10 @@ class Interpretation extends Fields } } // open the values - if (isset($this->{$methodName}[$nameSingleCode]) - && ArrayHelper::check( - $this->{$methodName}[$nameSingleCode] - )) + if (CFactory::_("Compiler.Builder.Items.Method.{$action_}.String")->exists($nameSingleCode)) { - foreach ($this->{$methodName}[$nameSingleCode] as $item) + foreach (CFactory::_("Compiler.Builder.Items.Method.{$action_}.String")-> + get($nameSingleCode) as $item) { switch ($item['method']) { @@ -21974,87 +20155,83 @@ class Interpretation extends Fields if ($item['type'] === 'usergroup' && !$export && $item['method'] != 6) { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " decode " . $item['name']; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "\$" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " decode " . $item['name']; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$" . $item['name'] . "Array = " . $decode . "(\$item->" . $item['name'] . $suffix_decode . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "if (" . $Component . "Helper::checkArray(\$" . $item['name'] . "Array))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . "\$" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$" . $item['name'] . "Names = array();"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "foreach (\$" . $item['name'] . "Array as \$" . $item['name'] . ")"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) . "\$" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "\$" . $item['name'] . "Names[] = " . $Component . "Helper::getGroupName(\$" . $item['name'] . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$item->" . $item['name'] . " = implode(', ', \$" . $item['name'] . "Names);"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}"; } /* elseif ($item['type'] === 'usergroup' && $export) { - $fix .= PHP_EOL.$this->_t(1).$tab.$this->_t(3) . "//".$this->setLine(__LINE__)." decode ".$item['name']; - $fix .= PHP_EOL.$this->_t(1).$tab.$this->_t(3) . "\$".$item['name']."Array = ".$decode."(\$item->".$item['name'].$suffix_decode.");"; - $fix .= PHP_EOL.$this->_t(1).$tab.$this->_t(3) . "if (".$Component."Helper::checkArray(\$".$item['name']."Array))"; - $fix .= PHP_EOL.$this->_t(1).$tab.$this->_t(3) . "{"; - $fix .= PHP_EOL.$this->_t(1).$tab.$this->_t(4) . "\$item->".$item['name']." = implode('|',\$".$item['name']."Array);"; - $fix .= PHP_EOL.$this->_t(1).$tab.$this->_t(3) . "}"; + $fix .= PHP_EOL.Indent::_(1).$tab.Indent::_(3) . "//".Line::_(__Line__, __Class__)." decode ".$item['name']; + $fix .= PHP_EOL.Indent::_(1).$tab.Indent::_(3) . "\$".$item['name']."Array = ".$decode."(\$item->".$item['name'].$suffix_decode.");"; + $fix .= PHP_EOL.Indent::_(1).$tab.Indent::_(3) . "if (".$Component."Helper::checkArray(\$".$item['name']."Array))"; + $fix .= PHP_EOL.Indent::_(1).$tab.Indent::_(3) . "{"; + $fix .= PHP_EOL.Indent::_(1).$tab.Indent::_(4) . "\$item->".$item['name']." = implode('|',\$".$item['name']."Array);"; + $fix .= PHP_EOL.Indent::_(1).$tab.Indent::_(3) . "}"; } */ elseif ($item['translation'] && !$export && $item['method'] != 6) { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " decode " . $item['name']; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "\$" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " decode " . $item['name']; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$" . $item['name'] . "Array = " . $decode . "(\$item->" . $item['name'] . $suffix_decode . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "if (" . $Component . "Helper::checkArray(\$" . $item['name'] . "Array))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . "\$" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$" . $item['name'] . "Names = array();"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "foreach (\$" . $item['name'] . "Array as \$" . $item['name'] . ")"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) . "\$" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "\$" . $item['name'] . "Names[] = JText:" . ":_(\$this->selectionTranslation(\$" . $item['name'] . ", '" . $item['name'] . "'));"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$item->" . $item['name'] . " = implode(', ', \$" . $item['name'] . "Names);"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}"; } else { - if ($item['method'] == 2 || $item['method'] == 3 - || $item['method'] == 4 - || $item['method'] == 5 - || $item['method'] == 6) + if ($item['method'] == 2 || $item['method'] == 3 || $item['method'] == 4 + || $item['method'] == 5 || $item['method'] == 6) { // expert mode (dev must do it all) if ($item['method'] == 6) { $_placeholder_for_field - = array('[[[field]]]' => "\$item->" - . $item['name']); - $fix .= $this->setPlaceholders( - PHP_EOL . $this->_t(1) . $tab . $this->_t(3) - . implode( - PHP_EOL . $this->_t(1) . $tab . $this->_t( - 3 - ), - $this->expertFieldModeling[$nameSingleCode][$item['name']]['get'] + = array('[[[field]]]' => "\$item->" . $item['name']); + $fix .= CFactory::_('Placeholder')->update( + PHP_EOL . Indent::_(1) . $tab . Indent::_(3) + . implode(PHP_EOL . Indent::_(1) . $tab . Indent::_(3), + CFactory::_('Compiler.Builder.Model.Expert.Field')->get( + $nameSingleCode . '.' . $item['name'] . '.get', [] + ) ), $_placeholder_for_field ); } @@ -22063,68 +20240,68 @@ class Interpretation extends Fields $taber = ''; if ($item['method'] == 3) { - $taber = $this->_t(1); - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) + $taber = Indent::_(1); + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "if (\$basickey && !is_numeric(\$item->" . $item['name'] . ") && \$item->" . $item['name'] . " === base64_encode(base64_decode(\$item->" . $item['name'] . ", true)))"; - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "{"; } elseif ($item['method'] == 5) { - $taber = $this->_t(1); - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) + $taber = Indent::_(1); + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "if (\$mediumkey && !is_numeric(\$item->" . $item['name'] . ") && \$item->" . $item['name'] . " === base64_encode(base64_decode(\$item->" . $item['name'] . ", true)))"; - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "{"; } elseif ($item['method'] == 4) { - $taber = $this->_t(1); - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) + $taber = Indent::_(1); + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "if (\$whmcskey && !is_numeric(\$item->" . $item['name'] . ") && \$item->" . $item['name'] . " === base64_encode(base64_decode(\$item->" . $item['name'] . ", true)))"; - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "{"; } if ($item['method'] == 3 || $item['method'] == 4 || $item['method'] == 5) { - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " decrypt " . $item['name']; } else { - $fix .= PHP_EOL . $this->_t(1) . $tab . $taber - . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fix .= PHP_EOL . Indent::_(1) . $tab . $taber + . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " decode " . $item['name']; } - $fix .= PHP_EOL . $this->_t(1) . $tab . $taber - . $this->_t(3) . "\$item->" . $item['name'] + $fix .= PHP_EOL . Indent::_(1) . $tab . $taber + . Indent::_(3) . "\$item->" . $item['name'] . " = " . $decode . "(\$item->" . $item['name'] . ");"; if ($item['method'] == 3 || $item['method'] == 4 || $item['method'] == 5) { - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "}"; } } } @@ -22132,96 +20309,96 @@ class Interpretation extends Fields { if ($export && $item['type'] === 'repeatable') { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) - . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) + . "//" . Line::_(__Line__, __Class__) . " decode repeatable " . $item['name']; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$" . $item['name'] . "Array = " . $decode . "(\$item->" . $item['name'] . $suffix_decode . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "if (" . $Component . "Helper::checkArray(\$" . $item['name'] . "Array))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "\$bucket" . $item['name'] . " = array();"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "foreach (\$" . $item['name'] . "Array as \$" . $item['name'] . "FieldName => \$" . $item['name'] . ")"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "if (" . $Component . "Helper::checkArray(\$" . $item['name'] . "))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(6) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(6) . "\$bucket" . $item['name'] . "[] = \$" . $item['name'] . "FieldName . '<||VDM||>' . implode('<|VDM|>',\$" . $item['name'] . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) - . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) + . "//" . Line::_(__Line__, __Class__) . " make sure the bucket has values."; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "if (" . $Component . "Helper::checkArray(\$bucket" . $item['name'] . "))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) - . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) + . "//" . Line::_(__Line__, __Class__) . " clear the repeatable field."; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "unset(\$item->" . $item['name'] . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) - . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) + . "//" . Line::_(__Line__, __Class__) . " set repeatable field for export."; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "\$item->" . $item['name'] . " = implode('<|||VDM|||>',\$bucket" . $item['name'] . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) - . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) + . "//" . Line::_(__Line__, __Class__) . " unset the bucket."; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(5) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(5) . "unset(\$bucket" . $item['name'] . ");"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(4) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(4) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}"; } elseif ($item['method'] == 1 && !$export) { // TODO we check if this works well. - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) - . "//" . $this->setLine(__LINE__) . " convert " + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) + . "//" . Line::_(__Line__, __Class__) . " convert " . $item['name']; if (isset($item['custom']['table'])) { // check if this is a local table if (strpos( - $item['custom']['table'], - '#__' . $this->componentCodeName . '_' + (string) $item['custom']['table'], + '#__' . CFactory::_('Config')->component_code_name . '_' ) !== false) { $keyTableNAme = str_replace( - '#__' . $this->componentCodeName . '_', - '', $item['custom']['table'] + '#__' . CFactory::_('Config')->component_code_name . '_', + '', (string) $item['custom']['table'] ); } else { $keyTableNAme = $item['custom']['table']; } - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "\$item->" . $item['name'] + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "\$item->" . $item['name'] . " = " . $Component . "Helper::jsonToString(\$item->" . $item['name'] . ", ', ', '" @@ -22231,8 +20408,8 @@ class Interpretation extends Fields } else { - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "\$item->" . $item['name'] + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "\$item->" . $item['name'] . " = " . $Component . "Helper::jsonToString(\$item->" . $item['name'] . ", ', ', '" @@ -22244,12 +20421,12 @@ class Interpretation extends Fields if (!$export) { // For those we have not cached yet. - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " convert " . $item['name']; - $fix .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(3) . "\$item->" . $item['name'] + $fix .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(3) . "\$item->" . $item['name'] . " = " . $Component . "Helper::jsonToString(\$item->" . $item['name'] . ");"; @@ -22260,21 +20437,19 @@ class Interpretation extends Fields } } /* // set translation (TODO) would be nice to cut down on double loops.. - if (!$export && isset($this->selectionTranslationFixBuilder[$nameListCode]) && ArrayHelper::check($this->selectionTranslationFixBuilder[$nameListCode])) + if (!$export && CFactory::_('Compiler.Builder.Selection.Translation')->exists($nameListCode)) { - foreach ($this->selectionTranslationFixBuilder[$nameListCode] as $name => $values) + foreach (CFactory::_('Compiler.Builder.Selection.Translation')->get($nameListCode) as $name => $values) { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" . $this->setLine(__LINE__) . " convert " . $name; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "\$item->" . $name . " = \$this->selectionTranslation(\$item->" . $name . ", '" . $name . "');"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" . Line::_(__Line__, __Class__) . " convert " . $name; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$item->" . $name . " = \$this->selectionTranslation(\$item->" . $name . ", '" . $name . "');"; } } */ // load the relations after modeling - if (isset($this->fieldRelations[$nameListCode]) - && ArrayHelper::check( - $this->fieldRelations[$nameListCode] - )) + if (($field_relations = + CFactory::_('Compiler.Builder.Field.Relations')->get($nameListCode)) !== null) { - foreach ($this->fieldRelations[$nameListCode] as $fields) + foreach ($field_relations as $fields) { foreach ($fields as $area => $field) { @@ -22288,34 +20463,30 @@ class Interpretation extends Fields } } // close the foreach if needed - if (StringHelper::check($fix) - || StringHelper::check($fix_access) - || $export - || $all) + if (StringHelper::check($fix) || StringHelper::check($fix_access) || $export || $all) { // start the loop - $forEachStart = PHP_EOL . PHP_EOL . $this->_t(1) . $tab . $this->_t( + $forEachStart = PHP_EOL . PHP_EOL . Indent::_(1) . $tab . Indent::_( 1 - ) . "//" . $this->setLine(__LINE__) + ) . "//" . Line::_(__Line__, __Class__) . " Set values to display correctly."; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "if (" . $Component . "Helper::checkArray(\$items))"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "{"; + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "{"; // do not add to export since it is already done if (!$export) { - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) - . "//" . $this->setLine(__LINE__) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) + . "//" . Line::_(__Line__, __Class__) . " Get the user object if not set."; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "if (!isset(\$user) || !" - . $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . "Helper::checkObject(\$user))"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) + . CFactory::_('Compiler.Builder.Content.One')->get('Component') . "Helper::checkObject(\$user))"; + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "{"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$user = JFactory::getUser();"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "}"; } // the permissional acttion switch @@ -22355,11 +20526,11 @@ class Interpretation extends Fields // add the notes and get the global switch if ($hasPermissional) { - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t( + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_( 2 - ) . "//" . $this->setLine(__LINE__) + ) . "//" . Line::_(__Line__, __Class__) . " Get global permissional control activation. (default is inactive)"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t( + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_( 2 ) . "\$strict_permission_per_field = JComponentHelper::getParams('com_" @@ -22368,20 +20539,20 @@ class Interpretation extends Fields . PHP_EOL; } } - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "foreach (\$items as \$nr => &\$item)"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) . "{"; + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "{"; // add the access options $forEachStart .= $fix_access; // add the permissional removal of values the user has not right to view or access if ($hasPermissional) { - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) - . "//" . $this->setLine(__LINE__) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) + . "//" . Line::_(__Line__, __Class__) . " use permissional control if globally set."; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "if (\$strict_permission_per_field)"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "{"; foreach ( $this->permissionFields[$nameSingleCode] as $fieldName => @@ -22396,121 +20567,110 @@ class Interpretation extends Fields { case 'access': case 'view': - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(4) . "//" . $this->setLine( - __LINE__ + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(4) . "//" . Line::_( + __LINE__,__CLASS__ ) . " set " . $permission_option . " permissional control for " . $fieldName . " value."; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(4) . "if (isset(\$item->" + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(4) . "if (isset(\$item->" . $fieldName . ") && (!\$user->authorise('" . $nameSingleCode . "." . $permission_option . "." . $fieldName . "', 'com_" . $component . "." . $nameSingleCode . ".' . (int) \$item->id)"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(5) . "|| !\$user->authorise('" + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(5) . "|| !\$user->authorise('" . $nameSingleCode . "." . $permission_option . "." . $fieldName . "', 'com_" . $component . "')))"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(4) . "{"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(5) . "//" . $this->setLine( - __LINE__ + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(4) . "{"; + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(5) . "//" . Line::_( + __LINE__,__CLASS__ ) . " We JUST empty the value (do you have a better idea)"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(5) . "\$item->" . $fieldName + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(5) . "\$item->" . $fieldName . " = '';"; - $forEachStart .= PHP_EOL . $this->_t(1) . $tab - . $this->_t(4) . "}"; + $forEachStart .= PHP_EOL . Indent::_(1) . $tab + . Indent::_(4) . "}"; break; } } } - $forEachStart .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $forEachStart .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "}"; } // remove these values if export if ($export) { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine(__LINE__) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " unset the values we don't want exported."; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "unset(\$item->asset_id);"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "unset(\$item->checked_out);"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "unset(\$item->checked_out_time);"; } - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "}"; if ($export) { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "//" - . $this->setLine(__LINE__) . " Add headers to items array."; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "//" + . Line::_(__Line__, __Class__) . " Add headers to items array."; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "\$headers = \$this->getExImPortHeaders();"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "if (" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "if (" . $Component . "Helper::checkObject(\$headers))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "array_unshift(\$items,\$headers);"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "}"; } } // add custom php to getitems method - $fix .= $this->getCustomScriptBuilder( + $fix .= CFactory::_('Customcode.Dispenser')->get( 'php_getitems', $nameSingleCode, PHP_EOL . PHP_EOL . $tab ); // load the encryption object if needed $script = ''; - foreach ($this->cryptionTypes as $cryptionType) + foreach (CFactory::_('Config')->cryption_types as $cryptionType) { if (${$cryptionType . 'Crypt'}) { if ('expert' !== $cryptionType) { - $script .= PHP_EOL . PHP_EOL . $this->_t(1) . $tab - . $this->_t(1) . "//" . $this->setLine(__LINE__) + $script .= PHP_EOL . PHP_EOL . Indent::_(1) . $tab + . Indent::_(1) . "//" . Line::_(__Line__, __Class__) . " Get the " . $cryptionType . " encryption key."; - $script .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) + $script .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "\$" . $cryptionType . "key = " . $Component . "Helper::getCryptKey('" . $cryptionType . "');"; - $script .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) - . "//" . $this->setLine(__LINE__) + $script .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) + . "//" . Line::_(__Line__, __Class__) . " Get the encryption object."; - $script .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) - . "\$" . $cryptionType . " = new FOFEncryptAes(\$" + $script .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) + . "\$" . $cryptionType . " = new Super___99175f6d_dba8_4086_8a65_5c4ec175e61d___Power(\$" . $cryptionType . "key);"; } - elseif (isset( - $this->{$cryptionType - . 'FieldModelInitiator'}[$nameSingleCode] - ) - && isset( - $this->{$cryptionType - . 'FieldModelInitiator'}[$nameSingleCode]['get'] - )) + elseif (CFactory::_('Compiler.Builder.Model.' . ucfirst($cryptionType). '.Field.Initiator')-> + exists("{$nameSingleCode}.get")) { - foreach ( - $this->{$cryptionType - . 'FieldModelInitiator'}[$nameSingleCode]['get'] as - $block - ) + foreach (CFactory::_('Compiler.Builder.Model.' . ucfirst($cryptionType). '.Field.Initiator')-> + get("{$nameSingleCode}.get") as $block) { - $script .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) - . implode( - PHP_EOL . $this->_t(1) . $tab . $this->_t(1), - $block - ); + $script .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . implode( + PHP_EOL . Indent::_(1) . $tab . Indent::_(1), $block + ); } } } @@ -22584,7 +20744,7 @@ class Interpretation extends Fields case 'custom.admin.views': case 'site.admin.view': $headers[] - = 'JHtml::addIncludePath(JPATH_COMPONENT.\'/helpers/html\');'; + = 'JHtml::addIncludePath(JPATH_COMPONENT.\'/helpers/html\');'; $headers[] = 'JHtml::_(\'behavior.formvalidator\');'; $headers[] = 'JHtml::_(\'formbehavior.chosen\', \'select\');'; $headers[] = 'JHtml::_(\'behavior.keepalive\');'; @@ -22605,11 +20765,8 @@ class Interpretation extends Fields case 'custom.admin.views.html': $headers[] = 'use Joomla\CMS\MVC\View\HtmlView;'; // load the file class if uikit is being loaded - if ((2 == $this->uikit || 1 == $this->uikit) - && isset($this->uikitComp[$codeName]) - && ArrayHelper::check( - $this->uikitComp[$codeName] - )) + if ((2 == CFactory::_('Config')->uikit || 1 == CFactory::_('Config')->uikit) + && CFactory::_('Compiler.Builder.Uikit.Comp')->exists($codeName)) { $headers[] = 'use Joomla\CMS\Filesystem\File;'; } @@ -22621,9 +20778,19 @@ class Interpretation extends Fields $headers[] = 'use Joomla\Utilities\ArrayHelper;'; break; case 'custom.admin.view.controller': + case 'import.custom.controller': + case 'import.controller': $headers[] = 'use Joomla\CMS\MVC\Controller\BaseController;'; $headers[] = 'use Joomla\Utilities\ArrayHelper;'; break; + case 'import.custom.model': + case 'import.model': + $headers[] = 'use Joomla\CMS\MVC\Model\BaseDatabaseModel;'; + $headers[] = 'use Joomla\CMS\Filesystem\File;'; + $headers[] = 'use Joomla\CMS\Filesystem\Folder;'; + $headers[] = 'use Joomla\Utilities\ArrayHelper;'; + $headers[] = 'use PhpOffice\PhpSpreadsheet\IOFactory;'; + break; case 'admin.views.controller': case 'custom.admin.views.controller': case 'dashboard.controller': @@ -22634,17 +20801,19 @@ class Interpretation extends Fields $headers[] = 'use Joomla\Utilities\ArrayHelper;'; break; } + // for plugin event TODO change event api signatures + $component_context = CFactory::_('Config')->component_context; // Trigger Event: jcb_ce_setClassHeader - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_setClassHeader', - array(&$this->componentContext, &$context, &$codeName, + array(&$component_context, &$context, &$codeName, &$headers) ); // check if headers were added if (ArrayHelper::check($headers)) { // return the headers - return $this->setPlaceholders(implode(PHP_EOL, $headers), $this->placeholders); + return CFactory::_('Placeholder')->update_(implode(PHP_EOL, $headers)); } return $default; @@ -22661,7 +20830,7 @@ class Interpretation extends Fields protected function setHelperClassHeader(&$headers, $target_client) { // add only to admin client - if ('admin' === $target_client && $this->addEximport) + if ('admin' === $target_client && CFactory::_('Config')->get('add_eximport', false)) { $headers[] = 'use PhpOffice\PhpSpreadsheet\IOFactory;'; $headers[] = 'use PhpOffice\PhpSpreadsheet\Spreadsheet;'; @@ -22681,40 +20850,30 @@ class Interpretation extends Fields protected function setChosenMultiSelectionHeaders(&$headers, $nameListCode) { // check that the filter type is the new filter option (2 = topbar) - if (isset($this->adminFilterType[$nameListCode]) - && $this->adminFilterType[$nameListCode] == 2) + if (CFactory::_('Compiler.Builder.Admin.Filter.Type')->get($nameListCode, 1) == 2) { // add category switch $add_category = false; - if (isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - ) - && isset($this->categoryBuilder[$nameListCode]['extension']) - && isset($this->categoryBuilder[$nameListCode]['filter']) - && $this->categoryBuilder[$nameListCode]['filter'] >= 1) + if (CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.extension") + && CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.filter", 0) >= 1) { // is found so add it $add_category = true; } // add accessLevels switch $add_access_levels = false; - if (in_array($nameListCode, $this->accessBuilder)) + if (CFactory::_('Compiler.Builder.Access.Switch.List')->exists($nameListCode)) { // is found so add it $add_access_levels = true; } // check if this view have filters - if (isset($this->filterBuilder[$nameListCode]) - && ArrayHelper::check( - $this->filterBuilder[$nameListCode] - )) + if (CFactory::_('Compiler.Builder.Filter')->exists($nameListCode)) { - foreach ($this->filterBuilder[$nameListCode] as $filter) + foreach (CFactory::_('Compiler.Builder.Filter')->get($nameListCode) as $filter) { // we need this only for filters that are multi - if (isset($filter['multi']) - && $filter['multi'] == 2) + if (isset($filter['multi']) && $filter['multi'] == 2) { // if this is a category we should make sure it must be added if (!$add_category && $filter['type'] === 'category') @@ -22758,7 +20917,7 @@ class Interpretation extends Fields $headers[] = 'JHtml::_(\'formbehavior.chosen\', \'.multipleCategories' . '\', null, array(\'placeholder_text_multiple\' => \'- \' . JText::_(\'' - . $this->categoryBuilder[$nameListCode]['name'] + . CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.name", 'error') . '\') . \' -\'));'; } // add accessLevels if not already added @@ -22771,8 +20930,8 @@ class Interpretation extends Fields $filter_name_select, 'U' ); // and to translation - $this->setLangContent( - $this->lang, $filter_name_select_lang, $filter_name_select + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $filter_name_select_lang, $filter_name_select ); // add the header $headers[] @@ -22800,7 +20959,7 @@ class Interpretation extends Fields foreach ($item['joinfields'] as $join) { $field['$item->{' . (int) $join . '}'] = '$item->' - . $this->listJoinBuilder[$nameListCode][(int) $join]['code']; + . CFactory::_('Compiler.Builder.List.Join')->get($nameListCode . '.' . (int) $join . '.code', 'error'); } } // set based on join_type @@ -22809,60 +20968,55 @@ class Interpretation extends Fields // code $code = (array) explode( PHP_EOL, str_replace( - array_keys($field), array_values($field), $item['set'] + array_keys($field), array_values($field), (string) $item['set'] ) ); - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . implode( - PHP_EOL . $this->_t(1) . $tab . $this->_t(3), $code + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . implode( + PHP_EOL . Indent::_(1) . $tab . Indent::_(3), $code ); } else { // concatenate - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " concatenate these fields"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "\$item->" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " concatenate these fields"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$item->" . $item['code'] . ' = ' . implode( - " . '" . str_replace("'", ''', $item['set']) . "' . ", + " . '" . str_replace("'", ''', (string) $item['set']) . "' . ", $field ) . ';'; } - return $this->setPlaceholders($fix, $this->placeholders); + return CFactory::_('Placeholder')->update_($fix); } public function setSelectionTranslationFix($views, $Component, $tab = '') { // add the fix if this view has the need for it $fix = ''; - if (isset($this->selectionTranslationFixBuilder[$views]) - && ArrayHelper::check( - $this->selectionTranslationFixBuilder[$views] - )) + if (CFactory::_('Compiler.Builder.Selection.Translation')->exists($views)) { - $fix .= PHP_EOL . PHP_EOL . $this->_t(1) . $tab . $this->_t(1) - . "//" . $this->setLine(__LINE__) + $fix .= PHP_EOL . PHP_EOL . Indent::_(1) . $tab . Indent::_(1) + . "//" . Line::_(__Line__, __Class__) . " set selection value to a translatable value"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "if (" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "if (" . $Component . "Helper::checkArray(\$items))"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "{"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "{"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "foreach (\$items as \$nr => &\$item)"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) . "{"; - foreach ( - $this->selectionTranslationFixBuilder[$views] as $name => - $values - ) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "{"; + foreach (CFactory::_('Compiler.Builder.Selection.Translation')-> + get($views) as $name => $values) { - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" - . $this->setLine(__LINE__) . " convert " . $name; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "//" + . Line::_(__Line__, __Class__) . " convert " . $name; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(3) . "\$item->" . $name . " = \$this->selectionTranslation(\$item->" . $name . ", '" . $name . "');"; } - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(2) . "}"; - $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(1) . "}" + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(2) . "}"; + $fix .= PHP_EOL . Indent::_(1) . $tab . Indent::_(1) . "}" . PHP_EOL; } @@ -22873,34 +21027,29 @@ class Interpretation extends Fields { // add the fix if this view has the need for it $fix = ''; - if (isset($this->selectionTranslationFixBuilder[$views]) - && ArrayHelper::check( - $this->selectionTranslationFixBuilder[$views] - )) + if (CFactory::_('Compiler.Builder.Selection.Translation')->exists($views)) { - $fix .= PHP_EOL . PHP_EOL . $this->_t(1) . "/**"; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $fix .= PHP_EOL . Indent::_(1) . " * Method to convert selection values to translatable string."; - $fix .= PHP_EOL . $this->_t(1) . " *"; - $fix .= PHP_EOL . $this->_t(1) . " * @return translatable string"; - $fix .= PHP_EOL . $this->_t(1) . " */"; - $fix .= PHP_EOL . $this->_t(1) + $fix .= PHP_EOL . Indent::_(1) . " *"; + $fix .= PHP_EOL . Indent::_(1) . " * @return translatable string"; + $fix .= PHP_EOL . Indent::_(1) . " */"; + $fix .= PHP_EOL . Indent::_(1) . "public function selectionTranslation(\$value,\$name)"; - $fix .= PHP_EOL . $this->_t(1) . "{"; - foreach ( - $this->selectionTranslationFixBuilder[$views] as $name => - $values - ) + $fix .= PHP_EOL . Indent::_(1) . "{"; + foreach (CFactory::_('Compiler.Builder.Selection.Translation')-> + get($views) as $name => $values) { if (ArrayHelper::check($values)) { - $fix .= PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $fix .= PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Array of " . $name . " language strings"; - $fix .= PHP_EOL . $this->_t(2) . "if (\$name === '" + $fix .= PHP_EOL . Indent::_(2) . "if (\$name === '" . $name . "')"; - $fix .= PHP_EOL . $this->_t(2) . "{"; - $fix .= PHP_EOL . $this->_t(3) . "\$" . $name + $fix .= PHP_EOL . Indent::_(2) . "{"; + $fix .= PHP_EOL . Indent::_(3) . "\$" . $name . "Array = array("; $counter = 0; foreach ($values as $value => $translang) @@ -22920,32 +21069,32 @@ class Interpretation extends Fields } if ($counter == 0) { - $fix .= PHP_EOL . $this->_t(4) . $key . " => '" + $fix .= PHP_EOL . Indent::_(4) . $key . " => '" . $translang . "'"; } else { - $fix .= "," . PHP_EOL . $this->_t(4) . $key + $fix .= "," . PHP_EOL . Indent::_(4) . $key . " => '" . $translang . "'"; } $counter++; } - $fix .= PHP_EOL . $this->_t(3) . ");"; - $fix .= PHP_EOL . $this->_t(3) . "//" . $this->setLine( - __LINE__ + $fix .= PHP_EOL . Indent::_(3) . ");"; + $fix .= PHP_EOL . Indent::_(3) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Now check if value is found in this array"; - $fix .= PHP_EOL . $this->_t(3) . "if (isset(\$" . $name + $fix .= PHP_EOL . Indent::_(3) . "if (isset(\$" . $name . "Array[\$value]) && " . $Component . "Helper::checkString(\$" . $name . "Array[\$value]))"; - $fix .= PHP_EOL . $this->_t(3) . "{"; - $fix .= PHP_EOL . $this->_t(4) . "return \$" . $name + $fix .= PHP_EOL . Indent::_(3) . "{"; + $fix .= PHP_EOL . Indent::_(4) . "return \$" . $name . "Array[\$value];"; - $fix .= PHP_EOL . $this->_t(3) . "}"; - $fix .= PHP_EOL . $this->_t(2) . "}"; + $fix .= PHP_EOL . Indent::_(3) . "}"; + $fix .= PHP_EOL . Indent::_(2) . "}"; } } - $fix .= PHP_EOL . $this->_t(2) . "return \$value;"; - $fix .= PHP_EOL . $this->_t(1) . "}"; + $fix .= PHP_EOL . Indent::_(2) . "return \$value;"; + $fix .= PHP_EOL . Indent::_(1) . "}"; } return $fix; @@ -22953,16 +21102,16 @@ class Interpretation extends Fields public function setRouterCase($viewsCodeName) { - if (strlen($viewsCodeName) > 0) + if (strlen((string) $viewsCodeName) > 0) { - $router = PHP_EOL . $this->_t(2) . "case '" . $viewsCodeName . "':"; - $router .= PHP_EOL . $this->_t(3) + $router = PHP_EOL . Indent::_(2) . "case '" . $viewsCodeName . "':"; + $router .= PHP_EOL . Indent::_(3) . "\$id = explode(':', \$segments[\$count-1]);"; - $router .= PHP_EOL . $this->_t(3) . "\$vars['id'] = (int) \$id[0];"; - $router .= PHP_EOL . $this->_t(3) . "\$vars['view'] = '" + $router .= PHP_EOL . Indent::_(3) . "\$vars['id'] = (int) \$id[0];"; + $router .= PHP_EOL . Indent::_(3) . "\$vars['view'] = '" . $viewsCodeName . "';"; - $router .= PHP_EOL . $this->_t(2) . "break;"; + $router .= PHP_EOL . Indent::_(2) . "break;"; return $router; } @@ -22975,7 +21124,7 @@ class Interpretation extends Fields $type = ComponentbuilderHelper::imageInfo($path); if ($type) { - $imagePath = $this->componentPath . '/admin/assets/images'; + $imagePath = CFactory::_('Utilities.Paths')->component_path . '/admin/assets/images'; // move the image to its place File::copy( JPATH_SITE . '/' . $path, @@ -22994,34 +21143,17 @@ class Interpretation extends Fields public function setDashboardIconAccess() { - if (isset($this->permissionDashboard) - && ArrayHelper::check($this->permissionDashboard)) - { - $this->permissionDashboard = array_unique( - $this->permissionDashboard - ); - - return PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) - . " view access array" . PHP_EOL . $this->_t(2) - . "\$viewAccess = array(" . PHP_EOL . $this->_t(3) . implode( - "," . PHP_EOL . $this->_t(3), $this->permissionDashboard - ) . ");"; - } - - return ''; + return CFactory::_('Compiler.Builder.Permission.Dashboard')->build(); } public function setDashboardIcons() { - if (isset($this->componentData->admin_views) - && ArrayHelper::check( - $this->componentData->admin_views - )) + if (CFactory::_('Component')->isArray('admin_views')) { $icons = ''; $counter = 0; $catArray = array(); - foreach ($this->componentData->admin_views as $view) + foreach (CFactory::_('Component')->get('admin_views') as $view) { $name_single = StringHelper::safe( $view['settings']->name_single @@ -23066,7 +21198,7 @@ class Interpretation extends Fields $view['settings']->name_single, 'U' ) . '_ADD'; // add to lang - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); $counter++; } if (isset($view['dashboard_list']) @@ -23103,25 +21235,21 @@ class Interpretation extends Fields $view['settings']->name_list, 'U' ); // add to lang - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); $counter++; } // dashboard link to category on dashboard is build here - if (isset($this->categoryBuilder[$name_list]) - && ArrayHelper::check( - $this->categoryBuilder[$name_list] - )) + if (CFactory::_('Compiler.Builder.Category')->exists("{$name_list}.code")) { - $catCode = $this->categoryBuilder[$name_list]['code']; + $catCode = CFactory::_('Compiler.Builder.Category')->get("{$name_list}.code"); // check if category has another name - if (isset($this->catOtherName[$name_list]) - && ArrayHelper::check( - $this->catOtherName[$name_list] - )) + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($name_list . '.views', $name_list); + $otherNames = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($name_list . '.name'); + if ($otherNames !== null) { - $otherViews = $this->catOtherName[$name_list]['views']; - $otherNames = $this->catOtherName[$name_list]['name']; // build lang $langName = StringHelper::safe( $otherNames, 'W' @@ -23129,7 +21257,6 @@ class Interpretation extends Fields } else { - $otherViews = $name_list; // build lang $langName = 'Categories For
' . StringHelper::safe( @@ -23142,7 +21269,7 @@ class Interpretation extends Fields // set the extension key string, new convention (more stable) $_key_extension = str_replace( '.', '_po0O0oq_', - $this->categoryBuilder[$name_list]['extension'] + (string) CFactory::_('Compiler.Builder.Category')->get("{$name_list}.extension", 'error') ); // add to lang @@ -23152,7 +21279,7 @@ class Interpretation extends Fields ) . '_' . StringHelper::safe( $catCode, 'U' ); - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); // get image type $type = ComponentbuilderHelper::imageInfo( $view['settings']->icon_category @@ -23202,11 +21329,11 @@ class Interpretation extends Fields $this->iconBuilder )) { - $imagePath = $this->componentPath + $imagePath = CFactory::_('Utilities.Paths')->component_path . '/admin/assets/images/icons'; foreach ($this->iconBuilder as $icon => $path) { - $array_buket = explode('.', $icon); + $array_buket = explode('.', (string) $icon); if (count((array) $array_buket) == 3) { list($type, $name, $action) = $array_buket; @@ -23240,22 +21367,20 @@ class Interpretation extends Fields public function setDashboardModelMethods() { - if (isset($this->componentData->php_dashboard_methods) - && StringHelper::check( - $this->componentData->php_dashboard_methods - )) + if (CFactory::_('Component')->isString('php_dashboard_methods')) { + // get hte value + $php_dashboard_methods = CFactory::_('Component')->get('php_dashboard_methods'); // get all the mothods that should load date to the view $this->DashboardGetCustomData = GetHelper::allBetween( - $this->componentData->php_dashboard_methods, + $php_dashboard_methods, 'public function get', '()' ); // return the methods - return PHP_EOL . PHP_EOL . $this->setPlaceholders( - $this->componentData->php_dashboard_methods, - $this->placeholders + return PHP_EOL . PHP_EOL . CFactory::_('Placeholder')->update_( + $php_dashboard_methods ); } @@ -23280,8 +21405,8 @@ class Interpretation extends Fields } // return the gets - return PHP_EOL . $this->_t(2) . implode( - PHP_EOL . $this->_t(2), $gets + return PHP_EOL . Indent::_(2) . implode( + PHP_EOL . Indent::_(2), $gets ); } @@ -23294,33 +21419,30 @@ class Interpretation extends Fields $display = array(); $mainAccordianName = 'cPanel'; $builder = array(); - $tab = $this->_t(1); + $tab = Indent::_(1); $loadTabs = false; // check if we have custom tabs - if (isset($this->componentData->dashboard_tab) - && ArrayHelper::check( - $this->componentData->dashboard_tab - )) + if (CFactory::_('Component')->isArray('dashboard_tab')) { // build the tabs and accordians - foreach ($this->componentData->dashboard_tab as $data) + foreach (CFactory::_('Component')->get('dashboard_tab') as $data) { $builder[$data['name']][$data['header']] - = $this->setPlaceholders( - $data['html'], $this->placeholders + = CFactory::_('Placeholder')->update_( + $data['html'] ); } // since we have custom tabs we must load the tab structure around the cpanel $display[] = '
'; - $display[] = $this->_t(1) . '
'; - $display[] = $this->_t(1) + $display[] = Indent::_(1) . '
'; + $display[] = Indent::_(1) . " 'cpanel')); ?>"; - $display[] = PHP_EOL . $this->_t(2) + $display[] = PHP_EOL . Indent::_(2) . ""; - $display[] = $this->_t(2) . '
'; + $display[] = Indent::_(2) . '
'; // set the tab to insure correct spacing - $tab = $this->_t(3); + $tab = Indent::_(3); // change the name of the main tab $mainAccordianName = 'Control Panel'; $loadTabs = true; @@ -23331,49 +21453,49 @@ class Interpretation extends Fields } // set dashboard display $display[] = $tab . '
'; - $display[] = $tab . $this->_t(1) + $display[] = $tab . Indent::_(1) . " 'main')); ?>"; - $display[] = $tab . $this->_t(2) + $display[] = $tab . Indent::_(2) . ""; - $display[] = $tab . $this->_t(3) + $display[] = $tab . Indent::_(3) . "loadTemplate('main');?>"; - $display[] = $tab . $this->_t(2) + $display[] = $tab . Indent::_(2) . ""; - $display[] = $tab . $this->_t(1) + $display[] = $tab . Indent::_(1) . ""; $display[] = $tab . "
"; $display[] = $tab . '
'; - $display[] = $tab . $this->_t(1) + $display[] = $tab . Indent::_(1) . " 'vdm')); ?>"; - $display[] = $tab . $this->_t(2) + $display[] = $tab . Indent::_(2) . "fileContentStatic[$this->hhh . 'COMPANYNAME' . $this->hhh] + . CFactory::_('Compiler.Builder.Content.One')->get('COMPANYNAME') . "', 'vdm'); ?>"; - $display[] = $tab . $this->_t(3) + $display[] = $tab . Indent::_(3) . "loadTemplate('vdm');?>"; - $display[] = $tab . $this->_t(2) + $display[] = $tab . Indent::_(2) . ""; - $display[] = $tab . $this->_t(1) + $display[] = $tab . Indent::_(1) . ""; $display[] = $tab . "
"; if ($loadTabs) { - $display[] = $this->_t(2) . "
"; - $display[] = $this->_t(2) + $display[] = Indent::_(2) . "
"; + $display[] = Indent::_(2) . ""; // load the new tabs foreach ($builder as $tabname => $accordians) { $alias = StringHelper::safe($tabname); - $display[] = PHP_EOL . $this->_t(2) + $display[] = PHP_EOL . Indent::_(2) . ""; - $display[] = $this->_t(2) . '
'; + $display[] = Indent::_(2) . '
'; $display[] = $tab . '
'; - $display[] = $tab . $this->_t(1) + $display[] = $tab . Indent::_(1) . " '" . $alias . "_one')); ?>"; @@ -23387,45 +21509,39 @@ class Interpretation extends Fields $slidecounter ); $tempName = $alias . '_' . $ac_alias; - $display[] = $tab . $this->_t(2) + $display[] = $tab . Indent::_(2) . ""; - $display[] = $tab . $this->_t(3) + $display[] = $tab . Indent::_(3) . "loadTemplate('" . $tempName . "');?>"; - $display[] = $tab . $this->_t(2) + $display[] = $tab . Indent::_(2) . ""; $slidecounter++; // build the template file - $target = array('custom_admin' => $this->componentCodeName); - $this->buildDynamique($target, 'template', $tempName); + $target = array('custom_admin' => CFactory::_('Config')->component_code_name); + CFactory::_('Utilities.Structure')->build($target, 'template', $tempName); // set the file data $TARGET = StringHelper::safe( - $this->target, 'U' + CFactory::_('Config')->build_target, 'U' ); // SITE_TEMPLATE_BODY <<>> - $this->fileContentDynamic[$this->componentCodeName . '_' - . $tempName][$this->hhh . 'CUSTOM_ADMIN_TEMPLATE_BODY' - . $this->hhh] - = PHP_EOL . $html; + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '_' . $tempName . '|CUSTOM_ADMIN_TEMPLATE_BODY', PHP_EOL . $html); // SITE_TEMPLATE_CODE_BODY <<>> - $this->fileContentDynamic[$this->componentCodeName . '_' - . $tempName][$this->hhh . 'CUSTOM_ADMIN_TEMPLATE_CODE_BODY' - . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '_' . $tempName . '|CUSTOM_ADMIN_TEMPLATE_CODE_BODY', ''); } - $display[] = $tab . $this->_t(1) + $display[] = $tab . Indent::_(1) . ""; $display[] = $tab . "
"; - $display[] = $this->_t(2) . "
"; - $display[] = $this->_t(2) + $display[] = Indent::_(2) . "
"; + $display[] = Indent::_(2) . ""; } - $display[] = PHP_EOL . $this->_t(1) + $display[] = PHP_EOL . Indent::_(1) . ""; - $display[] = $this->_t(1) . "
"; + $display[] = Indent::_(1) . "
"; } $display[] = "
"; @@ -23436,12 +21552,9 @@ class Interpretation extends Fields public function addCustomDashboardIcons(&$view, &$counter) { $icon = ''; - if (isset($this->componentData->custom_admin_views) - && ArrayHelper::check( - $this->componentData->custom_admin_views - )) + if (CFactory::_('Component')->isArray('custom_admin_views')) { - foreach ($this->componentData->custom_admin_views as $nr => $menu) + foreach (CFactory::_('Component')->get('custom_admin_views') as $nr => $menu) { if (!isset($this->customAdminAdded[$menu['settings']->code]) && isset($menu['dashboard_list']) @@ -23467,7 +21580,7 @@ class Interpretation extends Fields $langKey = $this->langPrefix . '_DASHBOARD_' . $menu['settings']->CODE; // add to lang - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); // set icon if ($counter == 0) { @@ -23504,7 +21617,7 @@ class Interpretation extends Fields $langKey = $this->langPrefix . '_DASHBOARD_' . $menu['settings']->CODE; // add to lang - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); // set icon $this->lastCustomDashboardIcon[$nr] = ", '" . $type . $menu['settings']->code . "'"; @@ -23512,12 +21625,9 @@ class Interpretation extends Fields } } // see if we should have custom menus - if (isset($this->componentData->custommenus) - && ArrayHelper::check( - $this->componentData->custommenus - )) + if (CFactory::_('Component')->isArray('custommenus')) { - foreach ($this->componentData->custommenus as $nr => $menu) + foreach (CFactory::_('Component')->get('custommenus') as $nr => $menu) { $nr = $nr + 100; $nameList = StringHelper::safe( @@ -23547,7 +21657,7 @@ class Interpretation extends Fields $langName = $menu['name'] . '

'; $langKey = $this->langPrefix . '_DASHBOARD_' . $nameUpper; // add to lang - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); // if this is a link build the icon values with pipe if (isset($menu['link']) @@ -23603,7 +21713,7 @@ class Interpretation extends Fields $langName = $menu['name'] . '

'; $langKey = $this->langPrefix . '_DASHBOARD_' . $nameUpper; // add to lang - $this->setLangContent($this->lang, $langKey, $langName); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langKey, $langName); // if this is a link build the icon values with pipe if (isset($menu['link']) @@ -23628,30 +21738,27 @@ class Interpretation extends Fields public function setSubMenus() { - if (isset($this->componentData->admin_views) - && ArrayHelper::check( - $this->componentData->admin_views - )) + if (CFactory::_('Component')->isArray('admin_views')) { $menus = ''; // main lang prefix $lang = $this->langPrefix . '_SUBMENU'; // set the code name - $codeName = $this->componentCodeName; + $codeName = CFactory::_('Config')->component_code_name; // set default dashboard - if (!StringHelper::check($this->dynamicDashboard)) + if (!CFactory::_('Registry')->get('build.dashboard')) { $menus .= "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_DASHBOARD'), 'index.php?option=com_" . $codeName . "&view=" . $codeName . "', \$submenu === '" . $codeName . "');"; - $this->setLangContent( - $this->lang, $lang . '_DASHBOARD', 'Dashboard' + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DASHBOARD', 'Dashboard' ); } $catArray = array(); // loop over all the admin views - foreach ($this->componentData->admin_views as $view) + foreach (CFactory::_('Component')->get('admin_views') as $view) { // set custom menu $menus .= $this->addCustomSubMenu( @@ -23667,67 +21774,41 @@ class Interpretation extends Fields { // setup access defaults $tab = ""; - $coreLoad = false; - if (isset($this->permissionCore[$nameSingleCode])) - { - $core = $this->permissionCore[$nameSingleCode]; - $coreLoad = true; - } // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingleCode, 'core.access')) { - $menus .= PHP_EOL . $this->_t(2) - . "if (\$user->authorise('" . $core['core.access'] + $menus .= PHP_EOL . Indent::_(2) + . "if (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.access') . "', 'com_" . $codeName . "') && \$user->authorise('" . $nameSingleCode . ".submenu', 'com_" . $codeName . "'))"; - $menus .= PHP_EOL . $this->_t(2) . "{"; + $menus .= PHP_EOL . Indent::_(2) . "{"; // add tab to lines to follow - $tab = $this->_t(1); + $tab = Indent::_(1); } - $menus .= PHP_EOL . $this->_t(2) . $tab + $menus .= PHP_EOL . Indent::_(2) . $tab . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "'), 'index.php?option=com_" . $codeName . "&view=" . $nameListCode . "', \$submenu === '" . $nameListCode . "');"; - $this->setLangContent( - $this->lang, $lang . "_" . $nameUpper, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . "_" . $nameUpper, $view['settings']->name_list ); // check if category has another name - if (isset($this->catOtherName[$nameListCode]) - && ArrayHelper::check( - $this->catOtherName[$nameListCode] - )) - { - $otherViews - = $this->catOtherName[$nameListCode]['views']; - } - else - { - $otherViews = $nameListCode; - } + $otherViews = CFactory::_('Compiler.Builder.Category.Other.Name')-> + get($nameListCode . '.views', $nameListCode); // first check if category sub-menu should be added // then check if view has category, if true add sub-menu for it if ($view['settings']->add_category_submenu == 1 - && isset($this->categoryBuilder[$nameListCode]) - && ArrayHelper::check( - $this->categoryBuilder[$nameListCode] - ) + && CFactory::_('Compiler.Builder.Category')->exists("{$nameListCode}.extension") && !in_array($otherViews, $catArray)) { // get the extension array $_extension_array = (array) explode( '.', - $this->categoryBuilder[$nameListCode]['extension'] + (string) CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension") ); // set the menu selection if (isset($_extension_array[1])) @@ -23739,55 +21820,47 @@ class Interpretation extends Fields $_menu = "categories"; } // now load the menus - $menus .= PHP_EOL . $this->_t(2) . $tab + $menus .= PHP_EOL . Indent::_(2) . $tab . "JHtmlSidebar::addEntry(JText:" . ":_('" - . $this->categoryBuilder[$nameListCode]['name'] + . CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.name", 'error') . "'), 'index.php?option=com_categories&view=categories&extension=" - . $this->categoryBuilder[$nameListCode]['extension'] + . CFactory::_('Compiler.Builder.Category')->get("{$nameListCode}.extension") . "', \$submenu === '" . $_menu . "');"; // make sure we add a category only once $catArray[] = $otherViews; } // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $nameSingleCode, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingleCode, 'core.access')) { - $menus .= PHP_EOL . $this->_t(2) . "}"; + $menus .= PHP_EOL . Indent::_(2) . "}"; } } // set the Joomla custom fields options if (isset($view['joomla_fields']) && $view['joomla_fields'] == 1) { - $menus .= PHP_EOL . $this->_t(2) + $menus .= PHP_EOL . Indent::_(2) . "if (JComponentHelper::isEnabled('com_fields'))"; - $menus .= PHP_EOL . $this->_t(2) . "{"; - $menus .= PHP_EOL . $this->_t(3) + $menus .= PHP_EOL . Indent::_(2) . "{"; + $menus .= PHP_EOL . Indent::_(3) . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "_FIELDS'), 'index.php?option=com_fields&context=com_" . $codeName . "." . $nameSingleCode . "', \$submenu === 'fields.fields');"; - $menus .= PHP_EOL . $this->_t(3) + $menus .= PHP_EOL . Indent::_(3) . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "_FIELDS_GROUPS'), 'index.php?option=com_fields&view=groups&context=com_" . $codeName . "." . $nameSingleCode . "', \$submenu === 'fields.groups');"; - $menus .= PHP_EOL . $this->_t(2) . "}"; - $this->setLangContent( - $this->lang, $lang . "_" . $nameUpper . "_FIELDS", + $menus .= PHP_EOL . Indent::_(2) . "}"; + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . "_" . $nameUpper . "_FIELDS", $view['settings']->name_list . ' Fields' ); - $this->setLangContent( - $this->lang, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . "_" . $nameUpper . "_FIELDS_GROUPS", $view['settings']->name_list . ' Field Groups' ); @@ -23795,7 +21868,7 @@ class Interpretation extends Fields $this->uninstallScriptBuilder[$nameSingleCode] = 'com_' . $codeName . '.' . $nameSingleCode; $this->uninstallScriptFields[$nameSingleCode] - = $nameSingleCode; + = $nameSingleCode; } } if (isset($this->lastCustomSubMenu) @@ -23818,12 +21891,9 @@ class Interpretation extends Fields { // see if we should have custom menus $custom = ''; - if (isset($this->componentData->custom_admin_views) - && ArrayHelper::check( - $this->componentData->custom_admin_views - )) + if (CFactory::_('Component')->isArray('custom_admin_views')) { - foreach ($this->componentData->custom_admin_views as $nr => $menu) + foreach (CFactory::_('Component')->get('custom_admin_views') as $nr => $menu) { if (!isset($this->customAdminAdded[$menu['settings']->code])) { @@ -23836,12 +21906,9 @@ class Interpretation extends Fields } } } - if (isset($this->componentData->custommenus) - && ArrayHelper::check( - $this->componentData->custommenus - )) + if (CFactory::_('Component')->isArray('custommenus')) { - foreach ($this->componentData->custommenus as $nr => $menu) + foreach (CFactory::_('Component')->get('custommenus') as $nr => $menu) { if (($_custom = $this->setCustomAdminSubMenu( $view, $codeName, $lang, $nr, $menu, 'customMenu' @@ -23880,47 +21947,32 @@ class Interpretation extends Fields { // setup access defaults $tab = ""; - - $coreLoad = false; - if (isset($this->permissionCore[$nameSingle])) - { - $core = $this->permissionCore[$nameSingle]; - $coreLoad = true; - } $custom = ''; // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $nameSingle, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingle, 'core.access')) { - $custom .= PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ - ) . " Access control (" . $core['core.access'] . " && " + $custom .= PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " Access control (" . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingle, 'core.access') . " && " . $nameSingle . ".submenu)."; - $custom .= PHP_EOL . $this->_t(2) . "if (\$user->authorise('" - . $core['core.access'] . "', 'com_" . $codeName + $custom .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('" + . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingle, 'core.access') . "', 'com_" . $codeName . "') && \$user->authorise('" . $nameSingle . ".submenu', 'com_" . $codeName . "'))"; - $custom .= PHP_EOL . $this->_t(2) . "{"; + $custom .= PHP_EOL . Indent::_(2) . "{"; // add tab to lines to follow - $tab = $this->_t(1); + $tab = Indent::_(1); } else { - $custom .= PHP_EOL . $this->_t(2) . "//" . $this->setLine( - __LINE__ + $custom .= PHP_EOL . Indent::_(2) . "//" . Line::_( + __LINE__,__CLASS__ ) . " Access control (" . $nameSingle . ".submenu)."; - $custom .= PHP_EOL . $this->_t(2) . "if (\$user->authorise('" + $custom .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('" . $nameSingle . ".submenu', 'com_" . $codeName . "'))"; - $custom .= PHP_EOL . $this->_t(2) . "{"; + $custom .= PHP_EOL . Indent::_(2) . "{"; // add tab to lines to follow - $tab = $this->_t(1); + $tab = Indent::_(1); } if (isset($menu['link']) && StringHelper::check( @@ -23928,29 +21980,29 @@ class Interpretation extends Fields )) { - $this->setLangContent( - $this->lang, $lang . '_' . $nameUpper, $name + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_' . $nameUpper, $name ); // add custom menu - $custom .= PHP_EOL . $this->_t(2) . $tab + $custom .= PHP_EOL . Indent::_(2) . $tab . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "'), '" . $menu['link'] . "', \$submenu === '" . $nameList . "');"; } else { - $this->setLangContent( - $this->lang, $lang . '_' . $nameUpper, $name + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_' . $nameUpper, $name ); // add custom menu - $custom .= PHP_EOL . $this->_t(2) . $tab + $custom .= PHP_EOL . Indent::_(2) . $tab . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "'), 'index.php?option=com_" . $codeName . "&view=" . $nameList . "', \$submenu === '" . $nameList . "');"; } // check if the item has permissions. - $custom .= PHP_EOL . $this->_t(2) . "}"; + $custom .= PHP_EOL . Indent::_(2) . "}"; return $custom; } @@ -23960,69 +22012,55 @@ class Interpretation extends Fields // setup access defaults $tab = ""; $nameSingle = StringHelper::safe($name); - $coreLoad = false; - if (isset($this->permissionCore[$nameSingle])) - { - $core = $this->permissionCore[$nameSingle]; - $coreLoad = true; - } $this->lastCustomSubMenu[$nr] = ''; // check if the item has permissions. - if ($coreLoad && isset($core['core.access']) - && isset($this->permissionBuilder['global'][$core['core.access']]) - && ArrayHelper::check( - $this->permissionBuilder['global'][$core['core.access']] - ) - && in_array( - $nameSingle, - $this->permissionBuilder['global'][$core['core.access']] - )) + if (CFactory::_('Compiler.Creator.Permission')->globalExist($nameSingle, 'core.access')) { - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) - . "if (\$user->authorise('" . $core['core.access'] + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) + . "if (\$user->authorise('" . CFactory::_('Compiler.Creator.Permission')->getGlobal($nameSingle, 'core.access') . "', 'com_" . $codeName . "') && \$user->authorise('" . $nameSingle . ".submenu', 'com_" . $codeName . "'))"; - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) . "{"; + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) . "{"; // add tab to lines to follow - $tab = $this->_t(1); + $tab = Indent::_(1); } else { - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) . "if (\$user->authorise('" . $nameSingle . ".submenu', 'com_" . $codeName . "'))"; - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) . "{"; + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) . "{"; // add tab to lines to follow - $tab = $this->_t(1); + $tab = Indent::_(1); } if (isset($menu['link']) && StringHelper::check( $menu['link'] )) { - $this->setLangContent( - $this->lang, $lang . '_' . $nameUpper, $name + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_' . $nameUpper, $name ); // add custom menu - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) . $tab + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) . $tab . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "'), '" . $menu['link'] . "', \$submenu === '" . $nameList . "');"; } else { - $this->setLangContent( - $this->lang, $lang . '_' . $nameUpper, $name + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_' . $nameUpper, $name ); // add custom menu - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) . $tab + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) . $tab . "JHtmlSidebar::addEntry(JText:" . ":_('" . $lang . "_" . $nameUpper . "'), 'index.php?option=com_" . $codeName . "&view=" . $nameList . "', \$submenu === '" . $nameList . "');"; } // check if the item has permissions. - $this->lastCustomSubMenu[$nr] .= PHP_EOL . $this->_t(2) . "}"; + $this->lastCustomSubMenu[$nr] .= PHP_EOL . Indent::_(2) . "}"; } return false; @@ -24030,32 +22068,23 @@ class Interpretation extends Fields public function setMainMenus() { - if (isset($this->componentData->admin_views) - && ArrayHelper::check( - $this->componentData->admin_views - )) + if (CFactory::_('Component')->isArray('admin_views')) { $menus = ''; // main lang prefix $lang = $this->langPrefix . '_MENU'; // set the code name - $codeName = $this->componentCodeName; + $codeName = CFactory::_('Config')->component_code_name; // default prefix is none $prefix = ''; // check if local is set - if (isset($this->componentData->add_menu_prefix) - && is_numeric( - $this->componentData->add_menu_prefix - )) + if (CFactory::_('Component')->isNumeric('add_menu_prefix')) { // set main menu prefix switch - $addPrefix = $this->componentData->add_menu_prefix; - if ($addPrefix == 1 && isset($this->componentData->menu_prefix) - && StringHelper::check( - $this->componentData->menu_prefix - )) + $addPrefix = CFactory::_('Component')->get('add_menu_prefix'); + if ($addPrefix == 1 && CFactory::_('Component')->isString('menu_prefix')) { - $prefix = trim($this->componentData->menu_prefix) . ' '; + $prefix = trim((string) CFactory::_('Component')->get('menu_prefix')) . ' '; } } else @@ -24064,25 +22093,25 @@ class Interpretation extends Fields $addPrefix = $this->params->get('add_menu_prefix', 1); if ($addPrefix == 1) { - $prefix = trim($this->params->get('menu_prefix', '»')) + $prefix = trim((string) $this->params->get('menu_prefix', '»')) . ' '; } } // add the prefix if ($addPrefix == 1) { - $this->setLangContent( - 'adminsys', $lang, $prefix . $this->componentData->name + CFactory::_('Language')->set( + 'adminsys', $lang, $prefix . CFactory::_('Component')->get('name') ); } else { - $this->setLangContent( - 'adminsys', $lang, $this->componentData->name + CFactory::_('Language')->set( + 'adminsys', $lang, CFactory::_('Component')->get('name') ); } // loop over the admin views - foreach ($this->componentData->admin_views as $view) + foreach (CFactory::_('Component')->get('admin_views') as $view) { // set custom menu $menus .= $this->addCustomMainMenu($view, $codeName, $lang); @@ -24094,10 +22123,10 @@ class Interpretation extends Fields $nameUpper = StringHelper::safe( $view['settings']->name_list, 'U' ); - $menus .= PHP_EOL . $this->_t(3) . '' . $lang . '_' . $nameUpper . ''; - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $nameUpper, $view['settings']->name_list ); @@ -24125,24 +22154,21 @@ class Interpretation extends Fields { $customMenu = ''; // see if we should have custom admin views - if (isset($this->componentData->custom_admin_views) - && ArrayHelper::check( - $this->componentData->custom_admin_views - )) + if (CFactory::_('Component')->isArray('custom_admin_views')) { - foreach ($this->componentData->custom_admin_views as $nr => $menu) + foreach (CFactory::_('Component')->get('custom_admin_views') as $nr => $menu) { if (!isset($this->customAdminAdded[$menu['settings']->code])) { if (isset($menu['mainmenu']) && $menu['mainmenu'] == 1 && $view['adminview'] == $menu['before']) { - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $menu['settings']->CODE, $menu['settings']->name ); // add custom menu - $customMenu .= PHP_EOL . $this->_t(3) + $customMenu .= PHP_EOL . Indent::_(3) . '' . $lang . '_' . $menu['settings']->CODE . ''; @@ -24150,12 +22176,12 @@ class Interpretation extends Fields elseif (isset($menu['mainmenu']) && $menu['mainmenu'] == 1 && empty($menu['before'])) { - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $menu['settings']->CODE, $menu['settings']->name ); // add custom menu - $this->lastCustomMainMenu[$nr] = PHP_EOL . $this->_t(3) + $this->lastCustomMainMenu[$nr] = PHP_EOL . Indent::_(3) . '' . $lang . '_' . $menu['settings']->CODE . ''; @@ -24164,12 +22190,9 @@ class Interpretation extends Fields } } // see if we should have custom menus - if (isset($this->componentData->custommenus) - && ArrayHelper::check( - $this->componentData->custommenus - )) + if (CFactory::_('Component')->isArray('custommenus')) { - foreach ($this->componentData->custommenus as $nr => $menu) + foreach (CFactory::_('Component')->get('custommenus') as $nr => $menu) { $nr = $nr + 100; if (isset($menu['mainmenu']) && $menu['mainmenu'] == 1 @@ -24184,14 +22207,14 @@ class Interpretation extends Fields $nameUpper = StringHelper::safe( $menu['name'], 'U' ); - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $nameUpper, $menu['name'] ); // sanitize url - if (strpos($menu['link'], 'http') === false) + if (strpos((string) $menu['link'], 'http') === false) { $menu['link'] = str_replace( - '/administrator/index.php?', '', $menu['link'] + '/administrator/index.php?', '', (string) $menu['link'] ); $menu['link'] = str_replace( 'administrator/index.php?', '', $menu['link'] @@ -24209,10 +22232,10 @@ class Interpretation extends Fields } // urlencode $menu['link'] = htmlspecialchars( - $menu['link'], ENT_XML1, 'UTF-8' + (string) $menu['link'], ENT_XML1, 'UTF-8' ); // add custom menu - $customMenu .= PHP_EOL . $this->_t(3) . '' . $lang . '_' . $nameUpper . ''; } @@ -24224,11 +22247,11 @@ class Interpretation extends Fields $nameUpper = StringHelper::safe( $menu['name_code'], 'U' ); - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $nameUpper, $menu['name'] ); // add custom menu - $customMenu .= PHP_EOL . $this->_t(3) + $customMenu .= PHP_EOL . Indent::_(3) . '' . $lang . '_' . $nameUpper . ''; @@ -24246,14 +22269,14 @@ class Interpretation extends Fields $nameUpper = StringHelper::safe( $menu['name'], 'U' ); - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $nameUpper, $menu['name'] ); // sanitize url - if (strpos($menu['link'], 'http') === false) + if (strpos((string) $menu['link'], 'http') === false) { $menu['link'] = str_replace( - '/administrator/index.php?', '', $menu['link'] + '/administrator/index.php?', '', (string) $menu['link'] ); $menu['link'] = str_replace( 'administrator/index.php?', '', $menu['link'] @@ -24271,10 +22294,10 @@ class Interpretation extends Fields } // urlencode $menu['link'] = htmlspecialchars( - $menu['link'], ENT_XML1, 'UTF-8' + (string) $menu['link'], ENT_XML1, 'UTF-8' ); // add custom menu - $this->lastCustomMainMenu[$nr] = PHP_EOL . $this->_t(3) + $this->lastCustomMainMenu[$nr] = PHP_EOL . Indent::_(3) . '' . $lang . '_' . $nameUpper . ''; } @@ -24286,11 +22309,11 @@ class Interpretation extends Fields $nameUpper = StringHelper::safe( $menu['name_code'], 'U' ); - $this->setLangContent( + CFactory::_('Language')->set( 'adminsys', $lang . '_' . $nameUpper, $menu['name'] ); // add custom menu - $this->lastCustomMainMenu[$nr] = PHP_EOL . $this->_t(3) + $this->lastCustomMainMenu[$nr] = PHP_EOL . Indent::_(3) . '' . $lang . '_' . $nameUpper . ''; @@ -24306,86 +22329,79 @@ class Interpretation extends Fields { // main lang prefix $lang = $this->langPrefix . '_CONFIG'; + // for plugin event TODO change event api signatures + $component_context = CFactory::_('Config')->component_context; if (1 == $timer) // this is before the admin views are build { // start loading Global params $autorName = StringHelper::html( - $this->componentData->author + CFactory::_('Component')->get('author') ); $autorEmail = StringHelper::html( - $this->componentData->email + CFactory::_('Component')->get('email') ); $this->extensionsParams[] = '"autorName":"' . $autorName . '","autorEmail":"' . $autorEmail . '"'; // set the custom fields - if (isset($this->componentData->config) - && ArrayHelper::check( - $this->componentData->config - )) + if (CFactory::_('Component')->isArray('config')) { // set component code name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; $nameSingleCode = 'config'; $nameListCode = 'configs'; // set place holders $placeholders = array(); - $placeholders[$this->hhh . 'component' . $this->hhh] - = $this->componentCodeName; - $placeholders[$this->hhh . 'Component' . $this->hhh] - = StringHelper::safe( - $this->componentData->name_code, 'F' + $placeholders[Placefix::_h('component')] + = CFactory::_('Config')->component_code_name; + $placeholders[Placefix::_h('Component')] + = StringHelper::safe( + CFactory::_('Component')->get('name_code'), 'F' ); - $placeholders[$this->hhh . 'COMPONENT' . $this->hhh] - = StringHelper::safe( - $this->componentData->name_code, 'U' + $placeholders[Placefix::_h('COMPONENT')] + = StringHelper::safe( + CFactory::_('Component')->get('name_code'), 'U' ); - $placeholders[$this->hhh . 'view' . $this->hhh] - = $nameSingleCode; - $placeholders[$this->hhh . 'views' . $this->hhh] - = $nameListCode; - $placeholders[$this->bbb . 'component' . $this->ddd] - = $this->componentCodeName; - $placeholders[$this->bbb . 'Component' . $this->ddd] - = $placeholders[$this->hhh . 'Component' - . $this->hhh]; - $placeholders[$this->bbb . 'COMPONENT' . $this->ddd] - = $placeholders[$this->hhh . 'COMPONENT' - . $this->hhh]; - $placeholders[$this->bbb . 'view' . $this->ddd] - = $nameSingleCode; - $placeholders[$this->bbb . 'views' . $this->ddd] - = $nameListCode; + $placeholders[Placefix::_h('view')] + = $nameSingleCode; + $placeholders[Placefix::_h('views')] + = $nameListCode; + $placeholders[Placefix::_('component')] + = CFactory::_('Config')->component_code_name; + $placeholders[Placefix::_('Component')] + = $placeholders[Placefix::_h('Component')]; + $placeholders[Placefix::_('COMPONENT')] + = $placeholders[Placefix::_h('COMPONENT')]; + $placeholders[Placefix::_('view')] + = $nameSingleCode; + $placeholders[Placefix::_('views')] + = $nameListCode; // load the global placeholders - if (ArrayHelper::check( - $this->globalPlaceholders - )) + foreach (CFactory::_('Component.Placeholder')->get() as $globalPlaceholder => $gloabalValue) { - foreach ( - $this->globalPlaceholders as $globalPlaceholder => - $gloabalValue - ) - { - $placeholders[$globalPlaceholder] = $gloabalValue; - } + $placeholders[$globalPlaceholder] = $gloabalValue; } - $view = ''; + $view = []; $viewType = 0; // set the custom table key $dbkey = 'g'; + // TODO: change plubin signature + $config_ = CFactory::_('Component')->get('config'); // Trigger Event: jcb_ce_onBeforeSetConfigFieldsets - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeSetConfigFieldsets', - array(&$this->componentContext, &$timer, + array(&$component_context, &$timer, &$this->configFieldSets, &$this->configFieldSetsCustomField, - &$this->componentData->config, + &$config_, &$this->extensionsParams, &$placeholders) ); + // update global values + CFactory::_('Component')->set('config', $config_); // build the config fields - foreach ($this->componentData->config as $field) + foreach ($config_ as $field) { // get the xml string - $xmlField = $this->getFieldXMLString( + $xmlField = CFactory::_('Compiler.Creator.Field.As.String')->get( $field, $view, $viewType, $lang, $nameSingleCode, $nameListCode, $placeholders, $dbkey, false ); @@ -24400,13 +22416,13 @@ class Interpretation extends Fields = $xmlField; // set global params to db on install $fieldName = StringHelper::safe( - $this->setPlaceholders( + CFactory::_('Placeholder')->update( GetHelper::between( $xmlField, 'name="', '"' ), $placeholders ) ); - $fieldDefault = $this->setPlaceholders( + $fieldDefault = CFactory::_('Placeholder')->update( GetHelper::between( $xmlField, 'default="', '"' ), $placeholders @@ -24417,8 +22433,8 @@ class Interpretation extends Fields )) { // add array if found - if ((strpos($field['custom_value'], '["') !== false) - && (strpos($field['custom_value'], '"]') + if ((strpos((string) $field['custom_value'], '["') !== false) + && (strpos((string) $field['custom_value'], '"]') !== false)) { // load the Global checkin defautls @@ -24449,15 +22465,20 @@ class Interpretation extends Fields } elseif (2 == $timer) // this is after the admin views are build { + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $config_ = CFactory::_('Component')->get('config'); // Trigger Event: jcb_ce_onBeforeSetConfigFieldsets - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeSetConfigFieldsets', - array(&$this->componentContext, &$timer, + array(&$component_context, &$timer, &$this->configFieldSets, &$this->configFieldSetsCustomField, - &$this->componentData->config, &$this->extensionsParams, - &$this->placeholders) + &$config_, &$this->extensionsParams, + &$placeholders) ); + // update global values + CFactory::_('Component')->set('config', $config_); // these field sets can only be added after admin view is build $this->setGroupControlConfigFieldsets($lang); // these can be added anytime really (but looks best after groups @@ -24468,12 +22489,14 @@ class Interpretation extends Fields // these are the coustom settings $this->setCustomControlConfigFieldsets($lang); } + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; // Trigger Event: jcb_ce_onAfterSetConfigFieldsets - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterSetConfigFieldsets', - array(&$this->componentContext, &$timer, &$this->configFieldSets, + array(&$component_context, &$timer, &$this->configFieldSets, &$this->configFieldSetsCustomField, &$this->extensionsParams, - &$this->frontEndParams, &$this->placeholders) + &$this->frontEndParams, &$placeholders) ); } @@ -24481,13 +22504,10 @@ class Interpretation extends Fields { $front_end = array(); // do quick build of front-end views - if (isset($this->componentData->site_views) - && ArrayHelper::check( - $this->componentData->site_views - )) + if (CFactory::_('Component')->isArray('site_views')) { // load the names only to link the page params - foreach ($this->componentData->site_views as $siteView) + foreach (CFactory::_('Component')->get('site_views') as $siteView) { // now load the view name to the front-end array $front_end[] = $siteView['settings']->name; @@ -24510,7 +22530,7 @@ class Interpretation extends Fields $viewRequest = 'name="' . $tabLower . '_request_id'; foreach ($tabFields as $et => $id_field) { - if (strpos($id_field, $viewRequest) !== false) + if (strpos((string) $id_field, $viewRequest) !== false) { $this->setRequestValues( $tabLower, $id_field, $viewRequest, 'id', @@ -24518,7 +22538,7 @@ class Interpretation extends Fields ); unset($tabFields[$et]); } - elseif (strpos($id_field, '_request_id') !== false) + elseif (strpos((string) $id_field, '_request_id') !== false) { // not loaded to a tab "view" name $_viewRequest = GetHelper::between( @@ -24537,7 +22557,7 @@ class Interpretation extends Fields $viewRequestC = 'name="' . $tabLower . '_request_catid'; foreach ($tabFields as $ci => $catid_field) { - if (strpos($catid_field, $viewRequestC) !== false) + if (strpos((string) $catid_field, $viewRequestC) !== false) { $this->setRequestValues( @@ -24546,7 +22566,7 @@ class Interpretation extends Fields ); unset($tabFields[$ci]); } - elseif (strpos($catid_field, '_request_catid') !== false) + elseif (strpos((string) $catid_field, '_request_catid') !== false) { // not loaded to a tab "view" name $_viewRequestC = GetHelper::between( @@ -24566,12 +22586,12 @@ class Interpretation extends Fields $pageSettings = array(); foreach ($tabFields as $ct => $field) { - if (strpos($field, $menuSetter) !== false) + if (strpos((string) $field, $menuSetter) !== false) { // set the values needed to insure route is done correclty $this->hasMenuGlobal[$tabLower] = $menuSetter; } - elseif (strpos($field, '_menu"') !== false) + elseif (strpos((string) $field, '_menu"') !== false) { // not loaded to a tab "view" name $_tabLower = GetHelper::between( @@ -24602,13 +22622,13 @@ class Interpretation extends Fields // is not having special var $key = $target; // update field - $field = str_replace($search . '"', 'name="' . $key . '"', $field); + $field = str_replace($search . '"', 'name="' . $key . '"', (string) $field); } else { // update field $field = str_replace( - $search . $key . '"', 'name="' . $key . '"', $field + $search . $key . '"', 'name="' . $key . '"', (string) $field ); } if (!isset($this->{$store}[$view])) @@ -24645,7 +22665,7 @@ class Interpretation extends Fields { // remove this display since it is not used in Joomla $bucket[] = str_replace( - 'display="config"', '', $tabField + 'display="config"', '', (string) $tabField ); } } @@ -24653,19 +22673,19 @@ class Interpretation extends Fields if (ArrayHelper::check($bucket)) { // setup lang - $this->setLangContent( - $this->lang, $lang . '_' . $tabUpper, $tab + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_' . $tabUpper, $tab ); // start field set - $this->configFieldSets[] = $this->_t(1) . "configFieldSets[] = $this->_t(2) . 'name="' + $this->configFieldSets[] = Indent::_(1) . "configFieldSets[] = Indent::_(2) . 'name="' . $tabCode . '"'; - $this->configFieldSets[] = $this->_t(2) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'label="' . $lang . '_' . $tabUpper . '">'; // set the fields $this->configFieldSets[] = implode("", $bucket); // close field set - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; } // remove after loading unset($this->configFieldSetsCustomField[$tab]); @@ -24676,42 +22696,39 @@ class Interpretation extends Fields public function setGroupControlConfigFieldsets($lang) { // start loading Group control params if needed - if (isset($this->setGroupControl) - && ArrayHelper::check( - $this->setGroupControl - )) + if (CFactory::_('Compiler.Builder.Field.Group.Control')->isActive()) { // start building field set for config - $this->configFieldSets[] = $this->_t(1) . "configFieldSets[] = $this->_t(2) . 'name="group_config"'; - $this->configFieldSets[] = $this->_t(2) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(1) . "configFieldSets[] = Indent::_(2) . 'name="group_config"'; + $this->configFieldSets[] = Indent::_(2) . 'label="' . $lang . '_GROUPS_LABEL"'; - $this->configFieldSets[] = $this->_t(2) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'description="' . $lang . '_GROUPS_DESC">'; // setup lang - $this->setLangContent( - $this->lang, $lang . '_GROUPS_LABEL', "Target Groups" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_GROUPS_LABEL', "Target Groups" ); - $this->setLangContent( - $this->lang, $lang . '_GROUPS_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_GROUPS_DESC', "The Parameters for the targeted groups are set here." ); - $this->setLangContent( - $this->lang, $lang . '_TARGET_GROUP_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_TARGET_GROUP_DESC', "Set the group/s being targeted by this user type." ); - foreach ($this->setGroupControl as $selector => $label) + foreach (CFactory::_('Compiler.Builder.Field.Group.Control')->allActive() as $selector => $label) { - $this->configFieldSets[] = $this->_t(2) . 'configFieldSets[] = $this->_t(3) . 'type="usergroup"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $label + $this->configFieldSets[] = Indent::_(3) . 'type="usergroup"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $label . '"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_TARGET_GROUP_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'multiple="true"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(3) . 'multiple="true"'; + $this->configFieldSets[] = Indent::_(2) . "/>"; // set params defaults $this->extensionsParams[] = '"' . $selector . '":["2"]'; } @@ -24727,7 +22744,7 @@ class Interpretation extends Fields unset($this->configFieldSetsCustomField['Target Groups']); } // close that fieldse - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; } } @@ -24739,120 +22756,120 @@ class Interpretation extends Fields public function setGlobalConfigFieldsets($lang, $autorName, $autorEmail) { // set component name - $component = $this->componentCodeName; + $component = CFactory::_('Config')->component_code_name; // start building field set for config $this->configFieldSets[] = 'configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'addrulepath="/administrator/components/com_' . $component . '/models/rules"'; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'addfieldpath="/administrator/components/com_' . $component . '/models/fields"'; - $this->configFieldSets[] = $this->_t(2) . 'name="global_config"'; - $this->configFieldSets[] = $this->_t(2) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'name="global_config"'; + $this->configFieldSets[] = Indent::_(2) . 'label="' . $lang . '_GLOBAL_LABEL"'; - $this->configFieldSets[] = $this->_t(2) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'description="' . $lang . '_GLOBAL_DESC">'; // setup lang - $this->setLangContent($this->lang, $lang . '_GLOBAL_LABEL', "Global"); - $this->setLangContent( - $this->lang, $lang . '_GLOBAL_DESC', "The Global Parameters" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_GLOBAL_LABEL', "Global"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_GLOBAL_DESC', "The Global Parameters" ); - // add auto checin if required - if ($this->addCheckin) + // add auto checkin if required + if (CFactory::_('Config')->get('add_checkin', false)) { - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . 'name="check_in"'; - $this->configFieldSets[] = $this->_t(3) . 'type="list"'; - $this->configFieldSets[] = $this->_t(3) . 'default="0"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . 'name="check_in"'; + $this->configFieldSets[] = Indent::_(3) . 'type="list"'; + $this->configFieldSets[] = Indent::_(3) . 'default="0"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_CHECK_TIMER_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_CHECK_TIMER_DESC">'; - $this->configFieldSets[] = $this->_t(3) . 'configFieldSets[] = $this->_t(4) . 'value="-5 hours">' + $this->configFieldSets[] = Indent::_(3) . 'configFieldSets[] = Indent::_(4) . 'value="-5 hours">' . $lang . '_CHECK_TIMER_OPTION_ONE'; - $this->configFieldSets[] = $this->_t(3) . 'configFieldSets[] = $this->_t(4) . 'value="-12 hours">' + $this->configFieldSets[] = Indent::_(3) . 'configFieldSets[] = Indent::_(4) . 'value="-12 hours">' . $lang . '_CHECK_TIMER_OPTION_TWO'; - $this->configFieldSets[] = $this->_t(3) . 'configFieldSets[] = $this->_t(4) . 'value="-1 day">' . $lang + $this->configFieldSets[] = Indent::_(3) . 'configFieldSets[] = Indent::_(4) . 'value="-1 day">' . $lang . '_CHECK_TIMER_OPTION_THREE'; - $this->configFieldSets[] = $this->_t(3) . 'configFieldSets[] = $this->_t(4) . 'value="-2 day">' . $lang + $this->configFieldSets[] = Indent::_(3) . 'configFieldSets[] = Indent::_(4) . 'value="-2 day">' . $lang . '_CHECK_TIMER_OPTION_FOUR'; - $this->configFieldSets[] = $this->_t(3) . 'configFieldSets[] = $this->_t(4) . 'value="-1 week">' . $lang + $this->configFieldSets[] = Indent::_(3) . 'configFieldSets[] = Indent::_(4) . 'value="-1 week">' . $lang . '_CHECK_TIMER_OPTION_FIVE'; - $this->configFieldSets[] = $this->_t(3) . 'configFieldSets[] = $this->_t(4) . 'value="0">' . $lang + $this->configFieldSets[] = Indent::_(3) . 'configFieldSets[] = Indent::_(4) . 'value="0">' . $lang . '_CHECK_TIMER_OPTION_SIX'; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; + $this->configFieldSets[] = Indent::_(2) . ''; // setup lang - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_LABEL', "Check in timer" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_LABEL', "Check in timer" ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_DESC', "Set the intervals for the auto checkin fuction of tables that checks out the items to an user." ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_OPTION_ONE', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_OPTION_ONE', "Every five hours" ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_OPTION_TWO', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_OPTION_TWO', "Every twelve hours" ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_OPTION_THREE', "Once a day" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_OPTION_THREE', "Once a day" ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_OPTION_FOUR', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_OPTION_FOUR', "Every second day" ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_OPTION_FIVE', "Once a week" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_OPTION_FIVE', "Once a week" ); - $this->setLangContent( - $this->lang, $lang . '_CHECK_TIMER_OPTION_SIX', "Never" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHECK_TIMER_OPTION_SIX', "Never" ); // load the Global checkin defautls $this->extensionsParams[] = '"check_in":"-1 day"'; } // set history control - if ($this->setTagHistory) + if (CFactory::_('Config')->get('set_tag_history', false)) { - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . 'name="save_history"'; - $this->configFieldSets[] = $this->_t(3) . 'type="radio"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . 'name="save_history"'; + $this->configFieldSets[] = Indent::_(3) . 'type="radio"'; + $this->configFieldSets[] = Indent::_(3) . 'class="btn-group btn-group-yesno"'; - $this->configFieldSets[] = $this->_t(3) . 'default="1"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'default="1"'; + $this->configFieldSets[] = Indent::_(3) . 'label="JGLOBAL_SAVE_HISTORY_OPTIONS_LABEL"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'description="JGLOBAL_SAVE_HISTORY_OPTIONS_DESC"'; - $this->configFieldSets[] = $this->_t(3) . ">"; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ">"; + $this->configFieldSets[] = Indent::_(3) . ''; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ''; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . 'name="history_limit"'; - $this->configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'filter="integer"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . ""; + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . 'name="history_limit"'; + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'filter="integer"'; + $this->configFieldSets[] = Indent::_(3) . 'label="JGLOBAL_HISTORY_LIMIT_OPTIONS_LABEL"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'description="JGLOBAL_HISTORY_LIMIT_OPTIONS_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'default="10"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(3) . 'default="10"'; + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . ''; // load the Global checkin defautls $this->extensionsParams[] @@ -24870,61 +22887,58 @@ class Interpretation extends Fields unset($this->configFieldSetsCustomField['Global']); } // set the author details - $this->configFieldSets[] = $this->_t(2) . 'configFieldSets[] = $this->_t(3) . 'type="spacer"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = Indent::_(3) . 'type="spacer"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_AUTHOR"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_AUTHOR_NAME_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_AUTHOR_NAME_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' . $autorName + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . $autorName . '"'; - $this->configFieldSets[] = $this->_t(3) . 'readonly="true"'; - $this->configFieldSets[] = $this->_t(3) . 'class="readonly"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . 'configFieldSets[] = $this->_t(3) . 'type="email"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'readonly="true"'; + $this->configFieldSets[] = Indent::_(3) . 'class="readonly"'; + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = Indent::_(3) . 'type="email"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_AUTHOR_EMAIL_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_AUTHOR_EMAIL_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' . $autorEmail + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . $autorEmail . '"'; - $this->configFieldSets[] = $this->_t(3) . 'readonly="true"'; - $this->configFieldSets[] = $this->_t(3) . 'class="readonly"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(3) . 'readonly="true"'; + $this->configFieldSets[] = Indent::_(3) . 'class="readonly"'; + $this->configFieldSets[] = Indent::_(2) . "/>"; // setup lang - $this->setLangContent($this->lang, $lang . '_AUTHOR', "Author Info"); - $this->setLangContent( - $this->lang, $lang . '_AUTHOR_NAME_LABEL', "Author Name" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_AUTHOR', "Author Info"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_AUTHOR_NAME_LABEL', "Author Name" ); - $this->setLangContent( - $this->lang, $lang . '_AUTHOR_NAME_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_AUTHOR_NAME_DESC', "The name of the author of this component." ); - $this->setLangContent( - $this->lang, $lang . '_AUTHOR_EMAIL_LABEL', "Author Email" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_AUTHOR_EMAIL_LABEL', "Author Email" ); - $this->setLangContent( - $this->lang, $lang . '_AUTHOR_EMAIL_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_AUTHOR_EMAIL_DESC', "The email address of the author of this component." ); // set if contributors were added $langCont = $lang . '_CONTRIBUTOR'; - if (isset($this->addContributors) && $this->addContributors - && isset($this->componentData->contributors) - && ArrayHelper::check( - $this->componentData->contributors - )) + if (CFactory::_('Config')->get('add_contributors', false) + && CFactory::_('Component')->isArray('contributors')) { foreach ( - $this->componentData->contributors as $counter => $contributor + CFactory::_('Component')->get('contributors') as $counter => $contributor ) { // make sure we dont use 0 @@ -24933,115 +22947,115 @@ class Interpretation extends Fields $COUNTER = StringHelper::safe($counter, 'U'); // set the dynamic values $cbTitle = htmlspecialchars( - $contributor['title'], ENT_XML1, 'UTF-8' + (string) $contributor['title'], ENT_XML1, 'UTF-8' ); $cbName = htmlspecialchars( - $contributor['name'], ENT_XML1, 'UTF-8' + (string) $contributor['name'], ENT_XML1, 'UTF-8' ); $cbEmail = htmlspecialchars( - $contributor['email'], ENT_XML1, 'UTF-8' + (string) $contributor['email'], ENT_XML1, 'UTF-8' ); $cbWebsite = htmlspecialchars( - $contributor['website'], ENT_XML1, 'UTF-8' + (string) $contributor['website'], ENT_XML1, 'UTF-8' ); // StringHelper::html($contributor['website']); // load to the $fieldsets - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ''; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="spacer"'; - $this->configFieldSets[] = $this->_t(3) . 'class="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="spacer"'; + $this->configFieldSets[] = Indent::_(3) . 'class="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_' . $COUNTER . '"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_TITLE_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_TITLE_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' . $cbTitle + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . $cbTitle . '"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_NAME_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_NAME_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' . $cbName + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . $cbName . '"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="email"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="email"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_EMAIL_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_EMAIL_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' . $cbEmail + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . $cbEmail . '"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="url"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="url"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_LINK_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_LINK_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . $cbWebsite . '"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="list"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' + $this->configFieldSets[] = Indent::_(3) . 'type="list"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . (int) $contributor['use'] . '"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_USE_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_USE_DESC">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="list"'; - $this->configFieldSets[] = $this->_t(3) . 'default="' + $this->configFieldSets[] = Indent::_(3) . 'type="list"'; + $this->configFieldSets[] = Indent::_(3) . 'default="' . (int) $contributor['show'] . '"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_SHOW_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_SHOW_DESC">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(2) . ""; + $this->configFieldSets[] = Indent::_(2) . ""; // add the contributor - $this->theContributors .= PHP_EOL . $this->_t(1) . "@" - . strtolower($contributor['title']) . $this->_t(2) + $this->theContributors .= PHP_EOL . Indent::_(1) . "@" + . strtolower((string) $contributor['title']) . Indent::_(2) . $contributor['name'] . ' <' . $contributor['website'] . '>'; // setup lang $Counter = StringHelper::safe($counter, 'Ww'); - $this->setLangContent( - $this->lang, $langCont . '_' . $COUNTER, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_' . $COUNTER, "Contributor " . $Counter ); // load the Global checkin defautls @@ -25060,7 +23074,7 @@ class Interpretation extends Fields } } // add more contributors if required - if (1 == $this->componentData->emptycontributors) + if (1 == CFactory::_('Component')->get('emptycontributors', 0)) { if (isset($counter)) { @@ -25071,385 +23085,420 @@ class Interpretation extends Fields { $min = 1; } - $max = $min + $this->componentData->number - 1; + $max = $min + CFactory::_('Component')->get('number') - 1; $moreContributerFields = range($min, $max, 1); foreach ($moreContributerFields as $counter) { $COUNTER = StringHelper::safe($counter, 'U'); - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ''; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="spacer"'; - $this->configFieldSets[] = $this->_t(3) . 'class="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="spacer"'; + $this->configFieldSets[] = Indent::_(3) . 'class="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_' . $COUNTER . '"'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_TITLE_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_TITLE_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_NAME_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_NAME_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="email"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="email"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_EMAIL_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_EMAIL_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="url"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="url"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_LINK_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_LINK_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="list"'; - $this->configFieldSets[] = $this->_t(3) . 'default="0"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="list"'; + $this->configFieldSets[] = Indent::_(3) . 'default="0"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_USE_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_USE_DESC">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="list"'; - $this->configFieldSets[] = $this->_t(3) . 'default="0"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $langCont + $this->configFieldSets[] = Indent::_(3) . 'type="list"'; + $this->configFieldSets[] = Indent::_(3) . 'default="0"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $langCont . '_SHOW_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $langCont . '_SHOW_DESC">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(2) . ""; + $this->configFieldSets[] = Indent::_(2) . ""; // setup lang $Counter = StringHelper::safe($counter, 'Ww'); - $this->setLangContent( - $this->lang, $langCont . '_' . $COUNTER, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_' . $COUNTER, "Contributor " . $Counter ); } } - if ($this->addContributors - || $this->componentData->emptycontributors == 1) + if (CFactory::_('Config')->get('add_contributors', false) + || CFactory::_('Component')->get('emptycontributors', 0) == 1) { // setup lang - $this->setLangContent( - $this->lang, $langCont . '_TITLE_LABEL', "Contributor Job Title" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_TITLE_LABEL', "Contributor Job Title" ); - $this->setLangContent( - $this->lang, $langCont . '_TITLE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_TITLE_DESC', "The job title that best describes the contributor's relationship to this component." ); - $this->setLangContent( - $this->lang, $langCont . '_NAME_LABEL', "Contributor Name" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_NAME_LABEL', "Contributor Name" ); - $this->setLangContent( - $this->lang, $langCont . '_NAME_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_NAME_DESC', "The name of this contributor." ); - $this->setLangContent( - $this->lang, $langCont . '_EMAIL_LABEL', "Contributor Email" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_EMAIL_LABEL', "Contributor Email" ); - $this->setLangContent( - $this->lang, $langCont . '_EMAIL_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_EMAIL_DESC', "The email of this contributor." ); - $this->setLangContent( - $this->lang, $langCont . '_LINK_LABEL', "Contributor Website" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_LINK_LABEL', "Contributor Website" ); - $this->setLangContent( - $this->lang, $langCont . '_LINK_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_LINK_DESC', "The link to this contributor's website." ); - $this->setLangContent($this->lang, $langCont . '_USE_LABEL', "Use"); - $this->setLangContent( - $this->lang, $langCont . '_USE_DESC', + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langCont . '_USE_LABEL', "Use"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_USE_DESC', "How should we link to this contributor." ); - $this->setLangContent($this->lang, $langCont . '_USE_NONE', "None"); - $this->setLangContent( - $this->lang, $langCont . '_USE_EMAIL', "Email" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $langCont . '_USE_NONE', "None"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_USE_EMAIL', "Email" ); - $this->setLangContent( - $this->lang, $langCont . '_USE_WWW', "Website" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_USE_WWW', "Website" ); - $this->setLangContent( - $this->lang, $langCont . '_SHOW_LABEL', "Show" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_SHOW_LABEL', "Show" ); - $this->setLangContent( - $this->lang, $langCont . '_SHOW_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_SHOW_DESC', "Select where you want this contributor's details to show in the component." ); - $this->setLangContent( - $this->lang, $langCont . '_SHOW_NONE', "Hide" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_SHOW_NONE', "Hide" ); - $this->setLangContent( - $this->lang, $langCont . '_SHOW_BACK', "Back-end" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_SHOW_BACK', "Back-end" ); - $this->setLangContent( - $this->lang, $langCont . '_SHOW_FRONT', "Front-end" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_SHOW_FRONT', "Front-end" ); - $this->setLangContent( - $this->lang, $langCont . '_SHOW_ALL', "Both Front & Back-end" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $langCont . '_SHOW_ALL', "Both Front & Back-end" ); } // close that fieldset - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; } public function setUikitConfigFieldsets($lang) { - if ($this->uikit > 0) + if (CFactory::_('Config')->uikit > 0) { // main lang prefix $lang = $lang . ''; // start building field set for uikit functions - $this->configFieldSets[] = $this->_t(1) . "configFieldSets[] = $this->_t(2) . 'name="uikit_config"'; - $this->configFieldSets[] = $this->_t(2) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(1) . "configFieldSets[] = Indent::_(2) . 'name="uikit_config"'; + $this->configFieldSets[] = Indent::_(2) . 'label="' . $lang . '_UIKIT_LABEL"'; - $this->configFieldSets[] = $this->_t(2) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'description="' . $lang . '_UIKIT_DESC">'; // set tab lang - if (1 == $this->uikit) + if (1 == CFactory::_('Config')->uikit) { - $this->setLangContent( - $this->lang, $lang . '_UIKIT_LABEL', "Uikit2 Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_LABEL', "Uikit2 Settings" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_DESC', "The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework -for developing fast and powerful web interfaces. For more info visit https://getuikit.com/v2/" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_DESC', "The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework +for developing fast and powerful web interfaces. For more info visit https://getuikit.com/v2/" ); } - elseif (2 == $this->uikit) + elseif (2 == CFactory::_('Config')->uikit) { - $this->setLangContent( - $this->lang, $lang . '_UIKIT_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_LABEL', "Uikit2 and Uikit3 Settings" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_DESC', "The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework -for developing fast and powerful web interfaces. For more info visit version 2 or version 3" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_DESC', "The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework +for developing fast and powerful web interfaces. For more info visit version 2 or version 3" ); } - elseif (3 == $this->uikit) + elseif (3 == CFactory::_('Config')->uikit) { - $this->setLangContent( - $this->lang, $lang . '_UIKIT_LABEL', "Uikit3 Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_LABEL', "Uikit3 Settings" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_DESC', "The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework -for developing fast and powerful web interfaces. For more info visit https://getuikit.com/" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_DESC', "The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework +for developing fast and powerful web interfaces. For more info visit https://getuikit.com/" ); } + // set field lang + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_JQUERY_LOAD_LABEL', "Load Joomla jQuery" + ); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_JQUERY_LOAD_DESC', + "Would you like to load the Joomla jQuery Framework?" + ); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_JQUERY_LOAD', "Load jQuery"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_JQUERY_REMOVE', "Remove jQuery"); + + // set the field + $this->configFieldSets[] = Indent::_(2) + . 'configFieldSets[] = Indent::_(3) . 'type="radio"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang + . '_JQUERY_LOAD_LABEL"'; + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang + . '_JQUERY_LOAD_DESC"'; + $this->configFieldSets[] = Indent::_(3) + . 'class="btn-group btn-group-yesno"'; + $this->configFieldSets[] = Indent::_(3) . 'default="">'; + $this->configFieldSets[] = Indent::_(3) . ''; + $this->configFieldSets[] = Indent::_(3) . '"'; + $this->configFieldSets[] = Indent::_(3) . '"'; + $this->configFieldSets[] = Indent::_(2) . ""; + // set params defaults + $this->extensionsParams[] = '"add_jquery_framework":"1"'; + // add version selection - if (2 == $this->uikit) + if (2 == CFactory::_('Config')->uikit) { // set field lang - $this->setLangContent( - $this->lang, $lang . '_UIKIT_VERSION_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_VERSION_LABEL', "Uikit Versions" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_VERSION_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_VERSION_DESC', "Select what version you would like to use" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_V2', "Version 2" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_V2', "Version 2" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_V3', "Version 3" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_V3', "Version 3" ); // set the field - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="radio"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'type="radio"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_UIKIT_VERSION_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_UIKIT_VERSION_DESC"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'class="btn-group btn-group-yesno"'; - $this->configFieldSets[] = $this->_t(3) . 'default="2">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(2) . ""; + $this->configFieldSets[] = Indent::_(2) . "
"; // set params defaults $this->extensionsParams[] = '"uikit_version":"2"'; } // set field lang - $this->setLangContent( - $this->lang, $lang . '_UIKIT_LOAD_LABEL', "Loading Options" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_LOAD_LABEL', "Loading Options" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_LOAD_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_LOAD_DESC', "Set the uikit loading option." ); - $this->setLangContent($this->lang, $lang . '_AUTO_LOAD', "Auto"); - $this->setLangContent($this->lang, $lang . '_FORCE_LOAD', "Force"); - $this->setLangContent($this->lang, $lang . '_DONT_LOAD', "Not"); - $this->setLangContent( - $this->lang, $lang . '_ONLY_EXTRA', "Only Extra" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_AUTO_LOAD', "Auto"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_FORCE_LOAD', "Force"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_DONT_LOAD', "Not"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ONLY_EXTRA', "Only Extra" ); // set the field - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="radio"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'type="radio"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_UIKIT_LOAD_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_UIKIT_LOAD_DESC"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'class="btn-group btn-group-yesno"'; - $this->configFieldSets[] = $this->_t(3) . 'default="">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(3) . '"'; - if (2 == $this->uikit || 1 == $this->uikit) + if (2 == CFactory::_('Config')->uikit || 1 == CFactory::_('Config')->uikit) { - $this->configFieldSets[] = $this->_t(3) . '"'; } - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(2) . ""; + $this->configFieldSets[] = Indent::_(2) . "
"; // set params defaults $this->extensionsParams[] = '"uikit_load":"1"'; // set field lang - $this->setLangContent( - $this->lang, $lang . '_UIKIT_MIN_LABEL', "Load Minified" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_MIN_LABEL', "Load Minified" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_MIN_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_MIN_DESC', "Should the minified version of uikit files be loaded?" ); - $this->setLangContent($this->lang, $lang . '_YES', "Yes"); - $this->setLangContent($this->lang, $lang . '_NO', "No"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_YES', "Yes"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_NO', "No"); // set the field - $this->configFieldSets[] = $this->_t(2) . 'configFieldSets[] = $this->_t(3) . 'type="radio"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = Indent::_(3) . 'type="radio"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_UIKIT_MIN_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_UIKIT_MIN_DESC"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'class="btn-group btn-group-yesno"'; - $this->configFieldSets[] = $this->_t(3) . 'default="">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(2) . ""; + $this->configFieldSets[] = Indent::_(3) . '"'; + $this->configFieldSets[] = Indent::_(3) . '"'; + $this->configFieldSets[] = Indent::_(2) . ""; // set params defaults $this->extensionsParams[] = '"uikit_min":""'; - if (2 == $this->uikit || 1 == $this->uikit) + if (2 == CFactory::_('Config')->uikit || 1 == CFactory::_('Config')->uikit) { // set field lang - $this->setLangContent( - $this->lang, $lang . '_UIKIT_STYLE_LABEL', "css Style" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_STYLE_LABEL', "css Style" ); - $this->setLangContent( - $this->lang, $lang . '_UIKIT_STYLE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_UIKIT_STYLE_DESC', "Set the css style that should be used." ); - $this->setLangContent( - $this->lang, $lang . '_FLAT_LOAD', "Flat" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_FLAT_LOAD', "Flat" ); - $this->setLangContent( - $this->lang, $lang . '_ALMOST_FLAT_LOAD', "Almost Flat" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ALMOST_FLAT_LOAD', "Almost Flat" ); - $this->setLangContent( - $this->lang, $lang . '_GRADIANT_LOAD', "Gradient" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_GRADIANT_LOAD', "Gradient" ); // set the field - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="radio"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'type="radio"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_UIKIT_STYLE_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_UIKIT_STYLE_DESC"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'class="btn-group btn-group-yesno"'; - if (2 == $this->uikit) + if (2 == CFactory::_('Config')->uikit) { - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'showon="uikit_version:2"'; } - $this->configFieldSets[] = $this->_t(3) . 'default="">'; - $this->configFieldSets[] = $this->_t(3) . ''; - $this->configFieldSets[] = $this->_t(3) . '"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . '"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . '"'; - $this->configFieldSets[] = $this->_t(2) . ""; + $this->configFieldSets[] = Indent::_(2) . "
"; // set params defaults $this->extensionsParams[] = '"uikit_style":""'; } @@ -25465,27 +23514,26 @@ for developing fast and powerful web interfaces. For more info visit configFieldSetsCustomField['Uikit Settings']); } // close that fieldset - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; } } public function setEmailHelperConfigFieldsets($lang) { - if (isset($this->componentData->add_email_helper) - && $this->componentData->add_email_helper) + if (CFactory::_('Component')->get('add_email_helper')) { // main lang prefix $lang = $lang . ''; // set main lang string - $this->setLangContent( - $this->lang, $lang . '_MAIL_CONFIGURATION', "Mail Configuration" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAIL_CONFIGURATION', "Mail Configuration" ); - $this->setLangContent($this->lang, $lang . '_DKIM', "DKIM"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_DKIM', "DKIM"); // start building field set for email helper functions - $this->configFieldSets[] = PHP_EOL . $this->_t(1) . "configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = PHP_EOL . Indent::_(1) . "configFieldSets[] = Indent::_(2) . "name=\"mail_configuration_custom_config\""; - $this->configFieldSets[] = $this->_t(2) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "label=\"" . $lang . "_MAIL_CONFIGURATION\">"; // add custom Mail Configurations if (isset($this->configFieldSetsCustomField['Mail Configuration']) @@ -25501,459 +23549,459 @@ for developing fast and powerful web interfaces. For more info visit setLangContent( - $this->lang, $lang . '_MAILONLINE_LABEL', "Mailer Status" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAILONLINE_LABEL', "Mailer Status" ); - $this->setLangContent( - $this->lang, $lang . '_MAILONLINE_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAILONLINE_DESCRIPTION', "Warning this will stop all emails from going out." ); - $this->setLangContent($this->lang, $lang . '_ON', "On"); - $this->setLangContent($this->lang, $lang . '_OFF', "Off"); - $this->setLangContent( - $this->lang, $lang . '_MAILER_LABEL', "Mailer" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_ON', "On"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_OFF', "Off"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAILER_LABEL', "Mailer" ); - $this->setLangContent( - $this->lang, $lang . '_MAILER_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAILER_DESCRIPTION', "Select what mailer you would like to use to send emails." ); - $this->setLangContent($this->lang, $lang . '_GLOBAL', "Global"); - $this->setLangContent( - $this->lang, $lang . '_PHP_MAIL', "PHP Mail" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_GLOBAL', "Global"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_PHP_MAIL', "PHP Mail" ); - $this->setLangContent( - $this->lang, $lang . '_SENDMAIL', "Sendmail" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SENDMAIL', "Sendmail" ); - $this->setLangContent($this->lang, $lang . '_SMTP', "SMTP"); - $this->setLangContent( - $this->lang, $lang . '_EMAILFROM_LABEL', " From Email" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_SMTP', "SMTP"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_EMAILFROM_LABEL', " From Email" ); - $this->setLangContent( - $this->lang, $lang . '_EMAILFROM_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_EMAILFROM_DESCRIPTION', "The global email address that will be used to send system email." ); - $this->setLangContent( - $this->lang, $lang . '_EMAILFROM_HINT', "Email Address Here" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_EMAILFROM_HINT', "Email Address Here" ); - $this->setLangContent( - $this->lang, $lang . '_FROMNAME_LABEL', "From Name" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_FROMNAME_LABEL', "From Name" ); - $this->setLangContent( - $this->lang, $lang . '_FROMNAME_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_FROMNAME_DESCRIPTION', "Text displayed in the header "From:" field when sending a site email. Usually the site name." ); - $this->setLangContent( - $this->lang, $lang . '_FROMNAME_HINT', "From Name Here" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_FROMNAME_HINT', "From Name Here" ); - $this->setLangContent( - $this->lang, $lang . '_EMAILREPLY_LABEL', " Reply to Email" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_EMAILREPLY_LABEL', " Reply to Email" ); - $this->setLangContent( - $this->lang, $lang . '_EMAILREPLY_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_EMAILREPLY_DESCRIPTION', "The global email address that will be used to set as the reply email. (leave blank for none)" ); - $this->setLangContent( - $this->lang, $lang . '_EMAILREPLY_HINT', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_EMAILREPLY_HINT', "Email Address Here" ); - $this->setLangContent( - $this->lang, $lang . '_REPLYNAME_LABEL', "Reply to Name" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_REPLYNAME_LABEL', "Reply to Name" ); - $this->setLangContent( - $this->lang, $lang . '_REPLYNAME_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_REPLYNAME_DESCRIPTION', "Text displayed in the header "Reply To:" field when replying to the site email. Usually the the person that receives the response. (leave blank for none)" ); - $this->setLangContent( - $this->lang, $lang . '_REPLYNAME_HINT', "Reply Name Here" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_REPLYNAME_HINT', "Reply Name Here" ); - $this->setLangContent( - $this->lang, $lang . '_SENDMAIL_LABEL', "Sendmail Path" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SENDMAIL_LABEL', "Sendmail Path" ); - $this->setLangContent( - $this->lang, $lang . '_SENDMAIL_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SENDMAIL_DESCRIPTION', "Enter the path to the sendmail program directory on your host server." ); - $this->setLangContent( - $this->lang, $lang . '_SENDMAIL_HINT', "/usr/sbin/sendmail" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SENDMAIL_HINT', "/usr/sbin/sendmail" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPAUTH_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPAUTH_LABEL', "SMTP Authentication" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPAUTH_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPAUTH_DESCRIPTION', "Select yes if your SMTP host requires SMTP Authentication." ); - $this->setLangContent($this->lang, $lang . '_YES', "Yes"); - $this->setLangContent($this->lang, $lang . '_NO', "No"); - $this->setLangContent( - $this->lang, $lang . '_SMTPSECURE_LABEL', "SMTP Security" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_YES', "Yes"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_NO', "No"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPSECURE_LABEL', "SMTP Security" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPSECURE_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPSECURE_DESCRIPTION', "Select the security model that your SMTP server uses." ); - $this->setLangContent($this->lang, $lang . '_NONE', "None"); - $this->setLangContent($this->lang, $lang . '_SSL', "SSL"); - $this->setLangContent($this->lang, $lang . '_TLS', "TLS"); - $this->setLangContent( - $this->lang, $lang . '_SMTPPORT_LABEL', "SMTP Port" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_NONE', "None"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_SSL', "SSL"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_TLS', "TLS"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPPORT_LABEL', "SMTP Port" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPPORT_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPPORT_DESCRIPTION', "Enter the port number of your SMTP server. Use 25 for most unsecured servers and 465 for most secure servers." ); - $this->setLangContent( - $this->lang, $lang . '_SMTPPORT_HINT', "25" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPPORT_HINT', "25" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPUSER_LABEL', "SMTP Username" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPUSER_LABEL', "SMTP Username" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPUSER_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPUSER_DESCRIPTION', "Enter the username for access to the SMTP host." ); - $this->setLangContent( - $this->lang, $lang . '_SMTPUSER_HINT', "email@demo.com" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPUSER_HINT', "email@demo.com" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPPASS_LABEL', "SMTP Password" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPPASS_LABEL', "SMTP Password" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPPASS_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPPASS_DESCRIPTION', "Enter the password for access to the SMTP host." ); - $this->setLangContent( - $this->lang, $lang . '_SMTPHOST_LABEL', "SMTP Host" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPHOST_LABEL', "SMTP Host" ); - $this->setLangContent( - $this->lang, $lang . '_SMTPHOST_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPHOST_DESCRIPTION', "Enter the name of the SMTP host." ); - $this->setLangContent( - $this->lang, $lang . '_SMTPHOST_HINT', "localhost" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SMTPHOST_HINT', "localhost" ); // set the mailer fields - $this->configFieldSets[] = PHP_EOL . $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"radio\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"mailonline\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"radio\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"mailonline\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_MAILONLINE_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_MAILONLINE_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"btn-group btn-group-yesno\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"1\">"; - $this->configFieldSets[] = $this->_t(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "default=\"1\">"; + $this->configFieldSets[] = Indent::_(3) . ""; + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(2) . "
"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"list\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"mailer\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"list\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"mailer\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_MAILER_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_MAILER_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"list_class\""; - $this->configFieldSets[] = $this->_t(3) . "multiple=\"false\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"WORD\""; - $this->configFieldSets[] = $this->_t(3) . "required=\"true\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"global\">"; - $this->configFieldSets[] = $this->_t(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "multiple=\"false\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"WORD\""; + $this->configFieldSets[] = Indent::_(3) . "required=\"true\""; + $this->configFieldSets[] = Indent::_(3) . "default=\"global\">"; + $this->configFieldSets[] = Indent::_(3) . ""; + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(2) . "
"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"emailfrom\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"emailfrom\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_EMAILFROM_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_EMAILFROM_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) . "validate=\"email\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "validate=\"email\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add email address here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_EMAILFROM_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp,sendmail,default\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"fromname\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"fromname\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_FROMNAME_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_FROMNAME_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add some name here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_FROMNAME_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp,sendmail,default\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"replyto\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"replyto\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_EMAILREPLY_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_EMAILREPLY_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) . "validate=\"email\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "validate=\"email\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add email address here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_EMAILREPLY_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp,sendmail,default\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"replytoname\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_REPLYNAME_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_REPLYNAME_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add some name here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_REPLYNAME_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp,sendmail,default\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"sendmail\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"sendmail\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SENDMAIL_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SENDMAIL_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "required=\"false\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"PATH\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "required=\"false\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"PATH\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add path to you local sendmail here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_SENDMAIL_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:sendmail\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"radio\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"smtpauth\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"radio\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"smtpauth\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SMTPAUTH_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SMTPAUTH_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"btn-group btn-group-yesno\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"0\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "default=\"0\""; + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp\">"; - $this->configFieldSets[] = $this->_t(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(2) . "
"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"list\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"smtpsecure\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"list\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"smtpsecure\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SMTPSECURE_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SMTPSECURE_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"list_class\""; - $this->configFieldSets[] = $this->_t(3) . "multiple=\"false\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"WORD\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"none\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "multiple=\"false\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"WORD\""; + $this->configFieldSets[] = Indent::_(3) . "default=\"none\""; + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp\">"; - $this->configFieldSets[] = $this->_t(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(2) . "
"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"smtpport\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"smtpport\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SMTPPORT_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"25\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "default=\"25\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SMTPPORT_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add the port number of your SMTP server here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_SMTPPORT_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"smtpuser\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"smtpuser\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SMTPUSER_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SMTPUSER_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add the username for SMTP server here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_SMTPUSER_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"password\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"smtppass\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"password\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"smtppass\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SMTPPASS_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SMTPPASS_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"raw\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"raw\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add the password for SMTP server here.\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"smtphost\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"smtphost\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_SMTPHOST_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "default=\"localhost\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_SMTPHOST_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add the name of the SMTP host here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_SMTPHOST_HINT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"mailer:smtp\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . "/>"; } // close that fieldset - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; // start dkim field set - $this->configFieldSets[] = $this->_t(1) . "configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(1) . "configFieldSets[] = Indent::_(2) . "name=\"dkim_custom_config\""; - $this->configFieldSets[] = $this->_t(2) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "label=\"" . $lang . "_DKIM\">"; // add custom DKIM fields if (isset($this->configFieldSetsCustomField['DKIM']) @@ -25968,74 +24016,74 @@ for developing fast and powerful web interfaces. For more info visit setLangContent( - $this->lang, $lang . '_DKIM_LABEL', "Enable DKIM" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_LABEL', "Enable DKIM" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_DESCRIPTION', "Set this option to Yes if you want to sign your emails using DKIM." ); - $this->setLangContent($this->lang, $lang . '_YES', "Yes"); - $this->setLangContent($this->lang, $lang . '_NO', "No"); - $this->setLangContent( - $this->lang, $lang . '_DKIM_DOMAIN_LABEL', "Domain" + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_YES', "Yes"); + CFactory::_('Language')->set(CFactory::_('Config')->lang_target, $lang . '_NO', "No"); + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_DOMAIN_LABEL', "Domain" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_DOMAIN_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_DOMAIN_DESCRIPTION', "Set the domain. Eg. domain.com" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_DOMAIN_HINT', "domain.com" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_DOMAIN_HINT', "domain.com" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_SELECTOR_LABEL', "Selector" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_SELECTOR_LABEL', "Selector" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_SELECTOR_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_SELECTOR_DESCRIPTION', "Set your DKIM/DNS selector." ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_SELECTOR_HINT', "vdm" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_SELECTOR_HINT', "vdm" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_PASSPHRASE_LABEL', "Passphrase" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_PASSPHRASE_LABEL', "Passphrase" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_PASSPHRASE_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_PASSPHRASE_DESCRIPTION', "Enter your passphrase here." ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_IDENTITY_LABEL', "Identity" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_IDENTITY_LABEL', "Identity" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_IDENTITY_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_IDENTITY_DESCRIPTION', "Set DKIM identity. This can be in the format of an email address 'you@yourdomain.com' typically used as the source of the email." ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_IDENTITY_HINT', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_IDENTITY_HINT', "you@yourdomain.com" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_PRIVATE_KEY_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_PRIVATE_KEY_LABEL', "Private key" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_PRIVATE_KEY_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_PRIVATE_KEY_DESCRIPTION', "set private key" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_PUBLIC_KEY_LABEL', "Public key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_PUBLIC_KEY_LABEL', "Public key" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_PUBLIC_KEY_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_PUBLIC_KEY_DESCRIPTION', "set public key" ); - $this->setLangContent( - $this->lang, $lang . '_NOTE_DKIM_USE_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_NOTE_DKIM_USE_LABEL', "Server Configuration" ); - $this->setLangContent( - $this->lang, $lang . '_NOTE_DKIM_USE_DESCRIPTION', "

Using the below details, you need to configure your DNS by adding a TXT record on your domain:

+ CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_NOTE_DKIM_USE_DESCRIPTION', "

Using the below details, you need to configure your DNS by adding a TXT record on your domain:

" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_KEY_LABEL', "Key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_KEY_LABEL', "Key" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_KEY_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_KEY_DESCRIPTION', "This is the KEY to use in the DNS record." ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_KEY_HINT', "vdm._domainkey" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_KEY_HINT', "vdm._domainkey" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_VALUE_LABEL', "Value" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_VALUE_LABEL', "Value" ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_VALUE_DESCRIPTION', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_VALUE_DESCRIPTION', "This is the TXT value to use in the DNS. Replace the PUBLICKEY with your public key." ); - $this->setLangContent( - $this->lang, $lang . '_DKIM_VALUE_HINT', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_DKIM_VALUE_HINT', "v=DKIM1;k=rsa;g=*;s=email;h=sha1;t=s;p=PUBLICKEY" ); - $this->configFieldSets[] = PHP_EOL . $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"radio\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"dkim\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"radio\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"btn-group btn-group-yesno\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"0\""; - $this->configFieldSets[] = $this->_t(3) . "required=\"true\">"; - $this->configFieldSets[] = $this->_t(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "default=\"0\""; + $this->configFieldSets[] = Indent::_(3) . "required=\"true\">"; + $this->configFieldSets[] = Indent::_(3) . ""; + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . ""; - $this->configFieldSets[] = $this->_t(2) . "
"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_domain\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_DOMAIN_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_DOMAIN_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add DKIM Domain here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_DKIM_DOMAIN_HINT\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"dkim:1\""; + $this->configFieldSets[] = Indent::_(3) . "onchange=\"vdm_dkim();\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_selector\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_SELECTOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"vdm\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "default=\"vdm\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_SELECTOR_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add DKIM/DNS selector here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_DKIM_SELECTOR_HINT\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"dkim:1\""; + $this->configFieldSets[] = Indent::_(3) . "onchange=\"vdm_dkim();\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"password\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"password\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_passphrase\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_PASSPHRASE_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_PASSPHRASE_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"raw\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"raw\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add passphrase here.\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_identity\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_IDENTITY_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"60\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"60\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_IDENTITY_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"raw\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"raw\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add DKIM Identity here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_DKIM_IDENTITY_HINT\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"textarea\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"textarea\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_private_key\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_PRIVATE_KEY_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "rows=\"15\""; - $this->configFieldSets[] = $this->_t(3) . "cols=\"5\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "rows=\"15\""; + $this->configFieldSets[] = Indent::_(3) . "cols=\"5\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_PRIVATE_KEY_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"input-xxlarge span12\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"textarea\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"textarea\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_public_key\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_PUBLIC_KEY_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "rows=\"5\""; - $this->configFieldSets[] = $this->_t(3) . "cols=\"5\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "rows=\"5\""; + $this->configFieldSets[] = Indent::_(3) . "cols=\"5\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_PUBLIC_KEY_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"input-xxlarge span12\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "showon=\"dkim:1\""; + $this->configFieldSets[] = Indent::_(3) . "onchange=\"vdm_dkim();\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"dkim_key\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_key\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_KEY_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"40\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"150\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"40\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"150\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_KEY_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add KEY here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_DKIM_KEY_HINT\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"dkim_value\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"dkim_value\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_DKIM_VALUE_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"80\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"350\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" + $this->configFieldSets[] = Indent::_(3) . "size=\"80\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"350\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_DKIM_VALUE_DESCRIPTION\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"STRING\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"STRING\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add TXT record here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_DKIM_VALUE_HINT\""; - $this->configFieldSets[] = $this->_t(3) . "showon=\"dkim:1\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(3) . "showon=\"dkim:1\""; + $this->configFieldSets[] = Indent::_(2) . "/>"; } // close that fieldset - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; } } public function setGooglechartConfigFieldsets($lang) { - if ($this->googlechart) + if (CFactory::_('Config')->get('google_chart', false)) { - $this->configFieldSets[] = PHP_EOL . $this->_t(1) . "configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = PHP_EOL . Indent::_(1) . "configFieldSets[] = Indent::_(2) . "name=\"googlechart_config\""; - $this->configFieldSets[] = $this->_t(2) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "label=\"" . $lang . "_CHART_SETTINGS_LABEL\""; - $this->configFieldSets[] = $this->_t(2) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "description=\"" . $lang . "_CHART_SETTINGS_DESC\">"; - $this->configFieldSets[] = $this->_t(2); - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2); + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_chartbackground\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#F7F7FA\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#F7F7FA\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTBACKGROUND_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTBACKGROUND_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_mainwidth\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_MAINWIDTH_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_MAINWIDTH_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add area width here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_MAINWIDTH_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_chartareatop\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTAREATOP_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTAREATOP_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add top spacing here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_CHARTAREATOP_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_chartarealeft\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTAREALEFT_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTAREALEFT_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add left spacing here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_CHARTAREALEFT_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_chartareawidth\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTAREAWIDTH_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTAREAWIDTH_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add chart width here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_CHARTAREAWIDTH_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_legendtextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_LEGENDTEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_LEGENDTEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_legendtextstylefontsize\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_LEGENDTEXTSTYLEFONTSIZE_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_LEGENDTEXTSTYLEFONTSIZE_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add size of the legend here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_LEGENDTEXTSTYLEFONTSIZE_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_vaxistextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_VAXISTEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_VAXISTEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_haxistextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_HAXISTEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_HAXISTEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"admin_haxistitletextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_HAXISTITLETEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_HAXISTITLETEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2); - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . "/>"; + $this->configFieldSets[] = Indent::_(2); + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2); - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_chartbackground\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#F7F7FA\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#F7F7FA\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTBACKGROUND_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTBACKGROUND_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) . "name=\"site_mainwidth\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_mainwidth\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_MAINWIDTH_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_MAINWIDTH_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add area width here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_MAINWIDTH_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_chartareatop\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTAREATOP_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTAREATOP_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add top spacing here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_CHARTAREATOP_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_chartarealeft\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTAREALEFT_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTAREALEFT_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add left spacing here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_CHARTAREALEFT_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_chartareawidth\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_CHARTAREAWIDTH_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_CHARTAREAWIDTH_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add chart width here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_CHARTAREAWIDTH_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_legendtextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_LEGENDTEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_LEGENDTEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"text\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"text\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_legendtextstylefontsize\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_LEGENDTEXTSTYLEFONTSIZE_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "size=\"20\""; - $this->configFieldSets[] = $this->_t(3) . "maxlength=\"50\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "size=\"20\""; + $this->configFieldSets[] = Indent::_(3) . "maxlength=\"50\""; + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_LEGENDTEXTSTYLEFONTSIZE_DESC\""; - $this->configFieldSets[] = $this->_t(3) . "class=\"text_area\""; - $this->configFieldSets[] = $this->_t(3) . "filter=\"INT\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . "class=\"text_area\""; + $this->configFieldSets[] = Indent::_(3) . "filter=\"INT\""; + $this->configFieldSets[] = Indent::_(3) . "message=\"Error! Please add size of the legend here.\""; - $this->configFieldSets[] = $this->_t(3) . "hint=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "hint=\"" . $lang . "_LEGENDTEXTSTYLEFONTSIZE_HINT\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_vaxistextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_VAXISTEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_VAXISTEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ""; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_haxistextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_HAXISTEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_HAXISTEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; - $this->configFieldSets[] = $this->_t(2) . ""; - $this->configFieldSets[] = $this->_t(2) . "configFieldSets[] = $this->_t(3) . "type=\"color\""; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(2) . "configFieldSets[] = Indent::_(3) . "type=\"color\""; + $this->configFieldSets[] = Indent::_(3) . "name=\"site_haxistitletextstylefontcolor\""; - $this->configFieldSets[] = $this->_t(3) . "default=\"#63B1F2\""; - $this->configFieldSets[] = $this->_t(3) . "label=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "default=\"#63B1F2\""; + $this->configFieldSets[] = Indent::_(3) . "label=\"" . $lang . "_HAXISTITLETEXTSTYLEFONTCOLOR_LABEL\""; - $this->configFieldSets[] = $this->_t(3) . "description=\"" . $lang + $this->configFieldSets[] = Indent::_(3) . "description=\"" . $lang . "_HAXISTITLETEXTSTYLEFONTCOLOR_DESC\""; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(2) . "/>"; // add custom Encryption Settings fields if (isset($this->configFieldSetsCustomField['Chart Settings']) @@ -26700,124 +24748,124 @@ function vdm_dkim() { unset($this->configFieldSetsCustomField['Chart Settings']); } - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; // set params defaults $this->extensionsParams[] = '"admin_chartbackground":"#F7F7FA","admin_mainwidth":"1000","admin_chartareatop":"20","admin_chartarealeft":"20","admin_chartareawidth":"170","admin_legendtextstylefontcolor":"10","admin_legendtextstylefontsize":"20","admin_vaxistextstylefontcolor":"#63B1F2","admin_haxistextstylefontcolor":"#63B1F2","admin_haxistitletextstylefontcolor":"#63B1F2","site_chartbackground":"#F7F7FA","site_mainwidth":"1000","site_chartareatop":"20","site_chartarealeft":"20","site_chartareawidth":"170","site_legendtextstylefontcolor":"10","site_legendtextstylefontsize":"20","site_vaxistextstylefontcolor":"#63B1F2","site_haxistextstylefontcolor":"#63B1F2","site_haxistitletextstylefontcolor":"#63B1F2"'; // set field lang - $this->setLangContent( - $this->lang, $lang . '_CHART_SETTINGS_LABEL', "Chart Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHART_SETTINGS_LABEL', "Chart Settings" ); - $this->setLangContent( - $this->lang, $lang . '_CHART_SETTINGS_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHART_SETTINGS_DESC', "The Google Chart Display Settings Are Made Here." ); - $this->setLangContent( - $this->lang, $lang . '_ADMIN_CHART_NOTE_LABEL', "Admin Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ADMIN_CHART_NOTE_LABEL', "Admin Settings" ); - $this->setLangContent( - $this->lang, $lang . '_ADMIN_CHART_NOTE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ADMIN_CHART_NOTE_DESC', "The following settings are used on the back-end of the site called (admin)." ); - $this->setLangContent( - $this->lang, $lang . '_SITE_CHART_NOTE_LABEL', "Site Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SITE_CHART_NOTE_LABEL', "Site Settings" ); - $this->setLangContent( - $this->lang, $lang . '_SITE_CHART_NOTE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_SITE_CHART_NOTE_DESC', "The following settings are used on the front-end of the site called (site)." ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREALEFT_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREALEFT_DESC', "Set in pixels the spacing from the left of the chart area to the beginning of the chart it self. Please don't add the px sign" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREALEFT_HINT', "170" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREALEFT_HINT', "170" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREALEFT_LABEL', "Left Spacing" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREALEFT_LABEL', "Left Spacing" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREATOP_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREATOP_DESC', "Set in pixels the spacing from the top of the chart area to the beginning of the chart it self. Please don't add the px sign" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREATOP_HINT', "20" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREATOP_HINT', "20" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREATOP_LABEL', "Top Spacing" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREATOP_LABEL', "Top Spacing" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREAWIDTH_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREAWIDTH_DESC', "Set in % the width of the chart it self inside the chart area. Please don't add the % sign" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREAWIDTH_HINT', "60" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREAWIDTH_HINT', "60" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTAREAWIDTH_LABEL', "Chart Width" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTAREAWIDTH_LABEL', "Chart Width" ); - $this->setLangContent( - $this->lang, $lang . '_CHARTBACKGROUND_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTBACKGROUND_DESC', "Select the chart background color here." ); - $this->setLangContent( - $this->lang, $lang . '_CHARTBACKGROUND_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_CHARTBACKGROUND_LABEL', "Chart Background" ); - $this->setLangContent( - $this->lang, $lang . '_HAXISTEXTSTYLEFONTCOLOR_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_HAXISTEXTSTYLEFONTCOLOR_DESC', "Select the horizontal axis font color." ); - $this->setLangContent( - $this->lang, $lang . '_HAXISTEXTSTYLEFONTCOLOR_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_HAXISTEXTSTYLEFONTCOLOR_LABEL', "hAxis Font Color" ); - $this->setLangContent( - $this->lang, $lang . '_HAXISTITLETEXTSTYLEFONTCOLOR_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_HAXISTITLETEXTSTYLEFONTCOLOR_DESC', "Select the horizontal axis title's font color." ); - $this->setLangContent( - $this->lang, $lang . '_HAXISTITLETEXTSTYLEFONTCOLOR_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_HAXISTITLETEXTSTYLEFONTCOLOR_LABEL', "hAxis Title Font Color" ); - $this->setLangContent( - $this->lang, $lang . '_LEGENDTEXTSTYLEFONTCOLOR_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_LEGENDTEXTSTYLEFONTCOLOR_DESC', "Select the legend font color." ); - $this->setLangContent( - $this->lang, $lang . '_LEGENDTEXTSTYLEFONTCOLOR_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_LEGENDTEXTSTYLEFONTCOLOR_LABEL', "Legend Font Color" ); - $this->setLangContent( - $this->lang, $lang . '_LEGENDTEXTSTYLEFONTSIZE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_LEGENDTEXTSTYLEFONTSIZE_DESC', "Set in pixels the font size of the legend" ); - $this->setLangContent( - $this->lang, $lang . '_LEGENDTEXTSTYLEFONTSIZE_HINT', "10" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_LEGENDTEXTSTYLEFONTSIZE_HINT', "10" ); - $this->setLangContent( - $this->lang, $lang . '_LEGENDTEXTSTYLEFONTSIZE_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_LEGENDTEXTSTYLEFONTSIZE_LABEL', "Legend Font Size" ); - $this->setLangContent( - $this->lang, $lang . '_MAINWIDTH_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAINWIDTH_DESC', "Set the width of the entire chart area" ); - $this->setLangContent( - $this->lang, $lang . '_MAINWIDTH_HINT', "1000" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAINWIDTH_HINT', "1000" ); - $this->setLangContent( - $this->lang, $lang . '_MAINWIDTH_LABEL', "Chart Area Width" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MAINWIDTH_LABEL', "Chart Area Width" ); - $this->setLangContent( - $this->lang, $lang . '_VAXISTEXTSTYLEFONTCOLOR_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_VAXISTEXTSTYLEFONTCOLOR_DESC', "Select the vertical axis font color." ); - $this->setLangContent( - $this->lang, $lang . '_VAXISTEXTSTYLEFONTCOLOR_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_VAXISTEXTSTYLEFONTCOLOR_LABEL', "vAxis Font Color" ); } @@ -26831,10 +24879,10 @@ function vdm_dkim() { // enable the loading of dynamic field sets $dynamicAddFields = array(); // Add encryption if needed - if ((isset($this->basicEncryption) && $this->basicEncryption) - || (isset($this->whmcsEncryption) && $this->whmcsEncryption) - || (isset($this->mediumEncryption) && $this->mediumEncryption) - || $this->componentData->add_license + if (CFactory::_('Config')->basic_encryption + || CFactory::_('Config')->whmcs_encryption + || CFactory::_('Config')->medium_encryption + || CFactory::_('Component')->get('add_license') || (isset($this->configFieldSetsCustomField['Encryption Settings']) && ArrayHelper::check( $this->configFieldSetsCustomField['Encryption Settings'] @@ -26842,74 +24890,70 @@ function vdm_dkim() { { $dynamicAddFields[] = "Encryption Settings"; // start building field set for encryption functions - $this->configFieldSets[] = $this->_t(1) . "configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(1) . "configFieldSets[] = Indent::_(2) . 'name="encryption_config"'; - $this->configFieldSets[] = $this->_t(2) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'label="' . $lang . '_ENCRYPTION_LABEL"'; - $this->configFieldSets[] = $this->_t(2) . 'description="' . $lang + $this->configFieldSets[] = Indent::_(2) . 'description="' . $lang . '_ENCRYPTION_DESC">'; // set tab lang - if (((isset($this->basicEncryption) && $this->basicEncryption) - || (isset($this->mediumEncryption) - && $this->mediumEncryption) - || (isset($this->whmcsEncryption) - && $this->whmcsEncryption)) - && $this->componentData->add_license - && $this->componentData->license_type == 3) + if ((CFactory::_('Config')->basic_encryption + || CFactory::_('Config')->medium_encryption + || CFactory::_('Config')->whmcs_encryption) + && CFactory::_('Component')->get('add_license') + && CFactory::_('Component')->get('license_type', 0) == 3) { - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_LABEL', "License & Encryption Settings" ); - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_DESC', "The license & encryption keys are set here." ); // add the next dynamic option $dynamicAddFields[] = "License & Encryption Settings"; } - elseif (((isset($this->basicEncryption) && $this->basicEncryption) - || (isset($this->mediumEncryption) - && $this->mediumEncryption) - || (isset($this->whmcsEncryption) - && $this->whmcsEncryption)) - && $this->componentData->add_license - && $this->componentData->license_type == 2) + elseif ((CFactory::_('Config')->basic_encryption + || CFactory::_('Config')->medium_encryption + || CFactory::_('Config')->whmcs_encryption) + && CFactory::_('Component')->get('add_license') + && CFactory::_('Component')->get('license_type', 0) == 2) { - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_LABEL', "Update & Encryption Settings" ); - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_DESC', "The update & encryption keys are set here." ); // add the next dynamic option $dynamicAddFields[] = "Update & Encryption Settings"; } - elseif ($this->componentData->add_license - && $this->componentData->license_type == 3) + elseif (CFactory::_('Component')->get('add_license') + && CFactory::_('Component')->get('license_type', 0) == 3) { - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_LABEL', "License Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_LABEL', "License Settings" ); - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_DESC', "The license key is set here." ); // add the next dynamic option $dynamicAddFields[] = "License Settings"; } - elseif ($this->componentData->add_license - && $this->componentData->license_type == 2) + elseif (CFactory::_('Component')->get('add_license') + && CFactory::_('Component')->get('license_type', 0) == 2) { - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_LABEL', "Update Settings" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_LABEL', "Update Settings" ); - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_DESC', "The update key is set here." ); // add the next dynamic option @@ -26917,209 +24961,209 @@ function vdm_dkim() { } else { - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_LABEL', "Encryption Settings" ); - $this->setLangContent( - $this->lang, $lang . '_ENCRYPTION_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_ENCRYPTION_DESC', "The encryption key for the field encryption is set here." ); } - if (isset($this->basicEncryption) && $this->basicEncryption) + if (CFactory::_('Config')->basic_encryption) { // set field lang - $this->setLangContent( - $this->lang, $lang . '_BASIC_KEY_LABEL', "Basic Key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_BASIC_KEY_LABEL', "Basic Key" ); - $this->setLangContent( - $this->lang, $lang . '_BASIC_KEY_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_BASIC_KEY_DESC', "Set the basic local key here." ); - $this->setLangContent( - $this->lang, $lang . '_BASIC_KEY_NOTE_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_BASIC_KEY_NOTE_LABEL', "Basic Encryption" ); - $this->setLangContent( - $this->lang, $lang . '_BASIC_KEY_NOTE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_BASIC_KEY_NOTE_DESC', "When using the basic encryption please use set a 32 character passphrase.
Never change this passphrase once it is set! DATA WILL GET CORRUPTED IF YOU DO!" ); // set the field - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ''; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_BASIC_KEY_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_BASIC_KEY_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; } - if (isset($this->mediumEncryption) && $this->mediumEncryption) + if (CFactory::_('Config')->medium_encryption) { // set field lang - $this->setLangContent( - $this->lang, $lang . '_MEDIUM_KEY_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MEDIUM_KEY_LABEL', "Medium Key (Path)" ); - $this->setLangContent( - $this->lang, $lang . '_MEDIUM_KEY_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MEDIUM_KEY_DESC', "Set the full path to where the key file must be stored. Make sure it is behind the root folder of your website, so that it is not public accessible." ); - $this->setLangContent( - $this->lang, $lang . '_MEDIUM_KEY_NOTE_LABEL', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MEDIUM_KEY_NOTE_LABEL', "Medium Encryption" ); - $this->setLangContent( - $this->lang, $lang . '_MEDIUM_KEY_NOTE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MEDIUM_KEY_NOTE_DESC', "When using the medium encryption option, the system generates its own key and stores it in a file at the folder/path you set here.
Never change this key once it is set, or remove the key file! DATA WILL GET CORRUPTED IF YOU DO! Also make sure the full path to where the the key file should be stored, is behind the root folder of your website/system, so that it is not public accessible. Making a backup of this key file over a secure connection is recommended!" ); // set the field - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ''; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_MEDIUM_KEY_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_MEDIUM_KEY_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="160"'; - $this->configFieldSets[] = $this->_t(3) . 'filter="PATH"'; - $this->configFieldSets[] = $this->_t(3) + $this->configFieldSets[] = Indent::_(3) . 'size="160"'; + $this->configFieldSets[] = Indent::_(3) . 'filter="PATH"'; + $this->configFieldSets[] = Indent::_(3) . 'hint="/home/user/hiddenfolder123/"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; // set some error message if the path does not exist - $this->setLangContent( - $this->lang, $lang . '_MEDIUM_KEY_PATH_ERROR', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_MEDIUM_KEY_PATH_ERROR', "Medium key path (for encryption of various fields) does not exist, or is not writable. Please check the path and update it in the global option of this component." ); } - if (isset($this->whmcsEncryption) && $this->whmcsEncryption - || $this->componentData->add_license) + if (CFactory::_('Config')->whmcs_encryption + || CFactory::_('Component')->get('add_license')) { // set field lang label and description - if ($this->componentData->add_license - && $this->componentData->license_type == 3) + if (CFactory::_('Component')->get('add_license') + && CFactory::_('Component')->get('license_type', 0) == 3) { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_LABEL', - $this->componentData->companyname . " License Key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_LABEL', + CFactory::_('Component')->get('companyname', '') . " License Key" ); - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_DESC', "Add the license key you recieved from " - . $this->componentData->companyname . " here." + . CFactory::_('Component')->get('companyname', '') . " here." ); } - elseif ($this->componentData->add_license - && $this->componentData->license_type == 2) + elseif (CFactory::_('Component')->get('add_license') + && CFactory::_('Component')->get('license_type', 0) == 2) { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_LABEL', - $this->componentData->companyname . " Update Key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_LABEL', + CFactory::_('Component')->get('companyname', '') . " Update Key" ); - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_DESC', "Add the update key you recieved from " - . $this->componentData->companyname . " here." + . CFactory::_('Component')->get('companyname', '') . " here." ); } else { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_LABEL', - $this->componentData->companyname . " Key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_LABEL', + CFactory::_('Component')->get('companyname', '') . " Key" ); - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_DESC', "Add the key you recieved from " - . $this->componentData->companyname . " here." + . CFactory::_('Component')->get('companyname', '') . " here." ); } // ajust the notice based on license - if ($this->componentData->license_type == 3) + if (CFactory::_('Component')->get('license_type',0) == 3) { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_NOTE_LABEL', - "Your " . $this->componentData->companyname + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_NOTE_LABEL', + "Your " . CFactory::_('Component')->get('companyname','') . " License Key" ); } - elseif ($this->componentData->license_type == 2) + elseif (CFactory::_('Component')->get('license_type',0) == 2) { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_NOTE_LABEL', - "Your " . $this->componentData->companyname + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_NOTE_LABEL', + "Your " . CFactory::_('Component')->get('companyname','') . " Update Key" ); } else { - if (isset($this->whmcsEncryption) && $this->whmcsEncryption) + if (CFactory::_('Config')->whmcs_encryption) { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_NOTE_LABEL', - "Your " . $this->componentData->companyname + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_NOTE_LABEL', + "Your " . CFactory::_('Component')->get('companyname','') . " Field Encryption Key" ); } else { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_NOTE_LABEL', - "Your " . $this->componentData->companyname . " Key" + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_NOTE_LABEL', + "Your " . CFactory::_('Component')->get('companyname','') . " Key" ); } } // add the description based on global settings - if (isset($this->whmcsEncryption) && $this->whmcsEncryption) + if (CFactory::_('Config')->whmcs_encryption) { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_NOTE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_NOTE_DESC', "You need to get this key from
get('whmcs_buy_link','') . "' target='_blank'>" - . $this->componentData->companyname + . CFactory::_('Component')->get('companyname','') . ".
When using the " - . $this->componentData->companyname + . CFactory::_('Component')->get('companyname','') . " field encryption you can never change this key once it is set! DATA WILL GET CORRUPTED IF YOU DO!" ); } else { - $this->setLangContent( - $this->lang, $lang . '_WHMCS_KEY_NOTE_DESC', + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, $lang . '_WHMCS_KEY_NOTE_DESC', "You need to get this key from get('whmcs_buy_link','') . "' target='_blank'>" - . $this->componentData->companyname . "." + . CFactory::_('Component')->get('companyname','') . "." ); } // set the fields - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . ''; - $this->configFieldSets[] = $this->_t(2) + $this->configFieldSets[] = Indent::_(2) . 'configFieldSets[] = $this->_t(3) . 'type="text"'; - $this->configFieldSets[] = $this->_t(3) . 'label="' . $lang + $this->configFieldSets[] = Indent::_(3) . 'type="text"'; + $this->configFieldSets[] = Indent::_(3) . 'label="' . $lang . '_WHMCS_KEY_LABEL"'; - $this->configFieldSets[] = $this->_t(3) . 'description="' + $this->configFieldSets[] = Indent::_(3) . 'description="' . $lang . '_WHMCS_KEY_DESC"'; - $this->configFieldSets[] = $this->_t(3) . 'size="60"'; - $this->configFieldSets[] = $this->_t(3) . 'default=""'; - $this->configFieldSets[] = $this->_t(2) . "/>"; + $this->configFieldSets[] = Indent::_(3) . 'size="60"'; + $this->configFieldSets[] = Indent::_(3) . 'default=""'; + $this->configFieldSets[] = Indent::_(2) . "/>"; } // load the dynamic field sets foreach ($dynamicAddFields as $dynamicAddField) @@ -27137,34 +25181,30 @@ function vdm_dkim() { } } // close that fieldset - $this->configFieldSets[] = $this->_t(1) . ""; + $this->configFieldSets[] = Indent::_(1) . ""; } } - public function setAccessSectionsCategory($nameSingleCode, $nameListCode - ) + public function setAccessSectionsCategory($nameSingleCode, $nameListCode) { $component = ''; // check if view has category - if (array_key_exists($nameSingleCode, $this->catCodeBuilder)) + $otherViews = CFactory::_('Compiler.Builder.Category.Code')->getString("{$nameSingleCode}.views"); + if ($otherViews !== null && $otherViews == $nameListCode) { - $otherViews = $this->catCodeBuilder[$nameSingleCode]['views']; - if ($otherViews == $nameListCode) - { - $component .= PHP_EOL . $this->_t(1) - . '
'; - $component .= PHP_EOL . $this->_t(2) - . ''; - $component .= PHP_EOL . $this->_t(2) - . ''; - $component .= PHP_EOL . $this->_t(2) - . ''; - $component .= PHP_EOL . $this->_t(2) - . ''; - $component .= PHP_EOL . $this->_t(2) - . ''; - $component .= PHP_EOL . $this->_t(1) . "
"; - } + $component .= PHP_EOL . Indent::_(1) + . '
'; + $component .= PHP_EOL . Indent::_(2) + . ''; + $component .= PHP_EOL . Indent::_(2) + . ''; + $component .= PHP_EOL . Indent::_(2) + . ''; + $component .= PHP_EOL . Indent::_(2) + . ''; + $component .= PHP_EOL . Indent::_(2) + . ''; + $component .= PHP_EOL . Indent::_(1) . "
"; } return $component; @@ -27174,30 +25214,30 @@ function vdm_dkim() { { $component = ''; // set all the core field permissions - $component .= PHP_EOL . $this->_t(1) . '
'; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(1) . '
'; + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(1) . '
'; - $component .= PHP_EOL . $this->_t(1) . '
'; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(1) . '
'; + $component .= PHP_EOL . Indent::_(1) . '
'; + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(2) + $component .= PHP_EOL . Indent::_(2) . ''; - $component .= PHP_EOL . $this->_t(1) . '
'; + $component .= PHP_EOL . Indent::_(1) . '
'; return $component; } @@ -27205,104 +25245,137 @@ function vdm_dkim() { public function setAccessSections() { // access size counter - $this->accessSize = 12; // ;) - // set the default component access values - $this->componentHead = array(); - $this->componentGlobal = array(); - $this->permissionViews = array(); + CFactory::_('Utilities.Counter')->accessSize = 12; // ;) + // Get the default fields + $default_fields = CFactory::_('Config')->default_fields; + + // for plugin event TODO change event api signatures + $component_context = CFactory::_('Config')->component_context; // Trigger Event: jcb_ce_onBeforeBuildAccessSections - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildAccessSections', - array(&$this->componentContext, &$this) + array(&$component_context, &$this) ); - - $this->componentHead[] = '
'; - - $this->componentHead[] = $this->_t(2) - . ''; - $this->componentHead[] = $this->_t(2) - . ''; - $this->componentHead[] = $this->_t(2) - . ''; - if ($this->addEximport) + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.admin', + 'title' => 'JACTION_ADMIN', + 'description' => 'JACTION_ADMIN_COMPONENT_DESC' + ], true); + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.options', + 'title' => 'JACTION_OPTIONS', + 'description' => 'JACTION_OPTIONS_COMPONENT_DESC' + ], true); + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.manage', + 'title' => 'JACTION_MANAGE', + 'description' => 'JACTION_MANAGE_COMPONENT_DESC' + ], true); + if (CFactory::_('Config')->get('add_eximport', false)) { $exportTitle = $this->langPrefix . '_' . StringHelper::safe('Export Data', 'U'); $exportDesc = $this->langPrefix . '_' . StringHelper::safe('Export Data', 'U') . '_DESC'; - $this->setLangContent('bothadmin', $exportTitle, 'Export Data'); - $this->setLangContent( + CFactory::_('Language')->set('bothadmin', $exportTitle, 'Export Data'); + CFactory::_('Language')->set( 'bothadmin', $exportDesc, ' Allows users in this group to export data.' ); - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.export', + 'title' => $exportTitle, + 'description' => $exportDesc + ], true); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; $importTitle = $this->langPrefix . '_' . StringHelper::safe('Import Data', 'U'); $importDesc = $this->langPrefix . '_' . StringHelper::safe('Import Data', 'U') . '_DESC'; - $this->setLangContent('bothadmin', $importTitle, 'Import Data'); - $this->setLangContent( + CFactory::_('Language')->set('bothadmin', $importTitle, 'Import Data'); + CFactory::_('Language')->set( 'bothadmin', $importDesc, ' Allows users in this group to import data.' ); - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.import', + 'title' => $importTitle, + 'description' => $importDesc + ], true); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; } // version permission $batchTitle = $this->langPrefix . '_' . StringHelper::safe('Use Batch', 'U'); $batchDesc = $this->langPrefix . '_' . StringHelper::safe('Use Batch', 'U') . '_DESC'; - $this->setLangContent('bothadmin', $batchTitle, 'Use Batch'); - $this->setLangContent( + CFactory::_('Language')->set('bothadmin', $batchTitle, 'Use Batch'); + CFactory::_('Language')->set( 'bothadmin', $batchDesc, ' Allows users in this group to use batch copy/update method.' ); - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.batch', + 'title' => $batchTitle, + 'description' => $batchDesc + ], true); // version permission $importTitle = $this->langPrefix . '_' . StringHelper::safe('Edit Versions', 'U'); $importDesc = $this->langPrefix . '_' . StringHelper::safe('Edit Versions', 'U') . '_DESC'; - $this->setLangContent('bothadmin', $importTitle, 'Edit Version'); - $this->setLangContent( + CFactory::_('Language')->set('bothadmin', $importTitle, 'Edit Version'); + CFactory::_('Language')->set( 'bothadmin', $importDesc, ' Allows users in this group to edit versions.' ); - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.version', + 'title' => $importTitle, + 'description' => $importDesc + ], true); // set the defaults - $this->componentHead[] = $this->_t(2) - . ''; - $this->componentHead[] = $this->_t(2) - . ''; - $this->componentHead[] = $this->_t(2) - . ''; - $this->componentHead[] = $this->_t(2) - . ''; - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.create', + 'title' => 'JACTION_CREATE', + 'description' => 'JACTION_CREATE_COMPONENT_DESC' + ], true); + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.delete', + 'title' => 'JACTION_DELETE', + 'description' => 'JACTION_DELETE_COMPONENT_DESC' + ], true); + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.edit', + 'title' => 'JACTION_EDIT', + 'description' => 'JACTION_EDIT_COMPONENT_DESC' + ], true); + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.edit.state', + 'title' => 'JACTION_EDITSTATE', + 'description' => 'JACTION_ACCESS_EDITSTATE_DESC' + ], true); + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.edit.own', + 'title' => 'JACTION_EDITOWN', + 'description' => 'JACTION_EDITOWN_COMPONENT_DESC' + ], true); // set the Joomla fields - if ($this->setJoomlaFields) + if (CFactory::_('Config')->get('set_joomla_fields', false)) { - $this->componentHead[] = $this->_t(2) - . ' '; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.edit.value', + 'title' => 'JACTION_EDITVALUE', + 'description' => 'JACTION_EDITVALUE_COMPONENT_DESC' + ], true); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; } // new custom created by permissions $created_byTitle = $this->langPrefix . '_' @@ -27310,40 +25383,40 @@ function vdm_dkim() { $created_byDesc = $this->langPrefix . '_' . StringHelper::safe('Edit Created By', 'U') . '_DESC'; - $this->setLangContent('bothadmin', $created_byTitle, 'Edit Created By'); - $this->setLangContent( + CFactory::_('Language')->set('bothadmin', $created_byTitle, 'Edit Created By'); + CFactory::_('Language')->set( 'bothadmin', $created_byDesc, ' Allows users in this group to edit created by.' ); - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.edit.created_by', + 'title' => $created_byTitle, + 'description' => $created_byDesc + ], true); // new custom created date permissions $createdTitle = $this->langPrefix . '_' . StringHelper::safe('Edit Created Date', 'U'); $createdDesc = $this->langPrefix . '_' . StringHelper::safe('Edit Created Date', 'U') . '_DESC'; - $this->setLangContent('bothadmin', $createdTitle, 'Edit Created Date'); - $this->setLangContent( + CFactory::_('Language')->set('bothadmin', $createdTitle, 'Edit Created Date'); + CFactory::_('Language')->set( 'bothadmin', $createdDesc, ' Allows users in this group to edit created date.' ); - $this->componentHead[] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->add('->HEAD<-', [ + 'name' => 'core.edit.created', + 'title' => $createdTitle, + 'description' => $createdDesc + ], true); // set the menu controller lookup - $menuControllers = array('access', 'submenu', 'dashboard_list', - 'dashboard_add'); + $menuControllers = ['access', 'submenu', 'dashboard_list', 'dashboard_add']; // set the custom admin views permissions - if (isset($this->componentData->custom_admin_views) - && ArrayHelper::check( - $this->componentData->custom_admin_views - )) + if (CFactory::_('Component')->isArray('custom_admin_views')) { foreach ( - $this->componentData->custom_admin_views as $custom_admin_view + CFactory::_('Component')->get('custom_admin_views') as $custom_admin_view ) { // new custom permissions to access this view @@ -27360,21 +25433,22 @@ function vdm_dkim() { $sortKey = StringHelper::safe( $customAdminName . ' Access' ); - $this->setLangContent( + CFactory::_('Language')->set( 'bothadmin', $customAdminTitle, $customAdminName . ' Access' ); - $this->setLangContent( + CFactory::_('Language')->set( 'bothadmin', $customAdminDesc, ' Allows the users in this group to access ' . StringHelper::safe($customAdminName, 'w') . '.' ); - $this->componentGlobal[$sortKey] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->set($sortKey, [ + 'name' => "$customAdminCode.access", + 'title' => $customAdminTitle, + 'description' => $customAdminDesc + ]); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; // add the custom permissions to use the buttons of this view $this->addCustomButtonPermissions( $custom_admin_view['settings'], $customAdminName, @@ -27416,19 +25490,16 @@ function vdm_dkim() { unset($menucontrollerView); } } - $this->buildPermissions( + CFactory::_('Compiler.Creator.Permission')->set( $custom_admin_view, $customAdminCode, $customAdminCode, $menuControllers, 'customAdmin' ); } } // set the site views permissions - if (isset($this->componentData->site_views) - && ArrayHelper::check( - $this->componentData->site_views - )) + if (CFactory::_('Component')->isArray('site_views')) { - foreach ($this->componentData->site_views as $site_view) + foreach (CFactory::_('Component')->get('site_views') as $site_view) { // new custom permissions to access this view $siteName = $site_view['settings']->name; @@ -27446,20 +25517,22 @@ function vdm_dkim() { ); if (isset($site_view['access']) && $site_view['access'] == 1) { - $this->setLangContent( + CFactory::_('Language')->set( 'bothadmin', $siteTitle, $siteName . ' (Site) Access' ); - $this->setLangContent( + CFactory::_('Language')->set( 'bothadmin', $siteDesc, ' Allows the users in this group to access site ' . StringHelper::safe($siteName, 'w') . '.' ); - $this->componentGlobal[$sortKey] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->set($sortKey, [ + 'name' => "site.$siteCode.access", + 'title' => $siteTitle, + 'description' => $siteDesc + ]); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; // check if this site view requires access rule to default to public if (isset($site_view['public_access']) && $site_view['public_access'] == 1) @@ -27475,12 +25548,9 @@ function vdm_dkim() { ); } } - if (isset($this->componentData->admin_views) - && ArrayHelper::check( - $this->componentData->admin_views - )) + if (CFactory::_('Component')->isArray('admin_views')) { - foreach ($this->componentData->admin_views as $view) + foreach (CFactory::_('Component')->get('admin_views') as $view) { // set view name $nameView = StringHelper::safe( @@ -27490,25 +25560,21 @@ function vdm_dkim() { $view['settings']->name_list ); // add custom tab permissions if found - if (isset($this->customTabs[$nameView]) - && ArrayHelper::check( - $this->customTabs[$nameView] - )) + if (($tabs_ = CFactory::_('Compiler.Builder.Custom.Tabs')->get($nameView)) !== null + && ArrayHelper::check($tabs_)) { - foreach ($this->customTabs[$nameView] as $_customTab) + foreach ($tabs_ as $_customTab) { if (isset($_customTab['permission']) && $_customTab['permission'] == 1) { - $this->componentGlobal[$_customTab['sortKey']] - = $this->_t(2) . ''; + CFactory::_('Compiler.Builder.Permission.Component')->set($_customTab['sortKey'], [ + 'name' => $_customTab['view'] . '.' . $_customTab['code'] . '.viewtab', + 'title' => $_customTab['lang_permission'], + 'description' => $_customTab['lang_permission_desc'] + ]); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; } } } @@ -27531,8 +25597,7 @@ function vdm_dkim() { $targetView_ = 'view.'; } // menucontroller - $menucontrollerView['action'] = $targetView_ - . $menuController; + $menucontrollerView['action'] = $targetView_ . $menuController; $menucontrollerView['implementation'] = '2'; if (isset($view['settings']->permissions) && ArrayHelper::check( @@ -27547,8 +25612,7 @@ function vdm_dkim() { else { $view['settings']->permissions = array(); - $view['settings']->permissions[] - = $menucontrollerView; + $view['settings']->permissions[] = $menucontrollerView; } unset($menucontrollerView); } @@ -27559,8 +25623,7 @@ function vdm_dkim() { )) { // field permission options - $permission_options = array(1 => 'edit', 2 => 'access', - 3 => 'view'); + $permission_options = array(1 => 'edit', 2 => 'access', 3 => 'view'); // check the fields for their permission settings foreach ($view['settings']->fields as $field) { @@ -27574,24 +25637,19 @@ function vdm_dkim() { $field['settings']->properties )) { - $fieldType = $this->getFieldType($field); - $fieldName = $this->getFieldName( + $fieldType = CFactory::_('Field.Type.Name')->get($field); + $fieldName = CFactory::_('Field.Name')->get( $field, $nameViews ); // loop the permission options - foreach ( - $field['permission'] as $permission_id - ) + foreach ($field['permission'] as $permission_id) { // set the permission key word - $permission_option - = $permission_options[(int) $permission_id]; + $permission_option = $permission_options[(int) $permission_id]; // reset the bucket $fieldView = array(); // set the permission for this field - $fieldView['action'] = 'view.' - . $permission_option . '.' - . $fieldName; + $fieldView['action'] = 'view.' . $permission_option . '.' . $fieldName; $fieldView['implementation'] = '3'; // check if persmissions was already set if (isset($view['settings']->permissions) @@ -27606,14 +25664,13 @@ function vdm_dkim() { } else { - $view['settings']->permissions - = array(); + $view['settings']->permissions = array(); $view['settings']->permissions[] = $fieldView; } - // insure that no default field get loaded + // ensure that no default field get loaded if (!in_array( - $fieldName, $this->defaultFields + $fieldName, $default_fields )) { // make sure the array is set @@ -27642,63 +25699,42 @@ function vdm_dkim() { } } } - $this->buildPermissions( + CFactory::_('Compiler.Creator.Permission')->set( $view, $nameView, $nameViews, $menuControllers ); } } // Trigger Event: jcb_ce_onAfterBuildAccessSections - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildAccessSections', - array(&$this->componentContext, &$this) + array(&$component_context, &$this) ); - // set the views permissions now - if (ArrayHelper::check($this->permissionViews)) - { - foreach ($this->permissionViews as $viewsCodeName => $actions) - { - $componentViews[] = $this->_t(1) . '
'; - foreach ($actions as $action) - { - $componentViews[] = $this->_t(2) . $action; - } - $componentViews[] = $this->_t(1) . "
"; - } - } /// now build the section - $component = implode(PHP_EOL, $this->componentHead); - // sort the array to insure easy search - ksort($this->componentGlobal, SORT_STRING); - // add global to the compnent section - $component .= PHP_EOL . implode(PHP_EOL, $this->componentGlobal) - . PHP_EOL . $this->_t(1) . "
"; + $component = CFactory::_('Compiler.Builder.Permission.Component')->build(); // add views to the component section - $component .= PHP_EOL . implode(PHP_EOL, $componentViews); - // be sure to reset again. (memory) - $this->componentHead = null; - $this->componentGlobal = null; - $this->permissionViews = null; + $component .= CFactory::_('Compiler.Builder.Permission.Views')->build(); // remove the fix, is not needed - if ($this->accessSize < 30) + if (CFactory::_('Utilities.Counter')->accessSize < 30) { // since we have less than 30 actions // we do not need the fix for this component $this->addAssetsTableFix = 0; + CFactory::_('Config')->set('add_assets_table_fix', $this->addAssetsTableFix); } else { - // get the worse case column size required (can be worse I know) + // get the worst case column size required (can be worse I know) // access/action size x 20 characters x 8 groups - $character_length = (int) MathHelper::bc( - 'mul', $this->accessSize, 20, 0 + $character_length = (int) MathHelper::bc( + 'mul', CFactory::_('Utilities.Counter')->accessSize, 20, 0 ); - $this->accessWorseCase = (int) MathHelper::bc( + // set worse case + CFactory::_('Config')->set('access_worse_case', (int) MathHelper::bc( 'mul', $character_length, 8, 0 - ); + )); } // return the build @@ -27733,458 +25769,43 @@ function vdm_dkim() { $sortButtonKey = StringHelper::safe( $nameView . ' ' . $customButtonName . ' Button Access' ); - $this->setLangContent( + CFactory::_('Language')->set( 'bothadmin', $customButtonTitle, $nameView . ' ' . $customButtonName . ' Button Access' ); - $this->setLangContent( + CFactory::_('Language')->set( 'bothadmin', $customButtonDesc, ' Allows the users in this group to access the ' . StringHelper::safe($customButtonName, 'w') . ' button.' ); - $this->componentGlobal[$sortButtonKey] = $this->_t(2) - . ''; + CFactory::_('Compiler.Builder.Permission.Component')->set($sortButtonKey, [ + 'name' => "$code.$customButtonCode", + 'title' => $customButtonTitle, + 'description' => $customButtonDesc + ]); // the size needs increase - $this->accessSize++; + CFactory::_('Utilities.Counter')->accessSize++; } } } - public function buildPermissions(&$view, $nameView, $nameViews, - $menuControllers, $type = 'admin' + /** + * Set the permissions + * + * @param array $view View details + * @param string $nameView View Single Code Name + * @param string $nameViews View List Code Name + * @param array $menuControllers Menu Controllers + * @param string $type Type of permissions area + * + * @return void + * @deprecated 3.3 Use CFactory::_('Compiler.Creator.Permission')->set($view, $nameView, $nameViews, $menuControllers, $type); + */ + public function buildPermissions(&$view, $nameView, $nameViews, $menuControllers, $type = 'admin' ) { - if (isset($view['settings']->permissions) - && ArrayHelper::check( - $view['settings']->permissions - ) - || (isset($view['port']) && $view['port']) - || (isset($view['history']) && $view['history'])) - { - // add export/import permissions to each view that has export/import options - if (isset($view['port']) && $view['port']) - { - // export - $exportView['action'] = 'view.export'; - $exportView['implementation'] = '2'; - if (ArrayHelper::check( - $view['settings']->permissions - )) - { - array_push($view['settings']->permissions, $exportView); - } - else - { - $view['settings']->permissions = array(); - $view['settings']->permissions[] = $exportView; - } - // import - $importView['action'] = 'view.import'; - $importView['implementation'] = '2'; - if (ArrayHelper::check( - $view['settings']->permissions - )) - { - array_push($view['settings']->permissions, $importView); - } - else - { - $view['settings']->permissions = array(); - $view['settings']->permissions[] = $importView; - } - } - // add version opstions to each view that has it added - if (isset($view['history']) && $view['history']) - { - // set version control - $versionView['action'] = 'view.version'; - $versionView['implementation'] = '3'; - if (ArrayHelper::check( - $view['settings']->permissions - )) - { - array_push($view['settings']->permissions, $versionView); - } - else - { - $view['settings']->permissions = array(); - $view['settings']->permissions[] = $versionView; - } - } - // add batch permissions - if ($type === 'admin') - { - // set batch control - $batchView['action'] = 'view.batch'; - $batchView['implementation'] = '2'; - if (ArrayHelper::check( - $view['settings']->permissions - )) - { - array_push($view['settings']->permissions, $batchView); - } - else - { - $view['settings']->permissions = array(); - $view['settings']->permissions[] = $batchView; - } - } - // load the permissions - foreach ($view['settings']->permissions as $permission) - { - // set acction name - $arr = explode('.', trim($permission['action'])); - if ($arr[0] != 'core' || $arr[0] === 'view') - { - array_shift($arr); - $actionMain = implode('.', $arr); - $action = $nameView . '.' . $actionMain; - } - else - { - if ($arr[0] === 'core') - { - // core is already set in global access - $permission['implementation'] = 1; - } - $action = $permission['action']; - } - // build action name - $actionNameBuilder = explode('.', trim($permission['action'])); - array_shift($actionNameBuilder); - $nameBuilder = trim(implode('___', $actionNameBuilder)); - $customName = trim(implode(' ', $actionNameBuilder)); - // check if we have access set for this view (if not skip) - if ($nameBuilder === 'edit___access' && $type === 'admin' - && (!isset($view['access']) || $view['access'] != 1)) - { - continue; - } - // build the names - if ($type === 'admin') - { - $W_NameList = StringHelper::safe( - $view['settings']->name_list, 'W' - ); - $w_NameList = StringHelper::safe( - $customName . ' ' . $view['settings']->name_list, 'w' - ); - $w_NameSingle = StringHelper::safe( - $view['settings']->name_single, 'w' - ); - } - elseif ($type === 'customAdmin') - { - $W_NameList = StringHelper::safe( - $view['settings']->name, 'W' - ); - $w_NameList = $view['settings']->name; - $w_NameSingle = $view['settings']->name; - } - // set title (only if not set already) - if (!isset($permission['title']) - || !StringHelper::check( - $permission['title'] - )) - { - // set the title based on the name builder - switch ($nameBuilder) - { - case 'edit': - // set edit title - $permission['title'] = $W_NameList . ' Edit'; - break; - case 'edit___own': - // set edit title - $permission['title'] = $W_NameList . ' Edit Own'; - break; - case 'edit___access': - // set edit title - $permission['title'] = $W_NameList . ' Edit Access'; - break; - case 'edit___state': - // set edit title - $permission['title'] = $W_NameList . ' Edit State'; - break; - case 'edit___created_by': - // set edit title - $permission['title'] = $W_NameList - . ' Edit Created By'; - break; - case 'edit___created': - // set edit title - $permission['title'] = $W_NameList - . ' Edit Created Date'; - break; - case 'create': - // set edit title - $permission['title'] = $W_NameList . ' Create'; - break; - case 'delete': - // set edit title - $permission['title'] = $W_NameList . ' Delete'; - break; - case 'access': - // set edit title - $permission['title'] = $W_NameList . ' Access'; - break; - case 'export': - // set edit title - $permission['title'] = $W_NameList . ' Export'; - break; - case 'import': - // set edit title - $permission['title'] = $W_NameList . ' Import'; - break; - case 'version': - // set edit title - $permission['title'] = $W_NameList - . ' Edit Version'; - break; - case 'batch': - // set edit title - $permission['title'] = $W_NameList . ' Batch Use'; - break; - default: - // set edit title - $permission['title'] = $W_NameList . ' ' - . StringHelper::safe( - $customName, 'W' - ); - break; - } - } - // set description (only if not set already) - if (!isset($permission['description']) - || !StringHelper::check( - $permission['description'] - )) - { - // set the title based on the name builder - switch ($nameBuilder) - { - case 'edit': - // set edit description - $permission['description'] - = ' Allows the users in this group to edit the ' - . $w_NameSingle; - break; - case 'edit___own': - // set edit description - $permission['description'] - = ' Allows the users in this group to edit ' - . $w_NameList . ' created by them'; - break; - case 'edit___access': - // set edit description - $permission['description'] - = ' Allows the users in this group to change the access of the ' - . $w_NameList; - break; - case 'edit___state': - // set edit description - $permission['description'] - = ' Allows the users in this group to update the state of the ' - . $w_NameSingle; - break; - case 'edit___created_by': - // set edit description - $permission['description'] - = ' Allows the users in this group to update the created by of the ' - . $w_NameList; - break; - case 'edit___created': - // set edit description - $permission['description'] - = ' Allows the users in this group to update the created date of the ' - . $w_NameList; - break; - case 'create': - // set edit description - $permission['description'] - = ' Allows the users in this group to create ' - . $w_NameList; - break; - case 'delete': - // set edit description - $permission['description'] - = ' Allows the users in this group to delete ' - . $w_NameList; - break; - case 'access': - // set edit description - $permission['description'] - = ' Allows the users in this group to access ' - . $w_NameList; - break; - case 'export': - // set edit description - $permission['description'] - = ' Allows the users in this group to export ' - . $w_NameList; - break; - case 'import': - // set edit description - $permission['description'] - = ' Allows the users in this group to import ' - . $w_NameList; - break; - case 'version': - // set edit description - $permission['description'] - = ' Allows users in this group to edit versions of ' - . $w_NameList; - break; - case 'batch': - // set edit description - $permission['description'] - = ' Allows users in this group to use batch copy/update method of ' - . $w_NameList; - break; - default: - // set edit description - $permission['description'] - = ' Allows the users in this group to ' - . StringHelper::safe( - $customName, 'w' - ) . ' of ' . $w_NameSingle; - break; - } - } - // if core is not used update all core strings - $coreCheck = explode( - '.', $action - ); - $coreCheck[0] = 'core'; - $coreTarget = implode( - '.', $coreCheck - ); - $this->permissionCore[$nameView][$coreTarget] = $action; - // set array sort name - $sortKey = StringHelper::safe( - $permission['title'] - ); - // set title - $title = $this->langPrefix . '_' - . StringHelper::safe( - $permission['title'], 'U' - ); - // load the actions - if ($permission['implementation'] == 1) - { - // only related to view - $this->permissionViews[$nameView][] = ''; - // load permission to action - $this->permissionBuilder[$action][$nameView] = $nameView; - } - elseif ($permission['implementation'] == 2) - { - // relation to whole component - $this->componentGlobal[$sortKey] = $this->_t(2) - . ''; - // the size needs increase - $this->accessSize++; - // build permission switch - $this->permissionBuilder['global'][$action][$nameView] - = $nameView; - // dashboard icon checker - if ($coreTarget === 'core.access') - { - $this->permissionDashboard[] = "'" . $nameViews - . ".access' => '" . $action . "'"; - $this->permissionDashboard[] = "'" . $nameView - . ".access' => '" . $action . "'"; - } - if ($coreTarget === 'core.create') - { - $this->permissionDashboard[] = "'" . $nameView - . ".create' => '" . $action . "'"; - } - // add menu controll view that has menus options - foreach ($menuControllers as $menuController) - { - if ($coreTarget === 'core.' . $menuController) - { - if ($menuController === 'dashboard_add') - { - $this->permissionDashboard[] = "'" . $nameView - . "." . $menuController . "' => '" . $action - . "'"; - } - else - { - $this->permissionDashboard[] = "'" . $nameViews - . "." . $menuController . "' => '" . $action - . "'"; - } - } - } - } - elseif ($permission['implementation'] == 3) - { - // only related to view - $this->permissionViews[$nameView][] = ''; - // load permission to action - $this->permissionBuilder[$action][$nameView] = $nameView; - // relation to whole component - $this->componentGlobal[$sortKey] = $this->_t(2) - . ''; - // the size needs increase - $this->accessSize++; - // build permission switch - $this->permissionBuilder['global'][$action][$nameView] - = $nameView; - // dashboard icon checker - if ($coreTarget === 'core.access') - { - $this->permissionDashboard[] = "'" . $nameViews - . ".access' => '" . $action . "'"; - $this->permissionDashboard[] = "'" . $nameView - . ".access' => '" . $action . "'"; - } - if ($coreTarget === 'core.create') - { - $this->permissionDashboard[] = "'" . $nameView - . ".create' => '" . $action . "'"; - } - // add menu controll view that has menus options - foreach ($menuControllers as $menuController) - { - if ($coreTarget === 'core.' . $menuController) - { - if ($menuController === 'dashboard_add') - { - $this->permissionDashboard[] = "'" . $nameView - . "." . $menuController . "' => '" . $action - . "'"; - } - else - { - $this->permissionDashboard[] = "'" . $nameViews - . "." . $menuController . "' => '" . $action - . "'"; - } - } - } - } - // set to language file - $this->setLangContent( - 'bothadmin', $title, $permission['title'] - ); - $this->setLangContent( - 'bothadmin', $title . '_DESC', $permission['description'] - ); - } - } + CFactory::_('Compiler.Creator.Permission')->set($view, $nameView, $nameViews, $menuControllers, $type); } public function getInbetweenStrings($str, $start = '#' . '#' . '#', @@ -28193,7 +25814,7 @@ function vdm_dkim() { { $matches = array(); $regex = "/$start([a-zA-Z0-9_]*)$end/"; - preg_match_all($regex, $str, $matches); + preg_match_all($regex, (string) $str, $matches); return $matches[1]; } @@ -28201,31 +25822,28 @@ function vdm_dkim() { public function getModCode(&$module) { // get component helper string - $Helper = $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] . 'Helper'; - $component = $this->fileContentStatic[$this->hhh . 'component' - . $this->hhh]; + $Helper = CFactory::_('Compiler.Builder.Content.One')->get('Component') . 'Helper'; + $component = CFactory::_('Compiler.Builder.Content.One')->get('component'); $_helper = ''; // get libraries code - $libraries = array($this->bbb . 'MOD_LIBRARIES' - . $this->ddd => $this->getModLibCode($module)); - $code = $this->setPlaceholders($module->mod_code, $libraries); + $libraries = array(Placefix::_('MOD_LIBRARIES') => $this->getModLibCode($module)); + $code = CFactory::_('Placeholder')->update($module->mod_code, $libraries); // check if component helper class should be added - if (strpos($code, $Helper . '::') !== false + if (strpos((string) $code, $Helper . '::') !== false && strpos( - $code, + (string) $code, "/components/com_" . $component . "/helpers/" . $component . ".php" ) === false) { - $_helper = '//' . $this->setLine(__LINE__) + $_helper = '//' . Line::_(__Line__, __Class__) . ' Include the component helper functions only once'; $_helper .= PHP_EOL . "JLoader::register('" . $Helper . "', JPATH_ADMINISTRATOR . '/components/com_" . $component . "/helpers/" . $component . ".php');"; } - return $this->setPlaceholders($_helper . PHP_EOL . $code . PHP_EOL, $this->fileContentStatic); + return CFactory::_('Placeholder')->update($_helper . PHP_EOL . $code . PHP_EOL, CFactory::_('Compiler.Builder.Content.One')->allActive()); } public function getModDefault(&$module, &$key) @@ -28233,65 +25851,77 @@ function vdm_dkim() { // first add the header $default = PHP_EOL . $module->default_header . PHP_EOL . '?>'; // add any css from the fields - $default .= $this->getCustomScriptBuilder( + $default .= CFactory::_('Customcode.Dispenser')->get( 'css_views', $key, PHP_EOL . '' . PHP_EOL ); // now add the body $default .= PHP_EOL . $module->default . PHP_EOL; // add any JavaScript from the fields - $default .= $this->getCustomScriptBuilder( + $default .= CFactory::_('Customcode.Dispenser')->get( 'views_footer', $key, PHP_EOL . '' . PHP_EOL ); // return the default content for the model default area - return $this->setPlaceholders($default, $this->fileContentStatic); + return CFactory::_('Placeholder')->update($default, CFactory::_('Compiler.Builder.Content.One')->allActive()); + } + + public function setModTemplates(&$module) + { + if (($data_ = CFactory::_('Compiler.Builder.Template.Data')-> + get(CFactory::_('Config')->build_target . '.' . $module->code_name)) !== null) + { + foreach ($data_ as $template => $data) + { + $header = $data['php_view'] ?? ''; + $body = $data['html'] ?? ''; + $default = PHP_EOL . $header . PHP_EOL . '?>'; + $default .= PHP_EOL . $body; + $TARGET = StringHelper::safe("MODDEFAULT_{$template}", 'U'); + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|' . $TARGET, + CFactory::_('Placeholder')->update( + $default, CFactory::_('Compiler.Builder.Content.One')->allActive() + ) + ); + } + } } public function getModHelperCode(&$module) { return - $this->setPlaceholders($module->class_helper_header . PHP_EOL . + CFactory::_('Placeholder')->update($module->class_helper_header . PHP_EOL . $module->class_helper_type . $module->class_helper_name . PHP_EOL . '{' . PHP_EOL . $module->class_helper_code . PHP_EOL . - "}" . PHP_EOL, $this->fileContentStatic); + "}" . PHP_EOL, CFactory::_('Compiler.Builder.Content.One')->allActive()); } public function getModLibCode(&$module) { $setter = ''; - if (isset($this->libManager[$module->key][$module->code_name]) - && ArrayHelper::check( - $this->libManager[$module->key][$module->code_name] - )) + if (($data_ = CFactory::_('Compiler.Builder.Library.Manager')-> + get($module->key . '.' . $module->code_name)) !== null) { - $setter .= '//' . $this->setLine(__LINE__) + $setter .= '//' . Line::_(__Line__, __Class__) . 'get the document object'; $setter .= PHP_EOL . '$document = JFactory::getDocument();'; - foreach ( - $this->libManager[$module->key][$module->code_name] as $id => - $true - ) + foreach ($data_ as $id => $true) { - if (isset($this->libraries[$id]) - && ObjectHelper::check( - $this->libraries[$id] - ) - && isset($this->libraries[$id]->document) + // get the library + $library = CFactory::_('Registry')->get("builder.libraries.$id", null); + if (is_object($library) + && isset($library->document) && StringHelper::check( - $this->libraries[$id]->document + $library->document )) { - $setter .= PHP_EOL . $this->libraries[$id]->document; + $setter .= PHP_EOL . $library->document; } - elseif (isset($this->libraries[$id]) - && ObjectHelper::check( - $this->libraries[$id] - ) - && isset($this->libraries[$id]->how)) + elseif (is_object($library) + && isset($library->how)) { $setter .= $this->setLibraryDocument($id); } @@ -28300,19 +25930,18 @@ function vdm_dkim() { // check if we have string if (StringHelper::check($setter)) { - return $this->setPlaceholders( $this->setPlaceholders( + return CFactory::_('Placeholder')->update( CFactory::_('Placeholder')->update_( str_replace( '$this->document->', '$document->', implode( PHP_EOL, array_map( - trim, + 'trim', (array) explode(PHP_EOL, $setter) ) ) - ), - $this->placeholders - ), $this->fileContentStatic); + ) + ), CFactory::_('Compiler.Builder.Content.One')->allActive()); } return ''; @@ -28346,7 +25975,7 @@ function vdm_dkim() { if ($add_scripts_field && $module->add_scripts_field) { // get the custom script field - $xmlFields .= PHP_EOL . $this->_t(2) + $xmlFields .= PHP_EOL . Indent::_(2) . ""; // don't add it again $add_scripts_field = false; @@ -28374,38 +26003,43 @@ function vdm_dkim() { // switch to add the language xml $addLang = array(); // now build the language files - if (isset($this->langContent[$module->key])) + if (CFactory::_('Language')->exist($module->key)) { + // for plugin event TODO change event api signatures + $langContent = CFactory::_('Language')->getTarget($module->key); // Trigger Event: jcb_ce_onBeforeBuildModuleLang - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildModuleLang', - array(&$this->componentContext, &$module, - &$this->langContent[$module->key], - &$module->lang_prefix, &$module->official_name) + array(&$component_context, &$module, + &$langContent, &$module->lang_prefix, &$module->official_name) ); // get other languages - $values = array_unique($this->langContent[$module->key]); + $values = array_unique($langContent); // get the other lang strings if there is any $this->multiLangString = $this->getMultiLangStrings($values); // start the modules language bucket (must rest every time) $this->languages['modules'] = array(); - $this->languages['modules'][$this->langTag] = array(); - $this->languages['modules'][$this->langTag]['all'] - = $this->langContent[$module->key]; - unset($this->langContent[$module->key]); + $this->languages['modules'][CFactory::_('Config')->get('lang_tag', 'en-GB')] = array(); + $this->languages['modules'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['all'] + = $langContent; + CFactory::_('Language')->setTarget($module->key, null); // update insert the current lang in to DB $this->setLangPlaceholders($values, $module->id, 'modules'); // remove old unused language strings $this->purgeLanuageStrings($values, $module->id, 'modules'); $total = count($values); unset($values); + // for plugin event TODO change event api signatures + $component_context = CFactory::_('Config')->component_context; // Trigger Event: jcb_ce_onBeforeBuildModuleLangFiles - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildModuleLangFiles', - array(&$this->componentContext, &$module, + array(&$component_context, &$module, &$this->languages['modules'], &$this->langTag) ); + // for plugin event TODO change event api signatures + CFactory::_('Config')->lang_tag = $this->langTag; // now we insert the values into the files if (ArrayHelper::check($this->languages['modules'])) { @@ -28423,34 +26057,31 @@ function vdm_dkim() { )) { $lang = array_map( - function ($langstring, $placeholder) { - return $placeholder . '="' . $langstring - . '"'; - }, array_values($languageStrings), + fn($langstring, $placeholder) => $placeholder . '="' . $langstring . '"', + array_values($languageStrings), array_keys($languageStrings) ); // set path - $path = $module->folder_path . '/language/' . $tag - . '/'; + $path = $module->folder_path . '/language/' . $tag . '/'; // create path if not exist if (!Folder::exists($path)) { Folder::create($path); // count the folder created - $this->folderCount++; + CFactory::_('Utilities.Counter')->folder++; } // add to language files (for now we add all to both TODO) - $this->writeFile( + CFactory::_('Utilities.File')->write( $path . $file_name, implode(PHP_EOL, $lang) ); - $this->writeFile( + CFactory::_('Utilities.File')->write( $path . $tag . '.' . $module->file_name . '.sys.ini', implode(PHP_EOL, $lang) ); // set the line counter - $this->lineCount = $this->lineCount + count( + CFactory::_('Utilities.Counter')->line += count( (array) $lang ); unset($lang); @@ -28471,64 +26102,64 @@ function vdm_dkim() { // should the scriptfile be added if ($module->add_install_script) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) + $xml .= PHP_EOL . Indent::_(1) . 'script.php'; } // should the sql install be added if ($module->add_sql) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(3) + $xml .= PHP_EOL . Indent::_(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(3) . 'sql/mysql/install.sql'; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // should the sql uninstall be added if ($module->add_sql_uninstall) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(3) + $xml .= PHP_EOL . Indent::_(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(3) . 'sql/mysql/uninstall.sql'; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // should the language xml be added if (ArrayHelper::check($addLang)) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) + $xml .= PHP_EOL . Indent::_(1) . ''; // load all the language files to xml foreach ($addLang as $addTag) { - $xml .= PHP_EOL . $this->_t(2) . '' . $addTag . '/' . $addTag . '.' . $module->file_name . '.ini'; - $xml .= PHP_EOL . $this->_t(2) . '' . $addTag . '/' . $addTag . '.' . $module->file_name . '.sys.ini'; } - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // add the module files - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) . 'file_name . '">' . $module->file_name . '.php'; // add other files found @@ -28539,7 +26170,7 @@ function vdm_dkim() { // only add what is not ignored if (!in_array($file, $ignore)) { - $xml .= PHP_EOL . $this->_t(2) . '' . $file + $xml .= PHP_EOL . Indent::_(2) . '' . $file . ''; } } @@ -28547,12 +26178,12 @@ function vdm_dkim() { // add language folder if (ArrayHelper::check($addLang)) { - $xml .= PHP_EOL . $this->_t(2) . 'language'; + $xml .= PHP_EOL . Indent::_(2) . 'language'; } // add sql folder if ($module->add_sql || $module->add_sql_uninstall) { - $xml .= PHP_EOL . $this->_t(2) . 'sql'; + $xml .= PHP_EOL . Indent::_(2) . 'sql'; } // add other files found if (ArrayHelper::check($folders)) @@ -28562,39 +26193,39 @@ function vdm_dkim() { // only add what is not ignored if (!in_array($folder, $ignore)) { - $xml .= PHP_EOL . $this->_t(2) . '' . $folder + $xml .= PHP_EOL . Indent::_(2) . '' . $folder . ''; } } } - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; // now add the Config Params if needed if (ArrayHelper::check($config_fields)) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; // only add if part of the component field types path is required if ($add_component_path) { // add path to module rules and custom fields - $xml .= PHP_EOL . $this->_t(1) . '_t(2) + $xml .= PHP_EOL . Indent::_(1) . '_t(2) + . CFactory::_('Config')->component_code_name . '/models/rules"'; + $xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="/administrator/components/com_' - . $this->componentCodeName . '/models/fields"'; - $xml .= PHP_EOL . $this->_t(1) . '>'; + . CFactory::_('Config')->component_code_name . '/models/fields"'; + $xml .= PHP_EOL . Indent::_(1) . '>'; } else { - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // add the fields foreach ($module->config_fields as $field_name => $fieldsets) { - $xml .= PHP_EOL . $this->_t(1) . ''; foreach ($fieldsets as $fieldset => $fields) { @@ -28647,30 +26278,30 @@ function vdm_dkim() { || isset($module->add_field_path[$field_name . $fieldset])) { - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . '
add_rule_path[$field_name . $fieldset])) { - $xml .= PHP_EOL . $this->_t(2) + $xml .= PHP_EOL . Indent::_(2) . 'addrulepath="' . $module->add_rule_path[$field_name . $fieldset] . '"'; } if (isset($module->add_field_path[$field_name . $fieldset])) { - $xml .= PHP_EOL . $this->_t(2) + $xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="' . $module->add_field_path[$field_name . $fieldset] . '"'; } - $xml .= PHP_EOL . $this->_t(1) . '>'; + $xml .= PHP_EOL . Indent::_(1) . '>'; } else { - $xml .= PHP_EOL . $this->_t(1) . '
'; } // load the fields @@ -28679,24 +26310,24 @@ function vdm_dkim() { $xml .= $config_fields[$field_name . $fieldset]; unset($config_fields[$field_name . $fieldset]); } - $xml .= PHP_EOL . $this->_t(1) . '
'; + $xml .= PHP_EOL . Indent::_(1) . '
'; } - $xml .= PHP_EOL . $this->_t(1) . '
'; + $xml .= PHP_EOL . Indent::_(1) . ''; } - $xml .= PHP_EOL . $this->_t(1) . '
'; + $xml .= PHP_EOL . Indent::_(1) . '
'; } // set update server if found if ($module->add_update_server) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) + $xml .= PHP_EOL . Indent::_(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . '' . $module->update_server_url . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } return $xml; @@ -28704,13 +26335,15 @@ function vdm_dkim() { public function getPluginMainClass(&$plugin) { - return - $this->setPlaceholders(PHP_EOL . $plugin->head . PHP_EOL . + return CFactory::_('Placeholder')->update( + PHP_EOL . $plugin->head . PHP_EOL . $plugin->comment . PHP_EOL . 'class ' . $plugin->class_name . ' extends ' . $plugin->extends . PHP_EOL . '{' . PHP_EOL . $plugin->main_class_code . PHP_EOL . - "}" . PHP_EOL, $this->fileContentStatic); + "}" . PHP_EOL, + CFactory::_('Compiler.Builder.Content.One')->allActive() + ); } public function getPluginMainXML(&$plugin) @@ -28759,25 +26392,28 @@ function vdm_dkim() { // switch to add the language xml $addLang = array(); // now build the language files - if (isset($this->langContent[$plugin->key])) + if (CFactory::_('Language')->exist($plugin->key)) { + // for plugin event TODO change event api signatures + $langContent = CFactory::_('Language')->getTarget($plugin->key); + $component_context = CFactory::_('Config')->component_context; // Trigger Event: jcb_ce_onBeforeBuildPluginLang - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildPluginLang', - array(&$this->componentContext, &$plugin, - &$this->langContent[$plugin->key], + array(&$component_context, &$plugin, + &$langContent, &$plugin->lang_prefix, &$plugin->official_name) ); // get other languages - $values = array_unique($this->langContent[$plugin->key]); + $values = array_unique($langContent); // get the other lang strings if there is any $this->multiLangString = $this->getMultiLangStrings($values); // start the plugins language bucket (must rest every time) $this->languages['plugins'] = array(); - $this->languages['plugins'][$this->langTag] = array(); - $this->languages['plugins'][$this->langTag]['all'] - = $this->langContent[$plugin->key]; - unset($this->langContent[$plugin->key]); + $this->languages['plugins'][CFactory::_('Config')->get('lang_tag', 'en-GB')] = array(); + $this->languages['plugins'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['all'] + = $langContent; + CFactory::_('Language')->setTarget($plugin->key, null); // update insert the current lang in to DB $this->setLangPlaceholders($values, $plugin->id, 'plugins'); // remove old unused language strings @@ -28785,12 +26421,14 @@ function vdm_dkim() { $total = count($values); unset($values); // Trigger Event: jcb_ce_onBeforeBuildPluginLangFiles - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildPluginLangFiles', - array(&$this->componentContext, &$plugin, + array(&$component_context, &$plugin, &$this->languages['plugins'], &$this->langTag) ); + // for plugin event TODO change event api signatures + CFactory::_('Config')->lang_tag = $this->langTag; // now we insert the values into the files if (ArrayHelper::check($this->languages['plugins'])) { @@ -28800,9 +26438,9 @@ function vdm_dkim() { $tag = trim($tag); foreach ($areas as $area => $languageStrings) { - $file_name = $tag . '.plg_' . strtolower($plugin->group) + $file_name = $tag . '.plg_' . strtolower((string) $plugin->group) . '_' - . strtolower($plugin->code_name) . '.ini'; + . strtolower((string) $plugin->code_name) . '.ini'; // check if language should be added if ($this->shouldLanguageBeAdded( $tag, $languageStrings, $total, @@ -28810,10 +26448,8 @@ function vdm_dkim() { )) { $lang = array_map( - function ($langstring, $placeholder) { - return $placeholder . '="' . $langstring - . '"'; - }, array_values($languageStrings), + fn($langstring, $placeholder) => $placeholder . '="' . $langstring . '"', + array_values($languageStrings), array_keys($languageStrings) ); // set path @@ -28824,23 +26460,23 @@ function vdm_dkim() { { Folder::create($path); // count the folder created - $this->folderCount++; + CFactory::_('Utilities.Counter')->folder++; } // add to language file - $this->writeFile( + CFactory::_('Utilities.File')->write( $path . $file_name, implode(PHP_EOL, $lang) ); - $this->writeFile( + CFactory::_('Utilities.File')->write( $path . $tag . '.plg_' . strtolower( - $plugin->group + (string) $plugin->group ) . '_' - . strtolower($plugin->code_name) . '.sys.ini', + . strtolower((string) $plugin->code_name) . '.sys.ini', implode(PHP_EOL, $lang) ); // set the line counter - $this->lineCount = $this->lineCount + count( + CFactory::_('Utilities.Counter')->line += count( (array) $lang ); unset($lang); @@ -28861,67 +26497,67 @@ function vdm_dkim() { // should the scriptfile be added if ($plugin->add_install_script) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) + $xml .= PHP_EOL . Indent::_(1) . 'script.php'; } // should the sql install be added if ($plugin->add_sql) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(3) + $xml .= PHP_EOL . Indent::_(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(3) . 'sql/mysql/install.sql'; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // should the sql uninstall be added if ($plugin->add_sql_uninstall) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(3) + $xml .= PHP_EOL . Indent::_(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(3) . 'sql/mysql/uninstall.sql'; - $xml .= PHP_EOL . $this->_t(2) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // should the language xml be added if (ArrayHelper::check($addLang)) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; // load all the language files to xml foreach ($addLang as $addTag) { - $xml .= PHP_EOL . $this->_t(2) . '' . $addTag . '/' . $addTag . '.plg_' - . strtolower($plugin->group) . '_' . strtolower( - $plugin->code_name + . strtolower((string) $plugin->group) . '_' . strtolower( + (string) $plugin->code_name ) . '.ini'; - $xml .= PHP_EOL . $this->_t(2) . '' . $addTag . '/' . $addTag . '.plg_' - . strtolower($plugin->group) . '_' . strtolower( - $plugin->code_name + . strtolower((string) $plugin->group) . '_' . strtolower( + (string) $plugin->code_name ) . '.sys.ini'; } - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // add the plugin files - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) . 'file_name . '">' . $plugin->file_name . '.php'; // add other files found @@ -28932,7 +26568,7 @@ function vdm_dkim() { // only add what is not ignored if (!in_array($file, $ignore)) { - $xml .= PHP_EOL . $this->_t(2) . '' . $file + $xml .= PHP_EOL . Indent::_(2) . '' . $file . ''; } } @@ -28940,12 +26576,12 @@ function vdm_dkim() { // add language folder if (ArrayHelper::check($addLang)) { - $xml .= PHP_EOL . $this->_t(2) . 'language'; + $xml .= PHP_EOL . Indent::_(2) . 'language'; } // add sql folder if ($plugin->add_sql || $plugin->add_sql_uninstall) { - $xml .= PHP_EOL . $this->_t(2) . 'sql'; + $xml .= PHP_EOL . Indent::_(2) . 'sql'; } // add other files found if (ArrayHelper::check($folders)) @@ -28955,39 +26591,39 @@ function vdm_dkim() { // only add what is not ignored if (!in_array($folder, $ignore)) { - $xml .= PHP_EOL . $this->_t(2) . '' . $folder + $xml .= PHP_EOL . Indent::_(2) . '' . $folder . ''; } } } - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; // now add the Config Params if needed if (ArrayHelper::check($config_fields)) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; // only add if part of the component field types path is required if ($add_component_path) { // add path to plugin rules and custom fields - $xml .= PHP_EOL . $this->_t(1) . '_t(2) + $xml .= PHP_EOL . Indent::_(1) . '_t(2) + . CFactory::_('Config')->component_code_name . '/models/rules"'; + $xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="/administrator/components/com_' - . $this->componentCodeName . '/models/fields"'; - $xml .= PHP_EOL . $this->_t(1) . '>'; + . CFactory::_('Config')->component_code_name . '/models/fields"'; + $xml .= PHP_EOL . Indent::_(1) . '>'; } else { - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } // add the fields foreach ($plugin->config_fields as $field_name => $fieldsets) { - $xml .= PHP_EOL . $this->_t(1) . ''; foreach ($fieldsets as $fieldset => $fields) { @@ -29005,16 +26641,16 @@ function vdm_dkim() { if (!isset($plugin->add_rule_path[$field_name . $fieldset])) { $plugin->add_rule_path[$field_name . $fieldset] = - '/plugins/' . strtolower($plugin->group - ) . '/' . strtolower($plugin->code_name) + '/plugins/' . strtolower((string) $plugin->group + ) . '/' . strtolower((string) $plugin->code_name) . '/rules'; } if (!isset($plugin->add_field_path[$field_name . $fieldset])) { $plugin->add_field_path[$field_name . $fieldset] = - '/plugins/' . strtolower($plugin->group - ) . '/' . strtolower($plugin->code_name) + '/plugins/' . strtolower((string) $plugin->group + ) . '/' . strtolower((string) $plugin->code_name) . '/fields'; } } @@ -29022,30 +26658,30 @@ function vdm_dkim() { if (isset($plugin->add_rule_path[$field_name . $fieldset]) || isset($plugin->add_field_path[$field_name . $fieldset])) { - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . '
add_rule_path[$field_name . $fieldset])) { - $xml .= PHP_EOL . $this->_t(2) + $xml .= PHP_EOL . Indent::_(2) . 'addrulepath="' . $plugin->add_rule_path[$field_name . $fieldset] . '"'; } if (isset($plugin->add_field_path[$field_name . $fieldset])) { - $xml .= PHP_EOL . $this->_t(2) + $xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="' . $plugin->add_field_path[$field_name . $fieldset] . '"'; } - $xml .= PHP_EOL . $this->_t(1) . '>'; + $xml .= PHP_EOL . Indent::_(1) . '>'; } else { - $xml .= PHP_EOL . $this->_t(1) . '
'; } // load the fields @@ -29054,24 +26690,24 @@ function vdm_dkim() { $xml .= $config_fields[$field_name . $fieldset]; unset($config_fields[$field_name . $fieldset]); } - $xml .= PHP_EOL . $this->_t(1) . '
'; + $xml .= PHP_EOL . Indent::_(1) . '
'; } - $xml .= PHP_EOL . $this->_t(1) . '
'; + $xml .= PHP_EOL . Indent::_(1) . ''; } - $xml .= PHP_EOL . $this->_t(1) . '
'; + $xml .= PHP_EOL . Indent::_(1) . '
'; } // set update server if found if ($plugin->add_update_server) { - $xml .= PHP_EOL . PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; - $xml .= PHP_EOL . $this->_t(2) + $xml .= PHP_EOL . Indent::_(1) . ''; + $xml .= PHP_EOL . Indent::_(2) . '' . $plugin->update_server_url . ''; - $xml .= PHP_EOL . $this->_t(1) . ''; + $xml .= PHP_EOL . Indent::_(1) . ''; } return $xml; @@ -29091,10 +26727,10 @@ function vdm_dkim() { if (StringHelper::check($power->description)) { // check if this is escaped - if (strpos($power->description, '/*') === false) + if (strpos((string) $power->description, '/*') === false) { // make this description escaped - $power->description = '/**' . PHP_EOL . ' * ' . implode(PHP_EOL . ' * ', explode(PHP_EOL, $power->description)) . PHP_EOL . ' */'; + $power->description = '/**' . PHP_EOL . ' * ' . implode(PHP_EOL . ' * ', explode(PHP_EOL, (string) $power->description)) . PHP_EOL . ' */'; } $code[] = PHP_EOL . $power->description; } @@ -29119,136 +26755,7 @@ function vdm_dkim() { } $code[] = '}' . PHP_EOL . PHP_EOL; - return $this->setPlaceholders(implode(PHP_EOL, $code), $this->fileContentStatic); - } - - public function setPowersAutoloader($namespace, $loadSite) - { - if (($size = ArrayHelper::check($namespace)) > 0) - { - // check if we are using a plugin - $use_plugin = isset($this->fileContentStatic[$this->hhh . 'PLUGIN_POWER_AUTOLOADER' . $this->hhh]); - // build the methods - $autoloadNotSiteMethod = array(); - $autoloadMethod = array(); - // add only if we are not using a plugin - $tab_space = 2; - if (!$use_plugin) - { - $autoloadNotSiteMethod[] = PHP_EOL . PHP_EOL; - $tab_space = 0; - } - elseif (!$loadSite) - { - // we add code to prevent this plugin from triggering on the site area - $autoloadNotSiteMethod[] = PHP_EOL . $this->_t(2) . '//' - . $this->setLine(__LINE__) . ' do not run the autoloader in the site area'; - $autoloadNotSiteMethod[] = $this->_t(2) . 'if ($this->app->isClient(\'site\'))'; - $autoloadNotSiteMethod[] = $this->_t(2) . '{'; - $autoloadNotSiteMethod[] = $this->_t(3) . 'return;'; - $autoloadNotSiteMethod[] = $this->_t(2) . '}' . PHP_EOL; - } - // we start building the spl_autoload_register function call - $autoloadMethod[] = $this->_t($tab_space) . '//' - . $this->setLine(__LINE__) . ' register this component namespace'; - $autoloadMethod[] = $this->_t($tab_space) . 'spl_autoload_register(function ($class) {'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '//' - . $this->setLine(__LINE__) . ' project-specific base directories and namespace prefix'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '$search = array('; - // ==== IMPORTANT NOTICE ===== - // make sure the name space values are sorted from the longest string to the shortest - // so that the search do not mistakenly match a shorter namespace before a longer one - // that has the same short namespace for example: - // NameSpace\SubName\Sub <- will always match first - // NameSpace\SubName\SubSubName - // Should the shorter namespace be listed [first] it will match both of these: - // NameSpace\SubName\Sub\ClassName - // ^^^^^^^^^^^^^^^^^^^^^ - // NameSpace\SubName\SubSubName\ClassName - // ^^^^^^^^^^^^^^^^^^^^^ - uksort($namespace, function ($a, $b) { - return strlen($b) - strlen($a); - }); - // counter to manage the comma in the actual array - $counter = 1; - foreach ($namespace as $base_dir => $prefix) - { - // don't add the ending comma on last value - if ($size == $counter) - { - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . "'$this->jcbPowersPath/$base_dir' => '" . implode('\\\\', $prefix) . "'"; - } - else - { - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . "'$this->jcbPowersPath/$base_dir' => '" . implode('\\\\', $prefix) . "',"; - } - $counter++; - } - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . ');'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '// Start the search and load if found'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '$found = false;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '$found_base_dir = "";'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '$found_len = 0;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . 'foreach ($search as $base_dir => $prefix)'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '{'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . '//' - . $this->setLine(__LINE__) . ' does the class use the namespace prefix?'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . '$len = strlen($prefix);'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . 'if (strncmp($prefix, $class, $len) === 0)'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . '{'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(3) . '//' - . $this->setLine(__LINE__) . ' we have a match so load the values'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(3) . '$found = true;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(3) . '$found_base_dir = $base_dir;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(3) . '$found_len = $len;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(3) . '//' - . $this->setLine(__LINE__) . ' done here'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(3) . 'break;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . '}'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '}'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '//' - . $this->setLine(__LINE__) . ' check if we found a match'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . 'if (!$found)'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '{'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . '//' - . $this->setLine(__LINE__) . ' no, move to the next registered autoloader'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . 'return;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '}'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '//' - . $this->setLine(__LINE__) . ' get the relative class name'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '$relative_class = substr($class, $found_len);'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '//' - . $this->setLine(__LINE__) . ' replace the namespace prefix with the base directory, replace namespace'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '// separators with directory separators in the relative class name, append'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '// with .php'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . "\$file = JPATH_ROOT . '/' . \$found_base_dir . '/src' . str_replace('\\\\', '/', \$relative_class) . '.php';"; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '//' - . $this->setLine(__LINE__) . ' if the file exists, require it'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . 'if (file_exists($file))'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '{'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(2) . 'require $file;'; - $autoloadMethod[] = $this->_t($tab_space) . $this->_t(1) . '}'; - $autoloadMethod[] = $this->_t($tab_space) . '});'; - // create the method string - $autoloader = implode(PHP_EOL, $autoloadNotSiteMethod) . implode(PHP_EOL, $autoloadMethod); - // check if we are using a plugin - if ($use_plugin) - { - $this->fileContentStatic[$this->hhh . 'PLUGIN_POWER_AUTOLOADER' . $this->hhh] = PHP_EOL . $autoloader; - } - else - { - // load to events placeholders - $this->fileContentStatic[$this->hhh . 'ADMIN_POWER_HELPER' . $this->hhh] .= $autoloader; - // load to site if needed - if ($loadSite) - { - $this->fileContentStatic[$this->hhh . 'SITE_POWER_HELPER' . $this->hhh] .= $autoloader; - } - } - // to add to custom files - $this->fileContentStatic[$this->hhh . 'CUSTOM_POWER_AUTOLOADER' . $this->hhh] .= PHP_EOL . implode(PHP_EOL, $autoloadMethod); - } + return CFactory::_('Placeholder')->update(implode(PHP_EOL, $code), CFactory::_('Compiler.Builder.Content.One')->allActive()); } /** @@ -29261,249 +26768,27 @@ function vdm_dkim() { * @return string The fields set in xml * */ - public function getExtensionFieldsetXML(&$extension, &$fields, $dbkey = 'zz' - ) + public function getExtensionFieldsetXML(&$extension, &$fields, $dbkey = 'zz') { + // get global placeholders + $placeholder = CFactory::_('Component.Placeholder')->get(); // build the fieldset - return $this->getFieldsetXML( + return CFactory::_('Compiler.Creator.Fieldset.Dynamic')->get( $fields, $extension->lang_prefix, $extension->key, $extension->key, - $this->globalPlaceholders, $dbkey + $placeholder, $dbkey ); } - public function getExtensionInstallClass(&$extension) - { - // yes we are adding it - $script = PHP_EOL . '/**'; - $script .= PHP_EOL . ' * ' . $extension->official_name - . ' script file.'; - $script .= PHP_EOL . ' *'; - $script .= PHP_EOL . ' * @package ' . $extension->class_name; - $script .= PHP_EOL . ' */'; - $script .= PHP_EOL . 'class ' . $extension->installer_class_name; - $script .= PHP_EOL . '{'; - // set constructor - if (isset($extension->add_php_script_construct) - && $extension->add_php_script_construct == 1 - && StringHelper::check( - $extension->php_script_construct - )) - { - $script .= $this->setInstallMethodScript( - 'construct', $extension->php_script_construct - ); - } - // add PHP in extension install - $addScriptMethods = array('php_preflight', 'php_postflight', - 'php_method'); - $addScriptTypes = array('install', 'update', 'uninstall', - 'discover_install'); - // set some buckets for sorting - $function_install = array(); - $function_update = array(); - $function_uninstall = array(); - $has_php_preflight = false; - $function_php_preflight = array('install' => array(), - 'uninstall' => array(), - 'discover_install' => array(), - 'update' => array()); - $has_php_postflight = false; - $function_php_postflight = array('install' => array(), - 'uninstall' => array(), - 'discover_install' => array(), - 'update' => array()); - // the function sorter - foreach ($addScriptMethods as $scriptMethod) - { - foreach ($addScriptTypes as $scriptType) - { - if (isset( - $extension->{'add_' . $scriptMethod . '_' . $scriptType} - ) - && $extension->{'add_' . $scriptMethod . '_' . $scriptType} - == 1 - && StringHelper::check( - $extension->{$scriptMethod . '_' . $scriptType} - )) - { - // add to the main methods - if ('php_method' === $scriptMethod) - { - ${'function_' . $scriptType}[] - = $extension->{$scriptMethod . '_' . $scriptType}; - } - else - { - ${'function_' . $scriptMethod}[$scriptType][] - = $extension->{$scriptMethod - . '_' . $scriptType}; - ${'has_' . $scriptMethod} = true; - } - } - } - } - // now add the install script. - if (ArrayHelper::check($function_install)) - { - $script .= $this->setInstallMethodScript( - 'install', $function_install - ); - } - // now add the update script. - if (ArrayHelper::check($function_update)) - { - $script .= $this->setInstallMethodScript( - 'update', $function_update - ); - } - // now add the uninstall script. - if (ArrayHelper::check($function_uninstall)) - { - $script .= $this->setInstallMethodScript( - 'uninstall', $function_uninstall - ); - } - // now add the preflight script. - if ($has_php_preflight) - { - $script .= $this->setInstallMethodScript( - 'preflight', $function_php_preflight - ); - } - // now add the postflight script. - if ($has_php_postflight) - { - $script .= $this->setInstallMethodScript( - 'postflight', $function_php_postflight - ); - } - $script .= PHP_EOL . '}' . PHP_EOL; - - return $script; - } - - protected function setInstallMethodScript($function_name, &$scripts) - { - $script = ''; - // build function - switch ($function_name) - { - case 'install': - case 'update': - case 'uninstall': - // the main function types - $script = PHP_EOL . PHP_EOL . $this->_t(1) . '/**'; - $script .= PHP_EOL . $this->_t(1) . ' * Called on ' - . $function_name; - $script .= PHP_EOL . $this->_t(1) . ' *'; - $script .= PHP_EOL . $this->_t(1) - . ' * @param JAdapterInstance $adapter The object responsible for running this script'; - $script .= PHP_EOL . $this->_t(1) . ' *'; - $script .= PHP_EOL . $this->_t(1) - . ' * @return boolean True on success'; - $script .= PHP_EOL . $this->_t(1) . ' */'; - $script .= PHP_EOL . $this->_t(1) . 'public function ' - . $function_name . '(JAdapterInstance $adapter)'; - $script .= PHP_EOL . $this->_t(1) . '{'; - $script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $scripts); - // return true - if ('uninstall' !== $function_name) - { - $script .= PHP_EOL . $this->_t(2) . 'return true;'; - } - break; - case 'preflight': - case 'postflight': - // the pre/post function types - $script = PHP_EOL . PHP_EOL . $this->_t(1) . '/**'; - $script .= PHP_EOL . $this->_t(1) - . ' * Called before any type of action'; - $script .= PHP_EOL . $this->_t(1) . ' *'; - $script .= PHP_EOL . $this->_t(1) - . ' * @param string $route Which action is happening (install|uninstall|discover_install|update)'; - $script .= PHP_EOL . $this->_t(1) - . ' * @param JAdapterInstance $adapter The object responsible for running this script'; - $script .= PHP_EOL . $this->_t(1) . ' *'; - $script .= PHP_EOL . $this->_t(1) - . ' * @return boolean True on success'; - $script .= PHP_EOL . $this->_t(1) . ' */'; - $script .= PHP_EOL . $this->_t(1) . 'public function ' - . $function_name . '($route, JAdapterInstance $adapter)'; - $script .= PHP_EOL . $this->_t(1) . '{'; - $script .= PHP_EOL . $this->_t(2) . '//' . $this->setLine( - __LINE__ - ) . ' get application'; - $script .= PHP_EOL . $this->_t(2) - . '$app = JFactory::getApplication();' . PHP_EOL; - // add the default version check (TODO) must make this dynamic - if ('preflight' === $function_name) - { - $script .= PHP_EOL . $this->_t(2) . '//' . $this->setLine( - __LINE__ - ) . ' the default for both install and update'; - $script .= PHP_EOL . $this->_t(2) - . '$jversion = new JVersion();'; - $script .= PHP_EOL . $this->_t(2) - . "if (!\$jversion->isCompatible('3.8.0'))"; - $script .= PHP_EOL . $this->_t(2) . '{'; - $script .= PHP_EOL . $this->_t(3) - . "\$app->enqueueMessage('Please upgrade to at least Joomla! 3.8.0 before continuing!', 'error');"; - $script .= PHP_EOL . $this->_t(3) . 'return false;'; - $script .= PHP_EOL . $this->_t(2) . '}' . PHP_EOL; - } - // now add the scripts - foreach ($scripts as $route => $_script) - { - if (ArrayHelper::check($_script)) - { - // set the if and script - $script .= PHP_EOL . $this->_t(2) . "if ('" . $route - . "' === \$route)"; - $script .= PHP_EOL . $this->_t(2) . '{'; - $script .= PHP_EOL . implode( - PHP_EOL . PHP_EOL, $_script - ); - $script .= PHP_EOL . $this->_t(2) . '}' . PHP_EOL; - } - } - // return true - $script .= PHP_EOL . $this->_t(2) . 'return true;'; - break; - case 'construct': - // the __construct script - $script = PHP_EOL . PHP_EOL . $this->_t(1) . '/**'; - $script .= PHP_EOL . $this->_t(1) . ' * Constructor'; - $script .= PHP_EOL . $this->_t(1) . ' *'; - $script .= PHP_EOL . $this->_t(1) - . ' * @param JAdapterInstance $adapter The object responsible for running this script'; - $script .= PHP_EOL . $this->_t(1) . ' */'; - $script .= PHP_EOL . $this->_t(1) - . 'public function __construct(JAdapterInstance $adapter)'; - $script .= PHP_EOL . $this->_t(1) . '{'; - $script .= PHP_EOL . $scripts; - break; - default: - // oops error - return ''; - } - // close the function - $script .= PHP_EOL . $this->_t(1) . '}'; - - return $script; - } - /** * check if a translation should be added * * @return bool * */ - public function shouldLanguageBeAdded(&$tag, &$languageStrings, &$total, - &$file_name - ) + public function shouldLanguageBeAdded(&$tag, &$languageStrings, &$total, &$file_name) { - // only log messages for none $this->langTag translations - if ($this->langTag !== $tag) + // only log messages for none CFactory::_('Config')->get('lang_tag', 'en-GB') translations + if (CFactory::_('Config')->get('lang_tag', 'en-GB') !== $tag) { $langStringNr = count($languageStrings); $langStringSum = MathHelper::bc( @@ -29516,7 +26801,7 @@ function vdm_dkim() { . $tag . ' translated)' : '(strings ' . $tag . ' translated)'; // force load if debug lines are added - if (!$this->debugLinenr) + if (!CFactory::_('Config')->get('debug_line_nr', false)) { // check if we should install this translation if ($percentage < $this->percentageLanguageAdd) @@ -29524,7 +26809,7 @@ function vdm_dkim() { // dont add $this->langNot[$file_name] = '' . $total . '(total ' - . $this->langTag . ' strings) only ' + . CFactory::_('Config')->get('lang_tag', 'en-GB') . ' strings) only ' . $langStringNr . '' . $stringNAme . ' = ' . $percentage; @@ -29534,7 +26819,7 @@ function vdm_dkim() { // show if it was added as well $this->langSet[$file_name] = '' . $total . '(total ' - . $this->langTag . ' strings) and ' + . CFactory::_('Config')->get('lang_tag', 'en-GB') . ' strings) and ' . $langStringNr . '' . $stringNAme . ' = ' . $percentage; } diff --git a/admin/helpers/compiler/f_Infusion.php b/admin/helpers/compiler/f_Infusion.php index 88d2b1996..11088496d 100644 --- a/admin/helpers/compiler/f_Infusion.php +++ b/admin/helpers/compiler/f_Infusion.php @@ -19,23 +19,44 @@ use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Utilities\ObjectHelper; use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as CFactory; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Minify; /** * Infusion class + * @deprecated 3.3 */ class Infusion extends Interpretation { + public $langFiles = array(); + + /** + * Switch to remove site folder + * + * @var bool + * @deprecated 3.3 Use CFactory::_('Config')->remove_site_folder; + */ public $removeSiteFolder = false; + + /** + * Switch to remove site edit folder + * + * @var bool + * @deprecated 3.3 Use CFactory::_('Config')->remove_site_edit_folder; + */ public $removeSiteEditFolder = true; /** * Constructor */ - public function __construct($config = array()) + public function __construct() { // first we run the perent constructor - if (parent::__construct($config)) + if (parent::__construct()) { // infuse the data into the structure return $this->buildFileContent(); @@ -44,24 +65,6 @@ class Infusion extends Interpretation return false; } - /** - * Set the line number in comments - * - * @param int $nr The line number - * - * @return void - * - */ - private function setLine($nr) - { - if ($this->debugLinenr) - { - return ' [Infusion ' . $nr . ']'; - } - - return ''; - } - /** * Build the content for the structure * @@ -71,315 +74,250 @@ class Infusion extends Interpretation */ protected function buildFileContent() { - if (isset($this->componentData->admin_views) - && ArrayHelper::check( - $this->componentData->admin_views - )) + if (CFactory::_('Component')->isArray('admin_views')) { + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); + $component_context = CFactory::_('Config')->component_context; // Trigger Event: jcb_ce_onBeforeBuildFilesContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildFilesContent', - array(&$this->componentContext, &$this->componentData, - &$this->fileContentStatic, &$this->fileContentDynamic, - &$this->placeholders, &$this->hhh) + array(&$component_context, &$this->componentData, + &$fileContentStatic, &$fileContentDynamic, + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); // COMPONENT - $this->fileContentStatic[$this->hhh . 'COMPONENT' . $this->hhh] - = $this->placeholders[$this->hhh . 'COMPONENT' . $this->hhh]; + CFactory::_('Compiler.Builder.Content.One')->set('COMPONENT', CFactory::_('Placeholder')->get('COMPONENT')); // Component - $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh] - = $this->placeholders[$this->hhh . 'Component' . $this->hhh]; + CFactory::_('Compiler.Builder.Content.One')->set('Component', CFactory::_('Placeholder')->get('Component')); // component - $this->fileContentStatic[$this->hhh . 'component' . $this->hhh] - = $this->placeholders[$this->hhh . 'component' . $this->hhh]; + CFactory::_('Compiler.Builder.Content.One')->set('component', CFactory::_('Placeholder')->get('component')); // COMPANYNAME - $this->fileContentStatic[$this->hhh . 'COMPANYNAME' . $this->hhh] - = trim( - JFilterOutput::cleanText($this->componentData->companyname) - ); + $companyname = CFactory::_('Component')->get('companyname'); + CFactory::_('Compiler.Builder.Content.One')->set('COMPANYNAME', trim( + (string) JFilterOutput::cleanText($companyname) + )); // CREATIONDATE - $this->fileContentStatic[$this->hhh . 'CREATIONDATE' . $this->hhh] - = JFactory::getDate($this->componentData->created)->format( + CFactory::_('Compiler.Builder.Content.One')->set('CREATIONDATE', + JFactory::getDate(CFactory::_('Component')->get('created'))->format( 'jS F, Y' - ); - $this->fileContentStatic[$this->hhh . 'CREATIONDATE' . $this->hhh - . 'GLOBAL'] - = $this->fileContentStatic[$this->hhh . 'CREATIONDATE' - . $this->hhh]; + )); + CFactory::_('Compiler.Builder.Content.One')->set('GLOBALCREATIONDATE', + CFactory::_('Compiler.Builder.Content.One')->get('CREATIONDATE')); // BUILDDATE - $this->fileContentStatic[$this->hhh . 'BUILDDATE' . $this->hhh] - = JFactory::getDate()->format('jS F, Y'); - $this->fileContentStatic[$this->hhh . 'BUILDDATE' . $this->hhh - . 'GLOBAL'] - = $this->fileContentStatic[$this->hhh . 'BUILDDATE' - . $this->hhh]; + CFactory::_('Compiler.Builder.Content.One')->set('BUILDDATE', JFactory::getDate( + CFactory::_('Config')->get('build_date', 'now'))->format('jS F, Y')); + CFactory::_('Compiler.Builder.Content.One')->set('GLOBALBUILDDATE', + CFactory::_('Compiler.Builder.Content.One')->get('BUILDDATE')); // AUTHOR - $this->fileContentStatic[$this->hhh . 'AUTHOR' . $this->hhh] = trim( - JFilterOutput::cleanText($this->componentData->author) - ); + $author = CFactory::_('Component')->get('author'); + CFactory::_('Compiler.Builder.Content.One')->set('AUTHOR', trim( + (string) JFilterOutput::cleanText($author) + )); // AUTHOREMAIL - $this->fileContentStatic[$this->hhh . 'AUTHOREMAIL' . $this->hhh] - = trim($this->componentData->email); + CFactory::_('Compiler.Builder.Content.One')->set('AUTHOREMAIL', trim((string) CFactory::_('Component')->get('email', ''))); // AUTHORWEBSITE - $this->fileContentStatic[$this->hhh . 'AUTHORWEBSITE' . $this->hhh] - = trim($this->componentData->website); + CFactory::_('Compiler.Builder.Content.One')->set('AUTHORWEBSITE', trim((string) CFactory::_('Component')->get('website', ''))); // COPYRIGHT - $this->fileContentStatic[$this->hhh . 'COPYRIGHT' . $this->hhh] - = trim($this->componentData->copyright); + CFactory::_('Compiler.Builder.Content.One')->set('COPYRIGHT', trim((string) CFactory::_('Component')->get('copyright', ''))); // LICENSE - $this->fileContentStatic[$this->hhh . 'LICENSE' . $this->hhh] - = trim($this->componentData->license); + CFactory::_('Compiler.Builder.Content.One')->set('LICENSE', trim((string) CFactory::_('Component')->get('license', ''))); // VERSION - $this->fileContentStatic[$this->hhh . 'VERSION' . $this->hhh] - = trim($this->componentData->component_version); + CFactory::_('Compiler.Builder.Content.One')->set('VERSION', trim((string) CFactory::_('Component')->get('component_version', ''))); // set the actual global version - $this->fileContentStatic[$this->hhh . 'ACTUALVERSION' . $this->hhh] - = $this->fileContentStatic[$this->hhh . 'VERSION' . $this->hhh]; + CFactory::_('Compiler.Builder.Content.One')->set('ACTUALVERSION', CFactory::_('Compiler.Builder.Content.One')->get('VERSION')); // do some Tweaks to the version based on selected options - if (strpos( - $this->fileContentStatic[$this->hhh . 'VERSION' - . $this->hhh], '.' - ) !== false) + if (strpos((string) CFactory::_('Compiler.Builder.Content.One')->get('VERSION'), '.') !== false) { $versionArray = explode( - '.', $this->fileContentStatic[$this->hhh . 'VERSION' - . $this->hhh] + '.', (string) CFactory::_('Compiler.Builder.Content.One')->get('VERSION') ); } // load only first two values if (isset($versionArray) && ArrayHelper::check( $versionArray - ) - && $this->componentData->mvc_versiondate == 2) + ) && CFactory::_('Component')->get('mvc_versiondate', 0) == 2) { - $this->fileContentStatic[$this->hhh . 'VERSION' . $this->hhh] - = $versionArray[0] . '.' . $versionArray[1] . '.x'; + CFactory::_('Compiler.Builder.Content.One')->set('VERSION', $versionArray[0] . '.' . $versionArray[1] . '.x'); } // load only the first value elseif (isset($versionArray) && ArrayHelper::check( $versionArray - ) - && $this->componentData->mvc_versiondate == 3) + ) && CFactory::_('Component')->get('mvc_versiondate', 0) == 3) { - $this->fileContentStatic[$this->hhh . 'VERSION' . $this->hhh] - = $versionArray[0] . '.x.x'; + CFactory::_('Compiler.Builder.Content.One')->set('VERSION', $versionArray[0] . '.x.x'); } unset($versionArray); // set the global version in case - $this->fileContentStatic[$this->hhh . 'VERSION' . $this->hhh - . 'GLOBAL'] - = $this->fileContentStatic[$this->hhh . 'VERSION' . $this->hhh]; + CFactory::_('Compiler.Builder.Content.One')->set('GLOBALVERSION', CFactory::_('Compiler.Builder.Content.One')->get('VERSION')); // set the joomla target xml version - $this->fileContentStatic[$this->hhh . 'XMLVERSION' . $this->hhh] - = $this->joomlaVersions[$this->joomlaVersion]['xml_version']; + CFactory::_('Compiler.Builder.Content.One')->set('XMLVERSION', CFactory::_('Config')->joomla_versions[CFactory::_('Config')->joomla_version]['xml_version']); // Component_name - $this->fileContentStatic[$this->hhh . 'Component_name' . $this->hhh] - = JFilterOutput::cleanText($this->componentData->name); + $name = CFactory::_('Component')->get('name'); + CFactory::_('Compiler.Builder.Content.One')->set('Component_name', JFilterOutput::cleanText($name)); // SHORT_DISCRIPTION - $this->fileContentStatic[$this->hhh . 'SHORT_DESCRIPTION' - . $this->hhh] - = trim( - JFilterOutput::cleanText( - $this->componentData->short_description + $short_description = CFactory::_('Component')->get('short_description'); + CFactory::_('Compiler.Builder.Content.One')->set('SHORT_DESCRIPTION', trim( + (string) JFilterOutput::cleanText( + $short_description ) - ); + )); // DESCRIPTION - $this->fileContentStatic[$this->hhh . 'DESCRIPTION' . $this->hhh] - = trim($this->componentData->description); + CFactory::_('Compiler.Builder.Content.One')->set('DESCRIPTION', trim((string) CFactory::_('Component')->get('description'))); // COMP_IMAGE_TYPE - $this->fileContentStatic[$this->hhh . 'COMP_IMAGE_TYPE' - . $this->hhh] - = $this->setComponentImageType($this->componentData->image); + CFactory::_('Compiler.Builder.Content.One')->set('COMP_IMAGE_TYPE', $this->setComponentImageType(CFactory::_('Component')->get('image'))); // ACCESS_SECTIONS - $this->fileContentStatic[$this->hhh . 'ACCESS_SECTIONS' - . $this->hhh] - = $this->setAccessSections(); + CFactory::_('Compiler.Builder.Content.One')->set('ACCESS_SECTIONS', $this->setAccessSections()); // CONFIG_FIELDSETS - $keepLang = $this->lang; - $this->lang = 'admin'; + $keepLang = CFactory::_('Config')->lang_target; + CFactory::_('Config')->lang_target = 'admin'; // start loading the category tree scripts - $this->fileContentStatic[$this->hhh . 'CATEGORY_CLASS_TREES' - . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.One')->set('CATEGORY_CLASS_TREES', ''); // run the field sets for first time $this->setConfigFieldsets(1); - $this->lang = $keepLang; + CFactory::_('Config')->lang_target = $keepLang; // ADMINJS - $this->fileContentStatic[$this->hhh . 'ADMINJS' . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_js'], $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('ADMINJS', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_js'] + )); // SITEJS - $this->fileContentStatic[$this->hhh . 'SITEJS' . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_js'], $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('SITEJS', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_js'] + )); // ADMINCSS - $this->fileContentStatic[$this->hhh . 'ADMINCSS' . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_css_admin'], - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('ADMINCSS', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_css_admin'] + )); // SITECSS - $this->fileContentStatic[$this->hhh . 'SITECSS' . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_css_site'], - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('SITECSS', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_css_site'] + )); // CUSTOM_HELPER_SCRIPT - $this->fileContentStatic[$this->hhh . 'CUSTOM_HELPER_SCRIPT' - . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_php_helper_admin'], - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('CUSTOM_HELPER_SCRIPT', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_php_helper_admin'] + )); // BOTH_CUSTOM_HELPER_SCRIPT - $this->fileContentStatic[$this->hhh . 'BOTH_CUSTOM_HELPER_SCRIPT' - . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_php_helper_both'], - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('BOTH_CUSTOM_HELPER_SCRIPT', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_php_helper_both'] + )); // ADMIN_GLOBAL_EVENT_HELPER - if (!isset($this->fileContentStatic[$this->hhh . 'ADMIN_GLOBAL_EVENT' - . $this->hhh])) + if (!CFactory::_('Compiler.Builder.Content.One')->exists('ADMIN_GLOBAL_EVENT')) { - $this->fileContentStatic[$this->hhh . 'ADMIN_GLOBAL_EVENT' - . $this->hhh] = ''; + CFactory::_('Compiler.Builder.Content.One')->set('ADMIN_GLOBAL_EVENT', ''); } - if (!isset($this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh])) + if (!CFactory::_('Compiler.Builder.Content.One')->exists('ADMIN_GLOBAL_EVENT_HELPER')) { - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] = ''; + CFactory::_('Compiler.Builder.Content.One')->set('ADMIN_GLOBAL_EVENT_HELPER', ''); } // now load the data for the global event if needed - if ($this->componentData->add_admin_event == 1) + if (CFactory::_('Component')->get('add_admin_event', 0) == 1) { // ADMIN_GLOBAL_EVENT - $this->fileContentStatic[$this->hhh . 'ADMIN_GLOBAL_EVENT' - . $this->hhh] - .= PHP_EOL . PHP_EOL . '// Trigger the Global Admin Event'; - $this->fileContentStatic[$this->hhh . 'ADMIN_GLOBAL_EVENT' - . $this->hhh] - .= PHP_EOL . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] - . 'Helper::globalEvent($document);'; + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT', PHP_EOL . PHP_EOL . '// Trigger the Global Admin Event'); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT', + PHP_EOL . CFactory::_('Compiler.Builder.Content.One')->get('Component') + . 'Helper::globalEvent($document);'); // ADMIN_GLOBAL_EVENT_HELPER - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . PHP_EOL . $this->_t(1) . '/**'; - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) - . '* The Global Admin Event Method.'; - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) . '**/'; - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) - . 'public static function globalEvent($document)'; - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) . '{'; - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->setPlaceholders( - $this->customScriptBuilder['component_php_admin_event'], - $this->placeholders - ); - $this->fileContentStatic[$this->hhh - . 'ADMIN_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) . '}'; + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', PHP_EOL . PHP_EOL . Indent::_(1) . '/**'); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', + PHP_EOL . Indent::_(1) + . '* The Global Admin Event Method.'); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', PHP_EOL . Indent::_(1) . '**/'); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', + PHP_EOL . Indent::_(1) + . 'public static function globalEvent($document)'); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', PHP_EOL . Indent::_(1) . '{'); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', + PHP_EOL . CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_php_admin_event'] + )); + CFactory::_('Compiler.Builder.Content.One')->add('ADMIN_GLOBAL_EVENT_HELPER', PHP_EOL . Indent::_(1) . '}'); } // now load the readme file if needed - if ($this->componentData->addreadme == 1) + if (CFactory::_('Component')->get('addreadme', 0) == 1) { - $this->fileContentStatic[$this->hhh . 'EXSTRA_ADMIN_FILES' - . $this->hhh] - .= PHP_EOL . $this->_t(3) - . "README.txt"; + CFactory::_('Compiler.Builder.Content.One')->add('EXSTRA_ADMIN_FILES', + PHP_EOL . Indent::_(3) + . "README.txt"); } // HELPER_CREATEUSER - $this->fileContentStatic[$this->hhh . 'HELPER_CREATEUSER' - . $this->hhh] - = $this->setCreateUserHelperMethod( - $this->componentData->creatuserhelper - ); + CFactory::_('Compiler.Builder.Content.One')->add('HELPER_CREATEUSER', + $this->setCreateUserHelperMethod( + CFactory::_('Component')->get('creatuserhelper') + )); // HELP - $this->fileContentStatic[$this->hhh . 'HELP' . $this->hhh] - = $this->noHelp(); + CFactory::_('Compiler.Builder.Content.One')->set('HELP', $this->noHelp()); // HELP_SITE - $this->fileContentStatic[$this->hhh . 'HELP_SITE' . $this->hhh] - = $this->noHelp(); + CFactory::_('Compiler.Builder.Content.One')->set('HELP_SITE', $this->noHelp()); // build route parse switch - $this->fileContentStatic[$this->hhh . 'ROUTER_PARSE_SWITCH' - . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.One')->set('ROUTER_PARSE_SWITCH', ''); // build route views - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.One')->set('ROUTER_BUILD_VIEWS', ''); // add the helper emailer if set - $this->fileContentStatic[$this->hhh . 'HELPER_EMAIL' . $this->hhh] - = $this->addEmailHelper(); + CFactory::_('Compiler.Builder.Content.One')->set('HELPER_EMAIL', $this->addEmailHelper()); // load the global placeholders - if (ArrayHelper::check($this->globalPlaceholders)) + foreach (CFactory::_('Component.Placeholder')->get() as $globalPlaceholder => + $gloabalValue + ) { - foreach ( - $this->globalPlaceholders as $globalPlaceholder => - $gloabalValue - ) - { - $this->fileContentStatic[$globalPlaceholder] - = $gloabalValue; - } + CFactory::_('Compiler.Builder.Content.One')->set($globalPlaceholder, $gloabalValue); } + // reset view array $viewarray = array(); $site_edit_view_array = array(); // start dynamic build - foreach ($this->componentData->admin_views as $view) + foreach (CFactory::_('Component')->get('admin_views') as $view) { // set the target - $this->target = 'admin'; - $this->lang = 'admin'; + CFactory::_('Config')->build_target = 'admin'; + CFactory::_('Config')->lang_target = 'admin'; // set local names $nameSingleCode = $view['settings']->name_single_code; @@ -395,11 +333,11 @@ class Infusion extends Interpretation ) && $view['edit_create_site_view'] > 0) { - $site_edit_view_array[] = $this->_t(4) . "'" + $site_edit_view_array[] = Indent::_(4) . "'" . $nameSingleCode . "'"; - $this->lang = 'both'; + CFactory::_('Config')->lang_target = 'both'; // insure site view does not get removed - $this->removeSiteEditFolder = false; + CFactory::_('Config')->remove_site_edit_folder = false; } // check if help is being loaded $this->checkHelp($nameSingleCode); @@ -409,7 +347,7 @@ class Infusion extends Interpretation ); // set view array - $viewarray[] = $this->_t(4) . "'" + $viewarray[] = Indent::_(4) . "'" . $nameSingleCode . "' => '" . $nameListCode . "'"; // set the view names @@ -418,336 +356,279 @@ class Infusion extends Interpretation { // set license per view if needed $this->setLockLicensePer( - $nameSingleCode, $this->target + $nameSingleCode, CFactory::_('Config')->build_target ); $this->setLockLicensePer( - $nameListCode, $this->target + $nameListCode, CFactory::_('Config')->build_target ); + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onBeforeBuildAdminEditViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildAdminEditViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$nameSingleCode, &$nameListCode, - &$this->fileContentStatic, - &$this->fileContentDynamic[$nameSingleCode], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$nameSingleCode], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); // FIELDSETS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'FIELDSETS' . $this->hhh] - = $this->setFieldSet( - $view, $this->componentCodeName, - $nameSingleCode, - $nameListCode + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|FIELDSETS', + CFactory::_('Compiler.Creator.Fieldset')->get( + $view, + CFactory::_('Config')->component_code_name, + $nameSingleCode, + $nameListCode + ) ); // ACCESSCONTROL <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'ACCESSCONTROL' . $this->hhh] - = $this->setFieldSetAccessControl( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|ACCESSCONTROL', $this->setFieldSetAccessControl( $nameSingleCode - ); + )); // LINKEDVIEWITEMS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWITEMS' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|LINKEDVIEWITEMS', ''); // ADDTOOLBAR <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'ADDTOOLBAR' . $this->hhh] - = $this->setAddToolBar($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|ADDTOOLBAR', $this->setAddToolBar($view)); // set the script for this view $this->buildTheViewScript($view); // VIEW_SCRIPT - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'VIEW_SCRIPT' . $this->hhh] - = $this->setViewScript( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|VIEW_SCRIPT', $this->setViewScript( $nameSingleCode, 'fileScript' - ); + )); // EDITBODYSCRIPT - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'EDITBODYSCRIPT' . $this->hhh] - = $this->setViewScript( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|EDITBODYSCRIPT', $this->setViewScript( $nameSingleCode, 'footerScript' - ); + )); // AJAXTOKE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'AJAXTOKE' . $this->hhh] - = $this->setAjaxToke( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|AJAXTOKE', $this->setAjaxToke( $nameSingleCode - ); + )); // DOCUMENT_CUSTOM_PHP <<>> - if ($phpDocument = $this->getCustomScriptBuilder( + if ($phpDocument = CFactory::_('Customcode.Dispenser')->get( 'php_document', $nameSingleCode, PHP_EOL, null, true, false )) { - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'DOCUMENT_CUSTOM_PHP' . $this->hhh] - = str_replace( - '$document->', '$this->document->', $phpDocument - ); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|DOCUMENT_CUSTOM_PHP', str_replace( + '$document->', '$this->document->', (string) $phpDocument + )); // clear some memory unset($phpDocument); } else { - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'DOCUMENT_CUSTOM_PHP' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|DOCUMENT_CUSTOM_PHP', ''); } // LINKEDVIEWTABLESCRIPTS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWTABLESCRIPTS' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|LINKEDVIEWTABLESCRIPTS', ''); // VALIDATEFIX <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'VALIDATIONFIX' . $this->hhh] - = $this->setValidationFix( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|VALIDATIONFIX', $this->setValidationFix( $nameSingleCode, - $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] - ); + CFactory::_('Compiler.Builder.Content.One')->get('Component') + )); // EDITBODY <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'EDITBODY' . $this->hhh] - = $this->setEditBody($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|EDITBODY', $this->setEditBody($view)); // EDITBODYFADEIN <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'EDITBODYFADEIN' . $this->hhh] - = $this->setFadeInEfect($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|EDITBODYFADEIN', $this->setFadeInEfect($view)); // JTABLECONSTRUCTOR <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JTABLECONSTRUCTOR' . $this->hhh] - = $this->setJtableConstructor( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JTABLECONSTRUCTOR', $this->setJtableConstructor( $nameSingleCode - ); + )); // JTABLEALIASCATEGORY <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JTABLEALIASCATEGORY' . $this->hhh] - = $this->setJtableAliasCategory( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JTABLEALIASCATEGORY', $this->setJtableAliasCategory( $nameSingleCode - ); + )); // METHOD_GET_ITEM <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'METHOD_GET_ITEM' . $this->hhh] - = $this->setMethodGetItem( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|METHOD_GET_ITEM', $this->setMethodGetItem( $nameSingleCode - ); + )); // LINKEDVIEWGLOBAL <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWGLOBAL' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|LINKEDVIEWGLOBAL', ''); // LINKEDVIEWMETHODS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'LINKEDVIEWMETHODS' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|LINKEDVIEWMETHODS', ''); // JMODELADMIN_BEFORE_DELETE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_BEFORE_DELETE' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_BEFORE_DELETE', CFactory::_('Customcode.Dispenser')->get( 'php_before_delete', $nameSingleCode, PHP_EOL - ); + )); // JMODELADMIN_AFTER_DELETE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_AFTER_DELETE' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_AFTER_DELETE', CFactory::_('Customcode.Dispenser')->get( 'php_after_delete', $nameSingleCode, PHP_EOL . PHP_EOL - ); + )); // JMODELADMIN_BEFORE_DELETE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_BEFORE_PUBLISH' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_BEFORE_PUBLISH', CFactory::_('Customcode.Dispenser')->get( 'php_before_publish', $nameSingleCode, PHP_EOL - ); + )); // JMODELADMIN_AFTER_DELETE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_AFTER_PUBLISH' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_AFTER_PUBLISH', CFactory::_('Customcode.Dispenser')->get( 'php_after_publish', $nameSingleCode, PHP_EOL . PHP_EOL - ); + )); // CHECKBOX_SAVE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'CHECKBOX_SAVE' . $this->hhh] - = $this->setCheckboxSave( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|CHECKBOX_SAVE', $this->setCheckboxSave( $nameSingleCode - ); + )); // METHOD_ITEM_SAVE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'METHOD_ITEM_SAVE' . $this->hhh] - = $this->setMethodItemSave( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|METHOD_ITEM_SAVE', $this->setMethodItemSave( $nameSingleCode - ); + )); // POSTSAVEHOOK <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'POSTSAVEHOOK' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|POSTSAVEHOOK', CFactory::_('Customcode.Dispenser')->get( 'php_postsavehook', $nameSingleCode, PHP_EOL, null, - true, PHP_EOL . $this->_t(2) . "return;", - PHP_EOL . PHP_EOL . $this->_t(2) . "return;" - ); + true, PHP_EOL . Indent::_(2) . "return;", + PHP_EOL . PHP_EOL . Indent::_(2) . "return;" + )); // VIEWCSS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'VIEWCSS' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|VIEWCSS', CFactory::_('Customcode.Dispenser')->get( 'css_view', $nameSingleCode, '', null, true - ); + )); // add css to front end if (isset($view['edit_create_site_view']) - && is_numeric( - $view['edit_create_site_view'] - ) + && is_numeric($view['edit_create_site_view']) && $view['edit_create_site_view'] > 0) { - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'SITE_VIEWCSS' . $this->hhh] - = $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'VIEWCSS' . $this->hhh]; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|SITE_VIEWCSS', CFactory::_('Compiler.Builder.Content.Multi')->get($nameSingleCode . '|VIEWCSS', '')); // check if we should add a create menu if ($view['edit_create_site_view'] == 2) { // SITE_MENU_XML <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'SITE_MENU_XML' . $this->hhh] - = $this->setAdminViewMenu( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|SITE_MENU_XML', $this->setAdminViewMenu( $nameSingleCode, $view - ); + )); } // SITE_ADMIN_VIEW_CONTROLLER_HEADER <<>> add the header details for the controller - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'SITE_ADMIN_VIEW_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|SITE_ADMIN_VIEW_CONTROLLER_HEADER', $this->setFileHeader( 'site.admin.view.controller', $nameSingleCode - ); + )); // SITE_ADMIN_VIEW_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'SITE_ADMIN_VIEW_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|SITE_ADMIN_VIEW_MODEL_HEADER', $this->setFileHeader( 'site.admin.view.model', $nameSingleCode - ); + )); // SITE_ADMIN_VIEW_HTML_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'SITE_ADMIN_VIEW_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|SITE_ADMIN_VIEW_HTML_HEADER', $this->setFileHeader( 'site.admin.view.html', $nameSingleCode - ); + )); // SITE_ADMIN_VIEW_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'SITE_ADMIN_VIEW_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|SITE_ADMIN_VIEW_HEADER', $this->setFileHeader( 'site.admin.view', $nameSingleCode - ); + )); } // TABLAYOUTFIELDSARRAY <<>> add the tab layout fields array to the model - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'TABLAYOUTFIELDSARRAY' . $this->hhh] - = $this->getTabLayoutFieldsArray( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|TABLAYOUTFIELDSARRAY', $this->getTabLayoutFieldsArray( $nameSingleCode - ); + )); // ADMIN_VIEW_CONTROLLER_HEADER <<>> add the header details for the controller - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'ADMIN_VIEW_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|ADMIN_VIEW_CONTROLLER_HEADER', $this->setFileHeader( 'admin.view.controller', $nameSingleCode - ); + )); // ADMIN_VIEW_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'ADMIN_VIEW_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|ADMIN_VIEW_MODEL_HEADER', $this->setFileHeader( 'admin.view.model', $nameSingleCode - ); + )); // ADMIN_VIEW_HTML_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'ADMIN_VIEW_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|ADMIN_VIEW_HTML_HEADER', $this->setFileHeader( 'admin.view.html', $nameSingleCode - ); + )); // ADMIN_VIEW_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'ADMIN_VIEW_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|ADMIN_VIEW_HEADER', $this->setFileHeader( 'admin.view', $nameSingleCode - ); + )); + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onAfterBuildAdminEditViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildAdminEditViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$nameSingleCode, &$nameListCode, - &$this->fileContentStatic, - &$this->fileContentDynamic[$nameSingleCode], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$nameSingleCode], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); } // set the views names if (isset($view['settings']->name_list) && $view['settings']->name_list != 'null') { - $this->lang = 'admin'; + CFactory::_('Config')->lang_target = 'admin'; // ICOMOON <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ICOMOON' . $this->hhh] - = $view['icomoon']; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ICOMOON', $view['icomoon']); + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onBeforeBuildAdminListViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildAdminListViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$nameSingleCode, &$nameListCode, - &$this->fileContentStatic, - &$this->fileContentDynamic[$nameListCode], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$nameListCode], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); // set the export/import option if (isset($view['port']) && $view['port'] || 1 == $view['settings']->add_custom_import) { - $this->eximportView[$nameListCode] - = true; + $this->eximportView[$nameListCode] = true; if (1 == $view['settings']->add_custom_import) { // this view has custom import scripting @@ -769,267 +650,190 @@ class Infusion extends Interpretation if (isset($view['checkin']) && $view['checkin'] == 1) { // AUTOCHECKIN <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'AUTOCHECKIN' . $this->hhh] - = $this->setAutoCheckin( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|AUTOCHECKIN', $this->setAutoCheckin( $nameSingleCode, - $this->componentCodeName - ); + CFactory::_('Config')->component_code_name + )); // CHECKINCALL <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'CHECKINCALL' . $this->hhh] - = $this->setCheckinCall(); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|CHECKINCALL', $this->setCheckinCall()); } else { // AUTOCHECKIN <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'AUTOCHECKIN' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|AUTOCHECKIN', ''); // CHECKINCALL <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'CHECKINCALL' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|CHECKINCALL', ''); } // admin list file contnet - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_JAVASCRIPT_FILE' . $this->hhh] - = $this->setViewScript( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_JAVASCRIPT_FILE', $this->setViewScript( $nameListCode, 'list_fileScript' - ); + )); // ADMIN_CUSTOM_BUTTONS_LIST - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_CUSTOM_BUTTONS_LIST' . $this->hhh] - = $this->setCustomButtons($view, 3, $this->_t(1)); - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_CUSTOM_FUNCTION_ONLY_BUTTONS_LIST' . $this->hhh] - = $this->setFunctionOnlyButtons( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_CUSTOM_BUTTONS_LIST', $this->setCustomButtons($view, 3, Indent::_(1))); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_CUSTOM_FUNCTION_ONLY_BUTTONS_LIST', $this->setFunctionOnlyButtons( $nameListCode - ); + )); // GET_ITEMS_METHOD_STRING_FIX <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'GET_ITEMS_METHOD_STRING_FIX' . $this->hhh] - = $this->setGetItemsMethodStringFix( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|GET_ITEMS_METHOD_STRING_FIX', $this->setGetItemsMethodStringFix( $nameSingleCode, $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] - ); + CFactory::_('Compiler.Builder.Content.One')->get('Component') + )); // GET_ITEMS_METHOD_AFTER_ALL <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'GET_ITEMS_METHOD_AFTER_ALL' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|GET_ITEMS_METHOD_AFTER_ALL', CFactory::_('Customcode.Dispenser')->get( 'php_getitems_after_all', $nameSingleCode, PHP_EOL - ); + )); // SELECTIONTRANSLATIONFIX <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'SELECTIONTRANSLATIONFIX' . $this->hhh] - = $this->setSelectionTranslationFix( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|SELECTIONTRANSLATIONFIX', $this->setSelectionTranslationFix( $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] - ); + CFactory::_('Compiler.Builder.Content.One')->get('Component') + )); // SELECTIONTRANSLATIONFIXFUNC <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'SELECTIONTRANSLATIONFIXFUNC' . $this->hhh] - = $this->setSelectionTranslationFixFunc( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|SELECTIONTRANSLATIONFIXFUNC', $this->setSelectionTranslationFixFunc( $nameListCode, - $this->fileContentStatic[$this->hhh . 'Component' - . $this->hhh] - ); + CFactory::_('Compiler.Builder.Content.One')->get('Component') + )); // FILTER_FIELDS <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'FILTER_FIELDS' . $this->hhh] - = $this->setFilterFieldsArray( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|FILTER_FIELDS', $this->setFilterFieldsArray( $nameSingleCode, $nameListCode - ); + )); // STOREDID <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'STOREDID' . $this->hhh] - = $this->setStoredId( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|STOREDID', $this->setStoredId( $nameSingleCode, $nameListCode - ); + )); // POPULATESTATE <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'POPULATESTATE' . $this->hhh] - = $this->setPopulateState( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|POPULATESTATE', $this->setPopulateState( $nameSingleCode, $nameListCode - ); + )); // SORTFIELDS <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'SORTFIELDS' . $this->hhh] - = $this->setSortFields( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|SORTFIELDS', $this->setSortFields( $nameListCode - ); + )); // CATEGORY_VIEWS - if (!isset( - $this->fileContentStatic[$this->hhh - . 'ROUTER_CATEGORY_VIEWS' . $this->hhh] - )) - { - $this->fileContentStatic[$this->hhh - . 'ROUTER_CATEGORY_VIEWS' . $this->hhh] - = ''; - } - $this->fileContentStatic[$this->hhh - . 'ROUTER_CATEGORY_VIEWS' . $this->hhh] - .= $this->setRouterCategoryViews( + CFactory::_('Compiler.Builder.Content.One')->add('ROUTER_CATEGORY_VIEWS', + $this->setRouterCategoryViews( $nameSingleCode, $nameListCode - ); + )); // FILTERFIELDDISPLAYHELPER <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'FILTERFIELDDISPLAYHELPER' . $this->hhh] - = $this->setFilterFieldSidebarDisplayHelper( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|FILTERFIELDDISPLAYHELPER', $this->setFilterFieldSidebarDisplayHelper( $nameSingleCode, $nameListCode - ); + )); // BATCHDISPLAYHELPER <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'BATCHDISPLAYHELPER' . $this->hhh] - = $this->setBatchDisplayHelper( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|BATCHDISPLAYHELPER', $this->setBatchDisplayHelper( $nameSingleCode, $nameListCode - ); + )); // FILTERFUNCTIONS <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'FILTERFUNCTIONS' . $this->hhh] - = $this->setFilterFieldHelper( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|FILTERFUNCTIONS', $this->setFilterFieldHelper( $nameSingleCode, $nameListCode - ); + )); // FIELDFILTERSETS <<>> - $this->fileContentDynamic['filter_' - . $nameListCode][$this->hhh - . 'FIELDFILTERSETS' . $this->hhh] - = $this->setFieldFilterSet( + CFactory::_('Compiler.Builder.Content.Multi')->set('filter_' . $nameListCode . '|FIELDFILTERSETS', + $this->setFieldFilterSet( $nameSingleCode, $nameListCode - ); + )); // FIELDLISTSETS <<>> - $this->fileContentDynamic['filter_' - . $nameListCode][$this->hhh - . 'FIELDLISTSETS' . $this->hhh] - = $this->setFieldFilterListSet( + CFactory::_('Compiler.Builder.Content.Multi')->set('filter_' . $nameListCode . '|FIELDLISTSETS', + $this->setFieldFilterListSet( $nameSingleCode, $nameListCode - ); + )); // LISTQUERY <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'LISTQUERY' . $this->hhh] - = $this->setListQuery( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|LISTQUERY', $this->setListQuery( $nameSingleCode, $nameListCode - ); + )); // MODELEXPORTMETHOD <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'MODELEXPORTMETHOD' . $this->hhh] - = $this->setGetItemsModelMethod( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|MODELEXPORTMETHOD', $this->setGetItemsModelMethod( $nameSingleCode, $nameListCode - ); + )); // MODELEXIMPORTMETHOD <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'CONTROLLEREXIMPORTMETHOD' . $this->hhh] - = $this->setControllerEximportMethod( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|CONTROLLEREXIMPORTMETHOD', $this->setControllerEximportMethod( $nameSingleCode, $nameListCode - ); + )); // EXPORTBUTTON <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'EXPORTBUTTON' . $this->hhh] - = $this->setExportButton( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|EXPORTBUTTON', $this->setExportButton( $nameSingleCode, $nameListCode - ); + )); // IMPORTBUTTON <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'IMPORTBUTTON' . $this->hhh] - = $this->setImportButton( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|IMPORTBUTTON', $this->setImportButton( $nameSingleCode, $nameListCode - ); + )); // VIEWS_DEFAULT_BODY <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'VIEWS_DEFAULT_BODY' . $this->hhh] - = $this->setDefaultViewsBody( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|VIEWS_DEFAULT_BODY', $this->setDefaultViewsBody( $nameSingleCode, $nameListCode - ); + )); // LISTHEAD <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'LISTHEAD' . $this->hhh] - = $this->setListHead( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|LISTHEAD', $this->setListHead( $nameSingleCode, $nameListCode - ); + )); // LISTBODY <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'LISTBODY' . $this->hhh] - = $this->setListBody( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|LISTBODY', $this->setListBody( $nameSingleCode, $nameListCode - ); + )); // LISTCOLNR <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'LISTCOLNR' . $this->hhh] - = $this->setListColnr( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|LISTCOLNR', $this->setListColnr( $nameListCode - ); + )); // JVIEWLISTCANDO <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'JVIEWLISTCANDO' . $this->hhh] - = $this->setJviewListCanDo( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|JVIEWLISTCANDO', $this->setJviewListCanDo( $nameSingleCode, $nameListCode - ); + )); // VIEWSCSS <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'VIEWSCSS' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|VIEWSCSS', CFactory::_('Customcode.Dispenser')->get( 'css_views', $nameSingleCode, '', null, true - ); + )); // ADMIN_DIPLAY_METHOD <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_DIPLAY_METHOD' . $this->hhh] - = $this->setAdminViewDisplayMethod( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_DIPLAY_METHOD', $this->setAdminViewDisplayMethod( $nameListCode - ); + )); // VIEWS_FOOTER_SCRIPT <<>> - $scriptNote = PHP_EOL . '//' . $this->setLine(__LINE__) + $scriptNote = PHP_EOL . '//' . Line::_(__Line__, __Class__) . ' ' . $nameListCode . ' footer script'; - if (($footerScript = $this->getCustomScriptBuilder( + if (($footerScript = CFactory::_('Customcode.Dispenser')->get( 'views_footer', $nameSingleCode, '', $scriptNote, true, false, PHP_EOL @@ -1037,207 +841,154 @@ class Infusion extends Interpretation && StringHelper::check($footerScript)) { // only minfy if no php is added to the footer script - if ($this->minify - && strpos($footerScript, 'get('minify', 0) + && strpos((string) $footerScript, 'add($footerScript); - $footerScript = $minifier->minify(); - // clear some memory - unset($minifier); + // minify the script + $footerScript = Minify::js($footerScript); } - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'VIEWS_FOOTER_SCRIPT' . $this->hhh] - = PHP_EOL . '"; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|VIEWS_FOOTER_SCRIPT', PHP_EOL . '"); // clear some memory unset($footerScript); } else { - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'VIEWS_FOOTER_SCRIPT' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|VIEWS_FOOTER_SCRIPT', ''); } // ADMIN_VIEWS_CONTROLLER_HEADER <<>> add the header details for the controller - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_VIEWS_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_VIEWS_CONTROLLER_HEADER', $this->setFileHeader( 'admin.views.controller', $nameListCode - ); + )); // ADMIN_VIEWS_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_VIEWS_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_VIEWS_MODEL_HEADER', $this->setFileHeader( 'admin.views.model', $nameListCode - ); + )); // ADMIN_VIEWS_HTML_HEADER <<>> add the header details for the views - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_VIEWS_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_VIEWS_HTML_HEADER', $this->setFileHeader( 'admin.views.html', $nameListCode - ); + )); // ADMIN_VIEWS_HEADER <<>> add the header details for the views - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'ADMIN_VIEWS_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|ADMIN_VIEWS_HEADER', $this->setFileHeader( 'admin.views', $nameListCode - ); + )); + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onAfterBuildAdminListViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildAdminListViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$nameSingleCode, &$nameListCode, - &$this->fileContentStatic, - &$this->fileContentDynamic[$nameListCode], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$nameListCode], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); } // set u fields used in batch - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'UNIQUEFIELDS' . $this->hhh] - = $this->setUniqueFields( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|UNIQUEFIELDS', $this->setUniqueFields( $nameSingleCode - ); + )); // TITLEALIASFIX <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'TITLEALIASFIX' . $this->hhh] - = $this->setAliasTitleFix( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|TITLEALIASFIX', $this->setAliasTitleFix( $nameSingleCode - ); + )); // GENERATENEWTITLE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'GENERATENEWTITLE' . $this->hhh] - = $this->setGenerateNewTitle( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|GENERATENEWTITLE', $this->setGenerateNewTitle( $nameSingleCode - ); + )); // GENERATENEWALIAS <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'GENERATENEWALIAS' . $this->hhh] - = $this->setGenerateNewAlias( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|GENERATENEWALIAS', $this->setGenerateNewAlias( $nameSingleCode - ); + )); // MODEL_BATCH_COPY <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'MODEL_BATCH_COPY' . $this->hhh] - = $this->setBatchCopy($nameSingleCode); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|MODEL_BATCH_COPY', $this->setBatchCopy($nameSingleCode)); // MODEL_BATCH_MOVE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'MODEL_BATCH_MOVE' . $this->hhh] - = $this->setBatchMove($nameSingleCode); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|MODEL_BATCH_MOVE', $this->setBatchMove($nameSingleCode)); // BATCH_ONCLICK_CANCEL_SCRIPT <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'BATCH_ONCLICK_CANCEL_SCRIPT' . $this->hhh] - = ''; // TODO <-- must still be build + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|BATCH_ONCLICK_CANCEL_SCRIPT', ''); // TODO <-- must still be build // JCONTROLLERFORM_ALLOWADD <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JCONTROLLERFORM_ALLOWADD' . $this->hhh] - = $this->setJcontrollerAllowAdd( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JCONTROLLERFORM_ALLOWADD', $this->setJcontrollerAllowAdd( $nameSingleCode, $nameListCode - ); + )); // JCONTROLLERFORM_BEFORECANCEL <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JCONTROLLERFORM_BEFORECANCEL' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JCONTROLLERFORM_BEFORECANCEL', CFactory::_('Customcode.Dispenser')->get( 'php_before_cancel', $nameSingleCode, - PHP_EOL, null, null, + PHP_EOL, null, false, '' - ); + )); // JCONTROLLERFORM_AFTERCANCEL <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JCONTROLLERFORM_AFTERCANCEL' . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JCONTROLLERFORM_AFTERCANCEL', CFactory::_('Customcode.Dispenser')->get( 'php_after_cancel', $nameSingleCode, - PHP_EOL, null, null, + PHP_EOL, null, false, '' - ); + )); // JCONTROLLERFORM_ALLOWEDIT <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JCONTROLLERFORM_ALLOWEDIT' . $this->hhh] - = $this->setJcontrollerAllowEdit( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JCONTROLLERFORM_ALLOWEDIT', $this->setJcontrollerAllowEdit( $nameSingleCode, $nameListCode - ); + )); // JMODELADMIN_GETFORM <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_GETFORM' . $this->hhh] - = $this->setJmodelAdminGetForm( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_GETFORM', $this->setJmodelAdminGetForm( $nameSingleCode, $nameListCode - ); + )); // JMODELADMIN_ALLOWEDIT <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_ALLOWEDIT' . $this->hhh] - = $this->setJmodelAdminAllowEdit( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_ALLOWEDIT', $this->setJmodelAdminAllowEdit( $nameSingleCode, $nameListCode - ); + )); // JMODELADMIN_CANDELETE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_CANDELETE' . $this->hhh] - = $this->setJmodelAdminCanDelete( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_CANDELETE', $this->setJmodelAdminCanDelete( $nameSingleCode, $nameListCode - ); + )); // JMODELADMIN_CANEDITSTATE <<>> - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'JMODELADMIN_CANEDITSTATE' . $this->hhh] - = $this->setJmodelAdminCanEditState( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|JMODELADMIN_CANEDITSTATE', $this->setJmodelAdminCanEditState( $nameSingleCode, $nameListCode - ); + )); // set custom admin view Toolbare buttons // CUSTOM_ADMIN_DYNAMIC_BUTTONS <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'CUSTOM_ADMIN_DYNAMIC_BUTTONS' . $this->hhh] - = $this->setCustomAdminDynamicButton( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|CUSTOM_ADMIN_DYNAMIC_BUTTONS', $this->setCustomAdminDynamicButton( $nameListCode - ); + )); // CUSTOM_ADMIN_DYNAMIC_BUTTONS_CONTROLLER <<>> - $this->fileContentDynamic[$nameListCode][$this->hhh - . 'CUSTOM_ADMIN_DYNAMIC_BUTTONS_CONTROLLER' . $this->hhh] - = $this->setCustomAdminDynamicButtonController( + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|CUSTOM_ADMIN_DYNAMIC_BUTTONS_CONTROLLER', $this->setCustomAdminDynamicButtonController( $nameListCode - ); + )); // set helper router - if (!isset( - $this->fileContentStatic[$this->hhh . 'ROUTEHELPER' - . $this->hhh] - )) - { - $this->fileContentStatic[$this->hhh . 'ROUTEHELPER' - . $this->hhh] - = ''; - } - $this->fileContentStatic[$this->hhh . 'ROUTEHELPER' - . $this->hhh] - .= $this->setRouterHelp( + CFactory::_('Compiler.Builder.Content.One')->add('ROUTEHELPER', + $this->setRouterHelp( $nameSingleCode, $nameListCode - ); + )); if (isset($view['edit_create_site_view']) && is_numeric( @@ -1246,352 +997,276 @@ class Infusion extends Interpretation && $view['edit_create_site_view'] > 0) { // add needed router stuff for front edit views - $this->fileContentStatic[$this->hhh . 'ROUTER_PARSE_SWITCH' - . $this->hhh] - .= $this->routerParseSwitch( + CFactory::_('Compiler.Builder.Content.One')->add('ROUTER_PARSE_SWITCH', + $this->routerParseSwitch( $nameSingleCode, null, false - ); - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] - .= $this->routerBuildViews( + )); + CFactory::_('Compiler.Builder.Content.One')->add('ROUTER_BUILD_VIEWS', + $this->routerBuildViews( $nameSingleCode - ); + )); } // ACCESS_SECTIONS - if (!isset( - $this->fileContentStatic[$this->hhh . 'ACCESS_SECTIONS' - . $this->hhh] - )) - { - $this->fileContentStatic[$this->hhh . 'ACCESS_SECTIONS' - . $this->hhh] - = ''; - } - $this->fileContentStatic[$this->hhh . 'ACCESS_SECTIONS' - . $this->hhh] - .= $this->setAccessSectionsCategory( + CFactory::_('Compiler.Builder.Content.One')->add('ACCESS_SECTIONS', + $this->setAccessSectionsCategory( $nameSingleCode, $nameListCode - ); + )); // set the Joomla Fields ACCESS section if needed if (isset($view['joomla_fields']) && $view['joomla_fields'] == 1) { - $this->fileContentStatic[$this->hhh . 'ACCESS_SECTIONS' - . $this->hhh] - .= $this->setAccessSectionsJoomlaFields(); + CFactory::_('Compiler.Builder.Content.One')->add('ACCESS_SECTIONS', $this->setAccessSectionsJoomlaFields()); } + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onAfterBuildAdminViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildAdminViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$nameSingleCode, &$nameListCode, - &$this->fileContentStatic, - &$this->fileContentDynamic, &$this->placeholders, + &$fileContentStatic, + &$fileContentDynamic, &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); } + // all fields stored in database + CFactory::_('Compiler.Builder.Content.One')->set('ALL_COMPONENT_FIELDS', CFactory::_('Compiler.Builder.Component.Fields')->varExport(null, 1)); + // setup the layouts $this->setCustomViewLayouts(); // setup custom_admin_views and all needed stuff for the site - if (isset($this->componentData->custom_admin_views) - && ArrayHelper::check( - $this->componentData->custom_admin_views - )) + if (CFactory::_('Component')->isArray('custom_admin_views')) { - $this->target = 'custom_admin'; - $this->lang = 'admin'; + CFactory::_('Config')->build_target = 'custom_admin'; + CFactory::_('Config')->lang_target = 'admin'; // start dynamic build - foreach ($this->componentData->custom_admin_views as $view) + foreach (CFactory::_('Component')->get('custom_admin_views') as $view) { // for single views - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SView' . $this->hhh] - = $view['settings']->Code; - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'sview' . $this->hhh] - = $view['settings']->code; - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SVIEW' . $this->hhh] - = $view['settings']->CODE; + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SView', $view['settings']->Code); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|sview', $view['settings']->code); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SVIEW', $view['settings']->CODE); // for list views - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SViews' . $this->hhh] - = $view['settings']->Code; - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'sviews' . $this->hhh] - = $view['settings']->code; - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SVIEWS' . $this->hhh] - = $view['settings']->CODE; + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SViews', $view['settings']->Code); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|sviews', $view['settings']->code); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SVIEWS', $view['settings']->CODE); // add to lang array - $this->setLangContent( - $this->lang, - $this->langPrefix . '_' . $view['settings']->CODE, + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, + CFactory::_('Config')->lang_prefix . '_' . $view['settings']->CODE, $view['settings']->name ); - $this->setLangContent( - $this->lang, - $this->langPrefix . '_' . $view['settings']->CODE + CFactory::_('Language')->set( + CFactory::_('Config')->lang_target, + CFactory::_('Config')->lang_prefix . '_' . $view['settings']->CODE . '_DESC', $view['settings']->description ); // ICOMOON <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'ICOMOON' . $this->hhh] - = $view['icomoon']; + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|ICOMOON', $view['icomoon']); // set placeholders - $this->placeholders[$this->hhh . 'SView' . $this->hhh] - = $view['settings']->Code; - $this->placeholders[$this->hhh . 'sview' . $this->hhh] - = $view['settings']->code; - $this->placeholders[$this->hhh . 'SVIEW' . $this->hhh] - = $view['settings']->CODE; - $this->placeholders[$this->bbb . 'SView' . $this->ddd] - = $view['settings']->Code; - $this->placeholders[$this->bbb . 'sview' . $this->ddd] - = $view['settings']->code; - $this->placeholders[$this->bbb . 'SVIEW' . $this->ddd] - = $view['settings']->CODE; - $this->placeholders[$this->hhh . 'SViews' . $this->hhh] - = $view['settings']->Code; - $this->placeholders[$this->hhh . 'sviews' . $this->hhh] - = $view['settings']->code; - $this->placeholders[$this->hhh . 'SVIEWS' . $this->hhh] - = $view['settings']->CODE; - $this->placeholders[$this->bbb . 'SViews' . $this->ddd] - = $view['settings']->Code; - $this->placeholders[$this->bbb . 'sviews' . $this->ddd] - = $view['settings']->code; - $this->placeholders[$this->bbb . 'SVIEWS' . $this->ddd] - = $view['settings']->CODE; + CFactory::_('Placeholder')->set('SView', $view['settings']->Code); + CFactory::_('Placeholder')->set('sview', $view['settings']->code); + CFactory::_('Placeholder')->set('SVIEW', $view['settings']->CODE); + CFactory::_('Placeholder')->set('SViews', $view['settings']->Code); + CFactory::_('Placeholder')->set('sviews', $view['settings']->code); + CFactory::_('Placeholder')->set('SVIEWS', $view['settings']->CODE); + + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onBeforeBuildCustomAdminViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildCustomAdminViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$view['settings']->code, - &$this->fileContentStatic, - &$this->fileContentDynamic[$view['settings']->code], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$view['settings']->code], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); // set license per view if needed $this->setLockLicensePer( - $view['settings']->code, $this->target + $view['settings']->code, CFactory::_('Config')->build_target ); // check if this custom admin view is the default view - if ($this->dynamicDashboardType === 'custom_admin_views' - && $this->dynamicDashboard === $view['settings']->code) + if (CFactory::_('Registry')->get('build.dashboard.type', '') === 'custom_admin_views' + && CFactory::_('Registry')->get('build.dashboard', '') === $view['settings']->code) { // HIDEMAINMENU <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'HIDEMAINMENU' . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|HIDEMAINMENU', ''); } else { // HIDEMAINMENU <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'HIDEMAINMENU' . $this->hhh] - = PHP_EOL . $this->_t(2) . '//' . $this->setLine( - __LINE__ + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|HIDEMAINMENU', PHP_EOL . Indent::_(2) . '//' . Line::_( + __LINE__,__CLASS__ ) . " hide the main menu" - . PHP_EOL . $this->_t(2) - . "\$this->app->input->set('hidemainmenu', true);"; + . PHP_EOL . Indent::_(2) + . "\$this->app->input->set('hidemainmenu', true);"); } if ($view['settings']->main_get->gettype == 1) { // CUSTOM_ADMIN_BEFORE_GET_ITEM <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_BEFORE_GET_ITEM' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_before_getitem', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_BEFORE_GET_ITEM', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_before_getitem', $view['settings']->code, '', null, true - ); + )); // CUSTOM_ADMIN_GET_ITEM <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_GET_ITEM' . $this->hhh] - = $this->setCustomViewGetItem( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_GET_ITEM', $this->setCustomViewGetItem( $view['settings']->main_get, - $view['settings']->code, $this->_t(2) - ); + $view['settings']->code, Indent::_(2) + )); // CUSTOM_ADMIN_AFTER_GET_ITEM <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_AFTER_GET_ITEM' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_after_getitem', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_AFTER_GET_ITEM', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_after_getitem', $view['settings']->code, '', null, true - ); + )); } elseif ($view['settings']->main_get->gettype == 2) { // CUSTOM_ADMIN_GET_LIST_QUERY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_GET_LIST_QUERY' . $this->hhh] - = $this->setCustomViewListQuery( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_GET_LIST_QUERY', $this->setCustomViewListQuery( $view['settings']->main_get, $view['settings']->code - ); + )); // CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_getlistquery', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_getlistquery', $view['settings']->code, PHP_EOL, null, true - ); + )); // CUSTOM_ADMIN_BEFORE_GET_ITEMS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_BEFORE_GET_ITEMS' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_before_getitems', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_BEFORE_GET_ITEMS', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_before_getitems', $view['settings']->code, PHP_EOL, null, true - ); + )); // CUSTOM_ADMIN_GET_ITEMS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_GET_ITEMS' . $this->hhh] - = $this->setCustomViewGetItems( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_GET_ITEMS', $this->setCustomViewGetItems( $view['settings']->main_get, $view['settings']->code - ); + )); // CUSTOM_ADMIN_AFTER_GET_ITEMS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_AFTER_GET_ITEMS' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_after_getitems', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_AFTER_GET_ITEMS', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_after_getitems', $view['settings']->code, PHP_EOL, null, true - ); + )); } // CUSTOM_ADMIN_CUSTOM_METHODS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_CUSTOM_METHODS' . $this->hhh] - = $this->setCustomViewCustomItemMethods( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_CUSTOM_METHODS', $this->setCustomViewCustomItemMethods( $view['settings']->main_get, $view['settings']->code - ); - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_CUSTOM_METHODS' . $this->hhh] - .= $this->setCustomViewCustomMethods( - $view, $view['settings']->code + )); + CFactory::_('Compiler.Builder.Content.Multi')->add($view['settings']->code . '|CUSTOM_ADMIN_CUSTOM_METHODS', + $this->setCustomViewCustomMethods( + $view, $view['settings']->code + ). false ); // CUSTOM_ADMIN_DIPLAY_METHOD <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_DIPLAY_METHOD' . $this->hhh] - = $this->setCustomViewDisplayMethod($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_DIPLAY_METHOD', $this->setCustomViewDisplayMethod($view)); // set document details $this->setPrepareDocument($view); // CUSTOM_ADMIN_EXTRA_DIPLAY_METHODS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_EXTRA_DIPLAY_METHODS' . $this->hhh] - = $this->setCustomViewExtraDisplayMethods($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_EXTRA_DIPLAY_METHODS', $this->setCustomViewExtraDisplayMethods($view)); // CUSTOM_ADMIN_CODE_BODY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_CODE_BODY' . $this->hhh] - = $this->setCustomViewCodeBody($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_CODE_BODY', $this->setCustomViewCodeBody($view)); // CUSTOM_ADMIN_BODY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_BODY' . $this->hhh] - = $this->setCustomViewBody($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_BODY', $this->setCustomViewBody($view)); // CUSTOM_ADMIN_SUBMITBUTTON_SCRIPT <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_SUBMITBUTTON_SCRIPT' . $this->hhh] - = $this->setCustomViewSubmitButtonScript($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_SUBMITBUTTON_SCRIPT', $this->setCustomViewSubmitButtonScript($view)); // setup the templates $this->setCustomViewTemplateBody($view); // set the site form if needed - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_TOP_FORM' . $this->hhh] - = $this->setCustomViewForm( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_TOP_FORM', $this->setCustomViewForm( $view['settings']->code, $view['settings']->main_get->gettype, 1 - ); - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_BOTTOM_FORM' . $this->hhh] - = $this->setCustomViewForm( + )); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_BOTTOM_FORM', $this->setCustomViewForm( $view['settings']->code, $view['settings']->main_get->gettype, 2 - ); + )); // set headers based on the main get type if ($view['settings']->main_get->gettype == 1) { // CUSTOM_ADMIN_VIEW_CONTROLLER_HEADER <<>> add the header details for the controller - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEW_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEW_CONTROLLER_HEADER', $this->setFileHeader( 'custom.admin.view.controller', $view['settings']->code - ); + )); // CUSTOM_ADMIN_VIEW_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEW_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEW_MODEL_HEADER', $this->setFileHeader( 'custom.admin.view.model', $view['settings']->code - ); + )); // CUSTOM_ADMIN_VIEW_HTML_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEW_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEW_HTML_HEADER', $this->setFileHeader( 'custom.admin.view.html', $view['settings']->code - ); + )); // CUSTOM_ADMIN_VIEW_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEW_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEW_HEADER', $this->setFileHeader( 'custom.admin.view', $view['settings']->code - ); + )); } elseif ($view['settings']->main_get->gettype == 2) { // CUSTOM_ADMIN_VIEWS_CONTROLLER_HEADER <<>> add the header details for the controller - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEWS_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEWS_CONTROLLER_HEADER', $this->setFileHeader( 'custom.admin.views.controller', $view['settings']->code - ); + )); // CUSTOM_ADMIN_VIEWS_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEWS_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEWS_MODEL_HEADER', $this->setFileHeader( 'custom.admin.views.model', $view['settings']->code - ); + )); // CUSTOM_ADMIN_VIEWS_HTML_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEWS_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEWS_HTML_HEADER', $this->setFileHeader( 'custom.admin.views.html', $view['settings']->code - ); + )); // CUSTOM_ADMIN_VIEWS_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'CUSTOM_ADMIN_VIEWS_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|CUSTOM_ADMIN_VIEWS_HEADER', $this->setFileHeader( 'custom.admin.views', $view['settings']->code - ); + )); } + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onAfterBuildCustomAdminViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildCustomAdminViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$view['settings']->code, - &$this->fileContentStatic, - &$this->fileContentDynamic[$view['settings']->code], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$view['settings']->code], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); } // setup the layouts @@ -1599,227 +1274,168 @@ class Infusion extends Interpretation } // ADMIN_HELPER_CLASS_HEADER - $this->fileContentStatic[$this->hhh . 'ADMIN_HELPER_CLASS_HEADER' - . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.One')->set('ADMIN_HELPER_CLASS_HEADER', + $this->setFileHeader( 'admin.helper', 'admin' - ); + )); // ADMIN_COMPONENT_HEADER - $this->fileContentStatic[$this->hhh . 'ADMIN_COMPONENT_HEADER' - . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.One')->set('ADMIN_COMPONENT_HEADER', + $this->setFileHeader( 'admin.component', 'admin' - ); + )); // SITE_HELPER_CLASS_HEADER - $this->fileContentStatic[$this->hhh . 'SITE_HELPER_CLASS_HEADER' - . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.One')->set('SITE_HELPER_CLASS_HEADER', + $this->setFileHeader( 'site.helper', 'site' - ); + )); // SITE_COMPONENT_HEADER - $this->fileContentStatic[$this->hhh . 'SITE_COMPONENT_HEADER' - . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.One')->set('SITE_COMPONENT_HEADER', + $this->setFileHeader( 'site.component', 'site' - ); + )); // HELPER_EXEL - $this->fileContentStatic[$this->hhh . 'HELPER_EXEL' - . $this->hhh] - = $this->setHelperExelMethods(); + CFactory::_('Compiler.Builder.Content.One')->set('HELPER_EXEL', $this->setHelperExelMethods()); // VIEWARRAY - $this->fileContentStatic[$this->hhh . 'VIEWARRAY' . $this->hhh] - = PHP_EOL . implode("," . PHP_EOL, $viewarray); + CFactory::_('Compiler.Builder.Content.One')->set('VIEWARRAY', PHP_EOL . implode("," . PHP_EOL, $viewarray)); // CUSTOM_ADMIN_EDIT_VIEW_ARRAY - $this->fileContentStatic[$this->hhh . 'SITE_EDIT_VIEW_ARRAY' - . $this->hhh] - = PHP_EOL . implode("," . PHP_EOL, $site_edit_view_array); + CFactory::_('Compiler.Builder.Content.One')->set('SITE_EDIT_VIEW_ARRAY', PHP_EOL . implode("," . PHP_EOL, $site_edit_view_array)); // MAINMENUS - $this->fileContentStatic[$this->hhh . 'MAINMENUS' . $this->hhh] - = $this->setMainMenus(); + CFactory::_('Compiler.Builder.Content.One')->set('MAINMENUS', $this->setMainMenus()); // SUBMENU - $this->fileContentStatic[$this->hhh . 'SUBMENU' . $this->hhh] - = $this->setSubMenus(); + CFactory::_('Compiler.Builder.Content.One')->set('SUBMENU', $this->setSubMenus()); // GET_CRYPT_KEY - $this->fileContentStatic[$this->hhh . 'GET_CRYPT_KEY' . $this->hhh] - = $this->setGetCryptKey(); + CFactory::_('Compiler.Builder.Content.One')->set('GET_CRYPT_KEY', $this->setGetCryptKey()); // set the license locker $this->setLockLicense(); // CONTRIBUTORS - $this->fileContentStatic[$this->hhh . 'CONTRIBUTORS' . $this->hhh] - = $this->theContributors; + CFactory::_('Compiler.Builder.Content.One')->set('CONTRIBUTORS', $this->theContributors); // INSTALL - $this->fileContentStatic[$this->hhh . 'INSTALL' . $this->hhh] - = $this->setInstall(); + CFactory::_('Compiler.Builder.Content.One')->set('INSTALL', $this->setInstall()); // UNINSTALL - $this->fileContentStatic[$this->hhh . 'UNINSTALL' . $this->hhh] - = $this->setUninstall(); + CFactory::_('Compiler.Builder.Content.One')->set('UNINSTALL', $this->setUninstall()); // UPDATE_VERSION_MYSQL $this->setVersionController(); // only set these if default dashboard it used - if (!StringHelper::check($this->dynamicDashboard)) + if (!CFactory::_('Registry')->get('build.dashboard')) { // DASHBOARDVIEW - $this->fileContentStatic[$this->hhh . 'DASHBOARDVIEW' - . $this->hhh] - = $this->componentCodeName; + CFactory::_('Compiler.Builder.Content.One')->set('DASHBOARDVIEW', CFactory::_('Config')->component_code_name); // DASHBOARDICONS - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASHBOARDICONS' . $this->hhh] - = $this->setDashboardIcons(); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASHBOARDICONS', $this->setDashboardIcons()); // DASHBOARDICONACCESS - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASHBOARDICONACCESS' . $this->hhh] - = $this->setDashboardIconAccess(); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASHBOARDICONACCESS', $this->setDashboardIconAccess()); // DASH_MODEL_METHODS - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_MODEL_METHODS' . $this->hhh] - = $this->setDashboardModelMethods(); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_MODEL_METHODS', $this->setDashboardModelMethods()); // DASH_GET_CUSTOM_DATA - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_GET_CUSTOM_DATA' . $this->hhh] - = $this->setDashboardGetCustomData(); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_GET_CUSTOM_DATA', $this->setDashboardGetCustomData()); // DASH_DISPLAY_DATA - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_DISPLAY_DATA' . $this->hhh] - = $this->setDashboardDisplayData(); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_DISPLAY_DATA', $this->setDashboardDisplayData()); // DASH_VIEW_HEADER - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_VIEW_HEADER' . $this->hhh] - = $this->setFileHeader('dashboard.view', 'dashboard'); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_VIEW_HEADER', $this->setFileHeader('dashboard.view', 'dashboard')); // DASH_VIEW_HTML_HEADER - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_VIEW_HTML_HEADER' . $this->hhh] - = $this->setFileHeader('dashboard.view.html', 'dashboard'); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_VIEW_HTML_HEADER', $this->setFileHeader('dashboard.view.html', 'dashboard')); // DASH_MODEL_HEADER - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader('dashboard.model', 'dashboard'); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_MODEL_HEADER', $this->setFileHeader('dashboard.model', 'dashboard')); // DASH_CONTROLLER_HEADER - $this->fileContentDynamic[$this->componentCodeName][$this->hhh - . 'DASH_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader('dashboard.controller', 'dashboard'); + CFactory::_('Compiler.Builder.Content.Multi')->set(CFactory::_('Config')->component_code_name . '|DASH_CONTROLLER_HEADER', $this->setFileHeader('dashboard.controller', 'dashboard')); } else { // DASHBOARDVIEW - $this->fileContentStatic[$this->hhh . 'DASHBOARDVIEW' - . $this->hhh] - = $this->dynamicDashboard; + CFactory::_('Compiler.Builder.Content.One')->set('DASHBOARDVIEW', CFactory::_('Registry')->get('build.dashboard')); } // add import - if (isset($this->addEximport) && $this->addEximport) + if (CFactory::_('Config')->get('add_eximport', false)) { // setup import files $target = array('admin' => 'import'); - $this->buildDynamique($target, 'import'); + CFactory::_('Utilities.Structure')->build($target, 'import'); // IMPORT_EXT_METHOD <<>> - $this->fileContentDynamic['import'][$this->hhh - . 'IMPORT_EXT_METHOD' . $this->hhh] - = PHP_EOL . PHP_EOL . $this->setPlaceholders( - ComponentbuilderHelper::getDynamicScripts('ext'), - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.Multi')->set('import' . '|IMPORT_EXT_METHOD', PHP_EOL . PHP_EOL . CFactory::_('Placeholder')->update_( + ComponentbuilderHelper::getDynamicScripts('ext') + )); // IMPORT_SETDATA_METHOD <<>> - $this->fileContentDynamic['import'][$this->hhh - . 'IMPORT_SETDATA_METHOD' . $this->hhh] - = PHP_EOL . PHP_EOL . $this->setPlaceholders( - ComponentbuilderHelper::getDynamicScripts('setdata'), - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.Multi')->set('import' . '|IMPORT_SETDATA_METHOD', PHP_EOL . PHP_EOL . CFactory::_('Placeholder')->update_( + ComponentbuilderHelper::getDynamicScripts('setdata') + )); // IMPORT_SAVE_METHOD <<>> - $this->fileContentDynamic['import'][$this->hhh - . 'IMPORT_SAVE_METHOD' . $this->hhh] - = PHP_EOL . PHP_EOL . $this->setPlaceholders( - ComponentbuilderHelper::getDynamicScripts('save'), - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.Multi')->set('import' . '|IMPORT_SAVE_METHOD', PHP_EOL . PHP_EOL . CFactory::_('Placeholder')->update_( + ComponentbuilderHelper::getDynamicScripts('save') + )); + // IMPORT_CONTROLLER_HEADER <<>> add the header details for the controller + CFactory::_('Compiler.Builder.Content.Multi')->set('import' . '|IMPORT_CONTROLLER_HEADER', $this->setFileHeader( + 'import.controller', 'import' + )); + // IMPORT_MODEL_HEADER <<>> add the header details for the model + CFactory::_('Compiler.Builder.Content.Multi')->set('import' . '|IMPORT_MODEL_HEADER', $this->setFileHeader( + 'import.model', 'import' + )); } // ensure that the ajax model and controller is set if needed - if (isset($this->addAjax) && $this->addAjax) + if (CFactory::_('Config')->get('add_ajax', false)) { // setup Ajax files $target = array('admin' => 'ajax'); - $this->buildDynamique($target, 'ajax'); + CFactory::_('Utilities.Structure')->build($target, 'ajax'); // set the controller - $this->fileContentDynamic['ajax'][$this->hhh - . 'REGISTER_AJAX_TASK' . $this->hhh] - = $this->setRegisterAjaxTask('admin'); - $this->fileContentDynamic['ajax'][$this->hhh - . 'AJAX_INPUT_RETURN' . $this->hhh] - = $this->setAjaxInputReturn('admin'); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|REGISTER_AJAX_TASK', $this->setRegisterAjaxTask('admin')); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|AJAX_INPUT_RETURN', $this->setAjaxInputReturn('admin')); // set the model header - $this->fileContentDynamic['ajax'][$this->hhh - . 'AJAX_ADMIN_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader('ajax.admin.model', 'ajax'); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|AJAX_ADMIN_MODEL_HEADER', $this->setFileHeader('ajax.admin.model', 'ajax')); // set the module - $this->fileContentDynamic['ajax'][$this->hhh - . 'AJAX_MODEL_METHODS' . $this->hhh] - = $this->setAjaxModelMethods('admin'); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|AJAX_MODEL_METHODS', $this->setAjaxModelMethods('admin')); } // ensure that the site ajax model and controller is set if needed - if (isset($this->addSiteAjax) && $this->addSiteAjax) + if (CFactory::_('Config')->get('add_site_ajax', false)) { // setup Ajax files $target = array('site' => 'ajax'); - $this->buildDynamique($target, 'ajax'); + CFactory::_('Utilities.Structure')->build($target, 'ajax'); // set the controller - $this->fileContentDynamic['ajax'][$this->hhh - . 'REGISTER_SITE_AJAX_TASK' . $this->hhh] - = $this->setRegisterAjaxTask('site'); - $this->fileContentDynamic['ajax'][$this->hhh - . 'AJAX_SITE_INPUT_RETURN' . $this->hhh] - = $this->setAjaxInputReturn('site'); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|REGISTER_SITE_AJAX_TASK', $this->setRegisterAjaxTask('site')); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|AJAX_SITE_INPUT_RETURN', $this->setAjaxInputReturn('site')); // set the model header - $this->fileContentDynamic['ajax'][$this->hhh - . 'AJAX_SITE_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader('ajax.site.model', 'ajax'); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|AJAX_SITE_MODEL_HEADER', $this->setFileHeader('ajax.site.model', 'ajax')); // set the module - $this->fileContentDynamic['ajax'][$this->hhh - . 'AJAX_SITE_MODEL_METHODS' . $this->hhh] - = $this->setAjaxModelMethods('site'); + CFactory::_('Compiler.Builder.Content.Multi')->set('ajax' . '|AJAX_SITE_MODEL_METHODS', $this->setAjaxModelMethods('site')); } // build the validation rules - if (isset($this->validationRules) - && ArrayHelper::check($this->validationRules)) + if (($validationRules = CFactory::_('Registry')->_('validation.rules')) !== null) { - foreach ($this->validationRules as $rule => $_php) + foreach ($validationRules as $rule => $_php) { // setup rule file $target = array('admin' => 'a_rule_zi'); - $this->buildDynamique($target, 'rule', $rule); + CFactory::_('Utilities.Structure')->build($target, 'rule', $rule); // set the JFormRule Name - $this->fileContentDynamic['a_rule_zi_' . $rule][$this->hhh - . 'Name' . $this->hhh] - = ucfirst($rule); + CFactory::_('Compiler.Builder.Content.Multi')->set('a_rule_zi_' . $rule . '|Name', ucfirst((string) $rule)); // set the JFormRule PHP - $this->fileContentDynamic['a_rule_zi_' . $rule][$this->hhh - . 'VALIDATION_RULE_METHODS' . $this->hhh] - = PHP_EOL . $_php; + CFactory::_('Compiler.Builder.Content.Multi')->set('a_rule_zi_' . $rule . '|VALIDATION_RULE_METHODS', PHP_EOL . $_php); } } @@ -1842,235 +1458,174 @@ class Infusion extends Interpretation } // CONFIG_FIELDSETS - $keepLang = $this->lang; - $this->lang = 'admin'; + $keepLang = CFactory::_('Config')->lang_target; + CFactory::_('Config')->lang_target = 'admin'; // run field sets for second time $this->setConfigFieldsets(2); - $this->lang = $keepLang; + CFactory::_('Config')->lang_target = $keepLang; // setup front-views and all needed stuff for the site - if (isset($this->componentData->site_views) - && ArrayHelper::check( - $this->componentData->site_views - )) + if (CFactory::_('Component')->isArray('site_views')) { - $this->target = 'site'; + CFactory::_('Config')->build_target = 'site'; // start dynamic build - foreach ($this->componentData->site_views as $view) + foreach (CFactory::_('Component')->get('site_views') as $view) { // for list views - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SViews' . $this->hhh] - = $view['settings']->Code; - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'sviews' . $this->hhh] - = $view['settings']->code; + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SViews', $view['settings']->Code); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|sviews', $view['settings']->code); // for single views - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SView' . $this->hhh] - = $view['settings']->Code; - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'sview' . $this->hhh] - = $view['settings']->code; + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SView', $view['settings']->Code); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|sview', $view['settings']->code); - // set placeholder - $this->placeholders[$this->hhh . 'SView' . $this->hhh] - = $view['settings']->Code; - $this->placeholders[$this->hhh . 'sview' . $this->hhh] - = $view['settings']->code; - $this->placeholders[$this->hhh . 'SVIEW' . $this->hhh] - = $view['settings']->CODE; - $this->placeholders[$this->bbb . 'SView' . $this->ddd] - = $view['settings']->Code; - $this->placeholders[$this->bbb . 'sview' . $this->ddd] - = $view['settings']->code; - $this->placeholders[$this->bbb . 'SVIEW' . $this->ddd] - = $view['settings']->CODE; - $this->placeholders[$this->hhh . 'SViews' . $this->hhh] - = $view['settings']->Code; - $this->placeholders[$this->hhh . 'sviews' . $this->hhh] - = $view['settings']->code; - $this->placeholders[$this->hhh . 'SVIEWS' . $this->hhh] - = $view['settings']->CODE; - $this->placeholders[$this->bbb . 'SViews' . $this->ddd] - = $view['settings']->Code; - $this->placeholders[$this->bbb . 'sviews' . $this->ddd] - = $view['settings']->code; - $this->placeholders[$this->bbb . 'SVIEWS' . $this->ddd] - = $view['settings']->CODE; + // set placeholders + CFactory::_('Placeholder')->set('SView', $view['settings']->Code); + CFactory::_('Placeholder')->set('sview', $view['settings']->code); + CFactory::_('Placeholder')->set('SVIEW', $view['settings']->CODE); + CFactory::_('Placeholder')->set('SViews', $view['settings']->Code); + CFactory::_('Placeholder')->set('sviews', $view['settings']->code); + CFactory::_('Placeholder')->set('SVIEWS', $view['settings']->CODE); + + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onBeforeBuildSiteViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildSiteViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$view['settings']->code, - &$this->fileContentStatic, - &$this->fileContentDynamic[$view['settings']->code], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$view['settings']->code], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); // set license per view if needed $this->setLockLicensePer( - $view['settings']->code, $this->target + $view['settings']->code, CFactory::_('Config')->build_target ); // set the site default view if (isset($view['default_view']) && $view['default_view'] == 1) { - $this->fileContentStatic[$this->hhh - . 'SITE_DEFAULT_VIEW' . $this->hhh] - = $view['settings']->code; + CFactory::_('Compiler.Builder.Content.One')->set('SITE_DEFAULT_VIEW', $view['settings']->code); } // add site menu if (isset($view['menu']) && $view['menu'] == 1) { // SITE_MENU_XML <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_MENU_XML' . $this->hhh] - = $this->setCustomViewMenu($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_MENU_XML', $this->setCustomViewMenu($view)); } // insure the needed route helper is loaded - $this->fileContentStatic[$this->hhh . 'ROUTEHELPER' - . $this->hhh] - .= $this->setRouterHelp( + CFactory::_('Compiler.Builder.Content.One')->add('ROUTEHELPER', + $this->setRouterHelp( $view['settings']->code, $view['settings']->code, true - ); + )); // build route details - $this->fileContentStatic[$this->hhh . 'ROUTER_PARSE_SWITCH' - . $this->hhh] - .= $this->routerParseSwitch( + CFactory::_('Compiler.Builder.Content.One')->add('ROUTER_PARSE_SWITCH', + $this->routerParseSwitch( $view['settings']->code, $view - ); - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] - .= $this->routerBuildViews($view['settings']->code); + )); + CFactory::_('Compiler.Builder.Content.One')->add('ROUTER_BUILD_VIEWS', $this->routerBuildViews($view['settings']->code)); if ($view['settings']->main_get->gettype == 1) { // set user permission access check USER_PERMISSION_CHECK_ACCESS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'USER_PERMISSION_CHECK_ACCESS' . $this->hhh] - = $this->setUserPermissionCheckAccess($view, 1); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|USER_PERMISSION_CHECK_ACCESS', $this->setUserPermissionCheckAccess($view, 1)); // SITE_BEFORE_GET_ITEM <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_BEFORE_GET_ITEM' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_before_getitem', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_BEFORE_GET_ITEM', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_before_getitem', $view['settings']->code, '', null, true - ); + )); // SITE_GET_ITEM <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_GET_ITEM' . $this->hhh] - = $this->setCustomViewGetItem( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_GET_ITEM', $this->setCustomViewGetItem( $view['settings']->main_get, - $view['settings']->code, $this->_t(2) - ); + $view['settings']->code, Indent::_(2) + )); // SITE_AFTER_GET_ITEM <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_AFTER_GET_ITEM' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_after_getitem', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_AFTER_GET_ITEM', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_after_getitem', $view['settings']->code, '', null, true - ); + )); } elseif ($view['settings']->main_get->gettype == 2) { // set user permission access check USER_PERMISSION_CHECK_ACCESS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'USER_PERMISSION_CHECK_ACCESS' . $this->hhh] - = $this->setUserPermissionCheckAccess($view, 2); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|USER_PERMISSION_CHECK_ACCESS', $this->setUserPermissionCheckAccess($view, 2)); // SITE_GET_LIST_QUERY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_GET_LIST_QUERY' . $this->hhh] - = $this->setCustomViewListQuery( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_GET_LIST_QUERY', $this->setCustomViewListQuery( $view['settings']->main_get, $view['settings']->code - ); + )); // SITE_BEFORE_GET_ITEMS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_BEFORE_GET_ITEMS' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_before_getitems', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_BEFORE_GET_ITEMS', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_before_getitems', $view['settings']->code, PHP_EOL, null, true - ); + )); // SITE_GET_ITEMS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_GET_ITEMS' . $this->hhh] - = $this->setCustomViewGetItems( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_GET_ITEMS', $this->setCustomViewGetItems( $view['settings']->main_get, $view['settings']->code - ); + )); // SITE_AFTER_GET_ITEMS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_AFTER_GET_ITEMS' . $this->hhh] - = $this->getCustomScriptBuilder( - $this->target . '_php_after_getitems', + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_AFTER_GET_ITEMS', CFactory::_('Customcode.Dispenser')->get( + CFactory::_('Config')->build_target . '_php_after_getitems', $view['settings']->code, PHP_EOL, null, true - ); + )); } // add to lang array - $this->setLangContent( + CFactory::_('Language')->set( 'site', - $this->langPrefix . '_' . $view['settings']->CODE, + CFactory::_('Config')->lang_prefix . '_' . $view['settings']->CODE, $view['settings']->name ); - $this->setLangContent( + CFactory::_('Language')->set( 'site', - $this->langPrefix . '_' . $view['settings']->CODE + CFactory::_('Config')->lang_prefix . '_' . $view['settings']->CODE . '_DESC', $view['settings']->description ); // SITE_CUSTOM_METHODS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_CUSTOM_METHODS' . $this->hhh] - = $this->setCustomViewCustomItemMethods( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_CUSTOM_METHODS', $this->setCustomViewCustomItemMethods( $view['settings']->main_get, $view['settings']->code - ); - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_CUSTOM_METHODS' . $this->hhh] - .= $this->setCustomViewCustomMethods( - $view, $view['settings']->code + )); + CFactory::_('Compiler.Builder.Content.Multi')->add($view['settings']->code . '|SITE_CUSTOM_METHODS', + $this->setCustomViewCustomMethods( + $view, $view['settings']->code + ), false ); // SITE_DIPLAY_METHOD <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_DIPLAY_METHOD' . $this->hhh] - = $this->setCustomViewDisplayMethod($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_DIPLAY_METHOD', $this->setCustomViewDisplayMethod($view)); // set document details $this->setPrepareDocument($view); // SITE_EXTRA_DIPLAY_METHODS <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_EXTRA_DIPLAY_METHODS' . $this->hhh] - = $this->setCustomViewExtraDisplayMethods($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_EXTRA_DIPLAY_METHODS', $this->setCustomViewExtraDisplayMethods($view)); // SITE_CODE_BODY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_CODE_BODY' . $this->hhh] - = $this->setCustomViewCodeBody($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_CODE_BODY', $this->setCustomViewCodeBody($view)); // SITE_BODY <<>> - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_BODY' . $this->hhh] - = $this->setCustomViewBody($view); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_BODY', $this->setCustomViewBody($view)); // setup the templates $this->setCustomViewTemplateBody($view); // set the site form if needed - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_TOP_FORM' . $this->hhh] - = $this->setCustomViewForm( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_TOP_FORM', $this->setCustomViewForm( $view['settings']->code, $view['settings']->main_get->gettype, 1 - ); - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_BOTTOM_FORM' . $this->hhh] - = $this->setCustomViewForm( + )); + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_BOTTOM_FORM', $this->setCustomViewForm( $view['settings']->code, $view['settings']->main_get->gettype, 2 - ); + )); // set headers based on the main get type if ($view['settings']->main_get->gettype == 1) @@ -2082,30 +1637,22 @@ class Infusion extends Interpretation && $view['settings']->php_controller != '//') { // SITE_VIEW_CONTROLLER_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEW_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEW_CONTROLLER_HEADER', $this->setFileHeader( 'site.view.controller', $view['settings']->code - ); + )); } // SITE_VIEW_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEW_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEW_MODEL_HEADER', $this->setFileHeader( 'site.view.model', $view['settings']->code - ); + )); // SITE_VIEW_HTML_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEW_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEW_HTML_HEADER', $this->setFileHeader( 'site.view.html', $view['settings']->code - ); + )); // SITE_VIEW_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEW_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEW_HEADER', $this->setFileHeader( 'site.view', $view['settings']->code - ); + )); } elseif ($view['settings']->main_get->gettype == 2) { @@ -2116,41 +1663,40 @@ class Infusion extends Interpretation && $view['settings']->php_controller != '//') { // SITE_VIEW_CONTROLLER_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEW_CONTROLLER_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEW_CONTROLLER_HEADER', $this->setFileHeader( 'site.views.controller', $view['settings']->code - ); + )); } // SITE_VIEWS_MODEL_HEADER <<>> add the header details for the model - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEWS_MODEL_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEWS_MODEL_HEADER', $this->setFileHeader( 'site.views.model', $view['settings']->code - ); + )); // SITE_VIEWS_HTML_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEWS_HTML_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEWS_HTML_HEADER', $this->setFileHeader( 'site.views.html', $view['settings']->code - ); + )); // SITE_VIEWS_HEADER <<>> add the header details for the view - $this->fileContentDynamic[$view['settings']->code][$this->hhh - . 'SITE_VIEWS_HEADER' . $this->hhh] - = $this->setFileHeader( + CFactory::_('Compiler.Builder.Content.Multi')->set($view['settings']->code . '|SITE_VIEWS_HEADER', $this->setFileHeader( 'site.views', $view['settings']->code - ); + )); } + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onAfterBuildSiteViewContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildSiteViewContent', - array(&$this->componentContext, &$view, + array(&$component_context, &$view, &$view['settings']->code, - &$this->fileContentStatic, - &$this->fileContentDynamic[$view['settings']->code], - &$this->placeholders, &$this->hhh) + &$fileContentStatic, + &$fileContentDynamic[$view['settings']->code], + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); } // setup the layouts @@ -2159,241 +1705,158 @@ class Infusion extends Interpretation else { // clear all site folder since none is needed - $this->removeSiteFolder = true; + CFactory::_('Config')->remove_site_folder = true; } // load the site statics - if (!$this->removeSiteFolder || !$this->removeSiteEditFolder) + if (!CFactory::_('Config')->remove_site_folder || !CFactory::_('Config')->remove_site_edit_folder) { - $this->target = 'site'; + CFactory::_('Config')->build_target = 'site'; // if no default site view was set, the redirect to root - if (!isset( - $this->fileContentStatic[$this->hhh . 'SITE_DEFAULT_VIEW' - . $this->hhh] - )) + if (!CFactory::_('Compiler.Builder.Content.One')->exists('SITE_DEFAULT_VIEW')) { - $this->fileContentStatic[$this->hhh . 'SITE_DEFAULT_VIEW' - . $this->hhh] - = ''; + CFactory::_('Compiler.Builder.Content.One')->set('SITE_DEFAULT_VIEW', ''); } // set site custom script to helper class // SITE_CUSTOM_HELPER_SCRIPT - $this->fileContentStatic[$this->hhh - . 'SITE_CUSTOM_HELPER_SCRIPT' . $this->hhh] - = $this->setPlaceholders( - $this->customScriptBuilder['component_php_helper_site'], - $this->placeholders - ); + CFactory::_('Compiler.Builder.Content.One')->set('SITE_CUSTOM_HELPER_SCRIPT', + CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_php_helper_site'] + )); // SITE_GLOBAL_EVENT_HELPER - if (!isset($this->fileContentStatic[$this->hhh . 'SITE_GLOBAL_EVENT' - . $this->hhh])) + if (!CFactory::_('Compiler.Builder.Content.One')->exists('SITE_GLOBAL_EVENT')) { - $this->fileContentStatic[$this->hhh . 'SITE_GLOBAL_EVENT' - . $this->hhh] = ''; + CFactory::_('Compiler.Builder.Content.One')->set('SITE_GLOBAL_EVENT', ''); } - if (!isset($this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh])) + if (!CFactory::_('Compiler.Builder.Content.One')->exists('SITE_GLOBAL_EVENT_HELPER')) { - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] = ''; + CFactory::_('Compiler.Builder.Content.One')->set('SITE_GLOBAL_EVENT_HELPER', ''); } // now load the data for the global event if needed - if ($this->componentData->add_site_event == 1) + if (CFactory::_('Component')->get('add_site_event', 0) == 1) { - $this->fileContentStatic[$this->hhh . 'SITE_GLOBAL_EVENT' - . $this->hhh] - .= PHP_EOL . PHP_EOL . '// Trigger the Global Site Event'; - $this->fileContentStatic[$this->hhh . 'SITE_GLOBAL_EVENT' - . $this->hhh] - .= PHP_EOL . $this->fileContentStatic[$this->hhh - . 'Component' . $this->hhh] - . 'Helper::globalEvent($document);'; + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT', PHP_EOL . PHP_EOL . '// Trigger the Global Site Event'); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT', + PHP_EOL . CFactory::_('Compiler.Builder.Content.One')->get('Component') + . 'Helper::globalEvent($document);'); // SITE_GLOBAL_EVENT_HELPER - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . PHP_EOL . $this->_t(1) . '/**'; - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) - . '* The Global Site Event Method.'; - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) . '**/'; - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) - . 'public static function globalEvent($document)'; - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) . '{'; - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->setPlaceholders( - $this->customScriptBuilder['component_php_site_event'], - $this->placeholders - ); - $this->fileContentStatic[$this->hhh - . 'SITE_GLOBAL_EVENT_HELPER' . $this->hhh] - .= PHP_EOL . $this->_t(1) . '}'; + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', PHP_EOL . PHP_EOL . Indent::_(1) . '/**'); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', + PHP_EOL . Indent::_(1) + . '* The Global Site Event Method.'); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', PHP_EOL . Indent::_(1) . '**/'); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', + PHP_EOL . Indent::_(1) + . 'public static function globalEvent($document)'); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', PHP_EOL . Indent::_(1) . '{'); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', + PHP_EOL . CFactory::_('Placeholder')->update_( + CFactory::_('Customcode.Dispenser')->hub['component_php_site_event'] + )); + CFactory::_('Compiler.Builder.Content.One')->add('SITE_GLOBAL_EVENT_HELPER', PHP_EOL . Indent::_(1) . '}'); } } // PREINSTALLSCRIPT - $this->fileContentStatic[$this->hhh . 'PREINSTALLSCRIPT' - . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.One')->add('PREINSTALLSCRIPT', + CFactory::_('Customcode.Dispenser')->get( 'php_preflight', 'install', PHP_EOL, null, true - ); + )); // PREUPDATESCRIPT - $this->fileContentStatic[$this->hhh . 'PREUPDATESCRIPT' - . $this->hhh] - = $this->getCustomScriptBuilder( + CFactory::_('Compiler.Builder.Content.One')->add('PREUPDATESCRIPT', + CFactory::_('Customcode.Dispenser')->get( 'php_preflight', 'update', PHP_EOL, null, true - ); + )); // POSTINSTALLSCRIPT - $this->fileContentStatic[$this->hhh . 'POSTINSTALLSCRIPT' - . $this->hhh] - = $this->setPostInstallScript(); + CFactory::_('Compiler.Builder.Content.One')->add('POSTINSTALLSCRIPT', $this->setPostInstallScript()); // POSTUPDATESCRIPT - $this->fileContentStatic[$this->hhh . 'POSTUPDATESCRIPT' - . $this->hhh] - = $this->setPostUpdateScript(); + CFactory::_('Compiler.Builder.Content.One')->add('POSTUPDATESCRIPT', $this->setPostUpdateScript()); // UNINSTALLSCRIPT - $this->fileContentStatic[$this->hhh . 'UNINSTALLSCRIPT' - . $this->hhh] - = $this->setUninstallScript(); + CFactory::_('Compiler.Builder.Content.One')->add('UNINSTALLSCRIPT', $this->setUninstallScript()); // MOVEFOLDERSSCRIPT - $this->fileContentStatic[$this->hhh . 'MOVEFOLDERSSCRIPT' - . $this->hhh] - = $this->setMoveFolderScript(); + CFactory::_('Compiler.Builder.Content.One')->set('MOVEFOLDERSSCRIPT', $this->setMoveFolderScript()); // MOVEFOLDERSMETHOD - $this->fileContentStatic[$this->hhh . 'MOVEFOLDERSMETHOD' - . $this->hhh] - = $this->setMoveFolderMethod(); + CFactory::_('Compiler.Builder.Content.One')->set('MOVEFOLDERSMETHOD', $this->setMoveFolderMethod()); // HELPER_UIKIT - $this->fileContentStatic[$this->hhh . 'HELPER_UIKIT' . $this->hhh] - = $this->setUikitHelperMethods(); + CFactory::_('Compiler.Builder.Content.One')->set('HELPER_UIKIT', $this->setUikitHelperMethods()); // CONFIG_FIELDSETS - $this->fileContentStatic[$this->hhh . 'CONFIG_FIELDSETS' - . $this->hhh] - = implode(PHP_EOL, $this->configFieldSets); + CFactory::_('Compiler.Builder.Content.One')->set('CONFIG_FIELDSETS', implode(PHP_EOL, $this->configFieldSets)); // check if this has been set - if (!isset( - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] - ) + if (!CFactory::_('Compiler.Builder.Content.One')->exists('ROUTER_BUILD_VIEWS') || !StringHelper::check( - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] + CFactory::_('Compiler.Builder.Content.One')->get('ROUTER_BUILD_VIEWS') )) { - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] - = 0; + CFactory::_('Compiler.Builder.Content.One')->set('ROUTER_BUILD_VIEWS', 0); } else { - $this->fileContentStatic[$this->hhh . 'ROUTER_BUILD_VIEWS' - . $this->hhh] - = '(' . $this->fileContentStatic[$this->hhh - . 'ROUTER_BUILD_VIEWS' . $this->hhh] . ')'; + CFactory::_('Compiler.Builder.Content.One')->set('ROUTER_BUILD_VIEWS', '(' . CFactory::_('Compiler.Builder.Content.One')->get('ROUTER_BUILD_VIEWS') . ')'); } // README - if ($this->componentData->addreadme) + if (CFactory::_('Component')->get('addreadme')) { - $this->fileContentStatic[$this->hhh . 'README' . $this->hhh] - = $this->componentData->readme; + CFactory::_('Compiler.Builder.Content.One')->set('README', CFactory::_('Component')->get('readme')); } - // remove all the power placeholders - $this->fileContentStatic[$this->hhh . 'ADMIN_POWER_HELPER' . $this->hhh] = ''; - $this->fileContentStatic[$this->hhh . 'SITE_POWER_HELPER' . $this->hhh] = ''; - $this->fileContentStatic[$this->hhh . 'CUSTOM_POWER_AUTOLOADER' . $this->hhh] = ''; - // infuse powers data if set - if (ArrayHelper::check($this->powers)) + + // CHANGELOG + if (($changelog = CFactory::_('Component')->get('changelog')) !== null) { - // start the autoloader - $autoloader = array(); - foreach ($this->powers as $power) - { - if (ObjectHelper::check($power)) - { - // Trigger Event: jcb_ce_onBeforeInfusePowerData - $this->triggerEvent( - 'jcb_ce_onBeforeInfusePowerData', - array(&$this->componentContext, &$power, &$this) - ); - // POWERCODE - $this->fileContentDynamic[$power->key][$this->hhh - . 'POWERCODE' . $this->hhh] - = $this->getPowerCode($power); - // build the autoloader - $autoloader[implode('.', $power->_namespace_prefix)] = $power->_namespace_prefix; - // Trigger Event: jcb_ce_onAfterInfusePowerData - $this->triggerEvent( - 'jcb_ce_onAfterInfusePowerData', - array(&$this->componentContext, &$power, &$this) - ); - } - } - // now set the power autoloader - $this->setPowersAutoloader($autoloader, (!$this->removeSiteFolder || !$this->removeSiteEditFolder)); + CFactory::_('Compiler.Builder.Content.One')->set('CHANGELOG', $changelog); } + + // Infuse POWERS + CFactory::_('Power.Infusion')->set(); + // tweak system to set stuff to the module domain - $_backup_target = $this->target; - $_backup_lang = $this->lang; - $_backup_langPrefix = $this->langPrefix; + $_backup_target = CFactory::_('Config')->build_target; + $_backup_lang = CFactory::_('Config')->lang_target; + $_backup_langPrefix = CFactory::_('Config')->lang_prefix; // infuse module data if set - if (ArrayHelper::check($this->joomlaModules)) + if (CFactory::_('Joomlamodule.Data')->exists()) { - foreach ($this->joomlaModules as $module) + foreach (CFactory::_('Joomlamodule.Data')->get() as $module) { if (ObjectHelper::check($module)) { // Trigger Event: jcb_ce_onBeforeInfuseModuleData - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeInfuseModuleData', - array(&$this->componentContext, &$module, &$this) + array(&$component_context, &$module, &$this) ); - $this->target = $module->key; - $this->lang = $module->key; + CFactory::_('Config')->build_target = $module->key; + CFactory::_('Config')->lang_target = $module->key; $this->langPrefix = $module->lang_prefix; + CFactory::_('Config')->set('lang_prefix', $module->lang_prefix); // MODCODE - $this->fileContentDynamic[$module->key][$this->hhh - . 'MODCODE' . $this->hhh] - = $this->getModCode($module); + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|MODCODE', $this->getModCode($module)); // DYNAMICGET - $this->fileContentDynamic[$module->key][$this->hhh - . 'DYNAMICGETS' . $this->hhh] - = $this->setCustomViewCustomMethods( + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|DYNAMICGETS', $this->setCustomViewCustomMethods( $module, $module->key - ); + )); // HELPERCODE if ($module->add_class_helper >= 1) { - $this->fileContentDynamic[$module->key][$this->hhh - . 'HELPERCODE' . $this->hhh] - = $this->getModHelperCode($module); + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|HELPERCODE', $this->getModHelperCode($module)); } // MODDEFAULT - $this->fileContentDynamic[$module->key][$this->hhh - . 'MODDEFAULT' . $this->hhh] - = $this->getModDefault($module, $module->key); + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|MODDEFAULT', $this->getModDefault($module, $module->key)); + // MODDEFAULT_XXX + $this->setModTemplates($module); // only add install script if needed if ($module->add_install_script) { // INSTALLCLASS - $this->fileContentDynamic[$module->key][$this->hhh - . 'INSTALLCLASS' . $this->hhh] - = $this->getExtensionInstallClass($module); + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|INSTALLCLASS', CFactory::_('Extension.InstallScript')->get($module)); } // FIELDSET if (isset($module->form_files) @@ -2408,54 +1871,49 @@ class Infusion extends Interpretation foreach ($fieldsets as $fieldset => $fields) { // FIELDSET_ . $file.$field_name.$fieldset - $this->fileContentDynamic[$module->key][$this->hhh - . 'FIELDSET_' . $file . $field_name - . $fieldset . $this->hhh] - = $this->getExtensionFieldsetXML( - $module, $fields + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . + '|FIELDSET_' . $file . $field_name . $fieldset, + $this->getExtensionFieldsetXML( + $module, $fields + ) ); } } } } // MAINXML - $this->fileContentDynamic[$module->key][$this->hhh - . 'MAINXML' . $this->hhh] - = $this->getModuleMainXML($module); + CFactory::_('Compiler.Builder.Content.Multi')->set($module->key . '|MAINXML', $this->getModuleMainXML($module)); // Trigger Event: jcb_ce_onAfterInfuseModuleData - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterInfuseModuleData', - array(&$this->componentContext, &$module, &$this) + array(&$component_context, &$module, &$this) ); } } } // infuse plugin data if set - if (ArrayHelper::check($this->joomlaPlugins)) + if (CFactory::_('Joomlaplugin.Data')->exists()) { - foreach ($this->joomlaPlugins as $plugin) + foreach (CFactory::_('Joomlaplugin.Data')->get() as $plugin) { if (ObjectHelper::check($plugin)) { // Trigger Event: jcb_ce_onBeforeInfusePluginData - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeInfusePluginData', - array(&$this->componentContext, &$plugin, &$this) + array(&$component_context, &$plugin, &$this) ); - $this->target = $plugin->key; - $this->lang = $plugin->key; + CFactory::_('Config')->build_target = $plugin->key; + CFactory::_('Config')->lang_target = $plugin->key; $this->langPrefix = $plugin->lang_prefix; + CFactory::_('Config')->set('lang_prefix', $plugin->lang_prefix); // MAINCLASS - $this->fileContentDynamic[$plugin->key][$this->hhh - . 'MAINCLASS' . $this->hhh] - = $this->getPluginMainClass($plugin); + CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . '|MAINCLASS', $this->getPluginMainClass($plugin)); // only add install script if needed if ($plugin->add_install_script) { // INSTALLCLASS - $this->fileContentDynamic[$plugin->key][$this->hhh - . 'INSTALLCLASS' . $this->hhh] - = $this->getExtensionInstallClass($plugin); + CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . '|INSTALLCLASS', CFactory::_('Extension.InstallScript')->get($plugin)); } // FIELDSET if (isset($plugin->form_files) @@ -2470,39 +1928,45 @@ class Infusion extends Interpretation foreach ($fieldsets as $fieldset => $fields) { // FIELDSET_ . $file.$field_name.$fieldset - $this->fileContentDynamic[$plugin->key][$this->hhh - . 'FIELDSET_' . $file . $field_name - . $fieldset . $this->hhh] - = $this->getExtensionFieldsetXML( - $plugin, $fields + CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . + '|FIELDSET_' . $file . $field_name . $fieldset, + $this->getExtensionFieldsetXML( + $plugin, $fields + ) ); } } } } // MAINXML - $this->fileContentDynamic[$plugin->key][$this->hhh - . 'MAINXML' . $this->hhh] - = $this->getPluginMainXML($plugin); + CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . '|MAINXML', $this->getPluginMainXML($plugin)); // Trigger Event: jcb_ce_onAfterInfusePluginData - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterInfusePluginData', - array(&$this->componentContext, &$plugin, &$this) + array(&$component_context, &$plugin, &$this) ); } } } // rest globals - $this->target = $_backup_target; - $this->lang = $_backup_lang; + CFactory::_('Config')->build_target = $_backup_target; + CFactory::_('Config')->lang_target = $_backup_lang; $this->langPrefix = $_backup_langPrefix; + CFactory::_('Config')->set('lang_prefix', $_backup_langPrefix); + // for plugin event TODO change event api signatures + $placeholders = CFactory::_('Placeholder')->active; + $fileContentStatic = CFactory::_('Compiler.Builder.Content.One')->allActive(); + $fileContentDynamic = CFactory::_('Compiler.Builder.Content.Multi')->allActive(); // Trigger Event: jcb_ce_onAfterBuildFilesContent - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildFilesContent', - array(&$this->componentContext, &$this->componentData, - &$this->fileContentStatic, &$this->fileContentDynamic, - &$this->placeholders, &$this->hhh) + array(&$component_context, &$this->componentData, + &$fileContentStatic, &$fileContentDynamic, + &$placeholders, &$this->hhh) ); + unset($fileContentStatic); + unset($fileContentDynamic); + unset($placeholders); return true; } @@ -2520,7 +1984,8 @@ class Infusion extends Interpretation protected function setViewPlaceholders(&$view) { // just to be safe, lets clear previous view placeholders - $this->clearFromPlaceHolders('view'); + CFactory::_('Placeholder')->clearType('view'); + CFactory::_('Placeholder')->clearType('views'); // VIEW <<>> if (isset($view->name_single) && $view->name_single != 'null') @@ -2535,18 +2000,9 @@ class Infusion extends Interpretation ); // set some place holder for the views - $this->placeholders[$this->hhh . 'view' . $this->hhh] - = $nameSingleCode; - $this->placeholders[$this->hhh . 'View' . $this->hhh] - = $name_single_first_uppercase; - $this->placeholders[$this->hhh . 'VIEW' . $this->hhh] - = $name_single_uppercase; - $this->placeholders[$this->bbb . 'view' . $this->ddd] - = $nameSingleCode; - $this->placeholders[$this->bbb . 'View' . $this->ddd] - = $name_single_first_uppercase; - $this->placeholders[$this->bbb . 'VIEW' . $this->ddd] - = $name_single_uppercase; + CFactory::_('Placeholder')->set('view', $nameSingleCode); + CFactory::_('Placeholder')->set('View', $name_single_first_uppercase); + CFactory::_('Placeholder')->set('VIEW', $name_single_uppercase); } // VIEWS <<>> @@ -2561,74 +2017,38 @@ class Infusion extends Interpretation ); // set some place holder for the views - $this->placeholders[$this->hhh . 'views' . $this->hhh] - = $nameListCode; - $this->placeholders[$this->hhh . 'Views' . $this->hhh] - = $name_list_first_uppercase; - $this->placeholders[$this->hhh . 'VIEWS' . $this->hhh] - = $name_list_uppercase; - $this->placeholders[$this->bbb . 'views' . $this->ddd] - = $nameListCode; - $this->placeholders[$this->bbb . 'Views' . $this->ddd] - = $name_list_first_uppercase; - $this->placeholders[$this->bbb . 'VIEWS' . $this->ddd] - = $name_list_uppercase; + CFactory::_('Placeholder')->set('views', $nameListCode); + CFactory::_('Placeholder')->set('Views', $name_list_first_uppercase); + CFactory::_('Placeholder')->set('VIEWS', $name_list_uppercase); } // view <<>> if (isset($nameSingleCode)) { - $this->fileContentDynamic[$nameSingleCode][$this->hhh . 'view' - . $this->hhh] - = $nameSingleCode; - $this->fileContentDynamic[$nameSingleCode][$this->hhh . 'VIEW' - . $this->hhh] - = $name_single_uppercase; - $this->fileContentDynamic[$nameSingleCode][$this->hhh . 'View' - . $this->hhh] - = $name_single_first_uppercase; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|view', $nameSingleCode); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|VIEW', $name_single_uppercase); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|View', $name_single_first_uppercase); if (isset($nameListCode)) { - $this->fileContentDynamic[$nameListCode][$this->hhh . 'view' - . $this->hhh] - = $nameSingleCode; - $this->fileContentDynamic[$nameListCode][$this->hhh . 'VIEW' - . $this->hhh] - = $name_single_uppercase; - $this->fileContentDynamic[$nameListCode][$this->hhh . 'View' - . $this->hhh] - = $name_single_first_uppercase; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|view', $nameSingleCode); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|VIEW', $name_single_uppercase); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|View', $name_single_first_uppercase); } } // views <<>> if (isset($nameListCode)) { - $this->fileContentDynamic[$nameListCode][$this->hhh . 'views' - . $this->hhh] - = $nameListCode; - $this->fileContentDynamic[$nameListCode][$this->hhh . 'VIEWS' - . $this->hhh] - = $name_list_uppercase; - $this->fileContentDynamic[$nameListCode][$this->hhh . 'Views' - . $this->hhh] - = $name_list_first_uppercase; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|views', $nameListCode); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|VIEWS', $name_list_uppercase); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameListCode . '|Views', $name_list_first_uppercase); if (isset($nameSingleCode)) { - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'views' - . $this->hhh] - = $nameListCode; - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'VIEWS' - . $this->hhh] - = $name_list_uppercase; - $this->fileContentDynamic[$nameSingleCode][$this->hhh - . 'Views' - . $this->hhh] - = $name_list_first_uppercase; + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|views', $nameListCode); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|VIEWS', $name_list_uppercase); + CFactory::_('Compiler.Builder.Content.Multi')->set($nameSingleCode . '|Views', $name_list_first_uppercase); } } } @@ -2648,59 +2068,63 @@ class Infusion extends Interpretation if ($this->setLangAdmin()) { $values[] = array_values( - $this->languages['components'][$this->langTag]['admin'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['admin'] ); $mainLangLoader['admin'] = count( - $this->languages['components'][$this->langTag]['admin'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['admin'] ); } // check the admin system lang is set if ($this->setLangAdminSys()) { $values[] = array_values( - $this->languages['components'][$this->langTag]['adminsys'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['adminsys'] ); $mainLangLoader['adminsys'] = count( - $this->languages['components'][$this->langTag]['adminsys'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['adminsys'] ); } // check the site lang is set - if ((!$this->removeSiteFolder || !$this->removeSiteEditFolder) + if ((!CFactory::_('Config')->remove_site_folder || !CFactory::_('Config')->remove_site_edit_folder) && $this->setLangSite()) { $values[] = array_values( - $this->languages['components'][$this->langTag]['site'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['site'] ); $mainLangLoader['site'] = count( - $this->languages['components'][$this->langTag]['site'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['site'] ); } // check the site system lang is set - if ((!$this->removeSiteFolder || !$this->removeSiteEditFolder) + if ((!CFactory::_('Config')->remove_site_folder || !CFactory::_('Config')->remove_site_edit_folder) && $this->setLangSiteSys()) { $values[] = array_values( - $this->languages['components'][$this->langTag]['sitesys'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['sitesys'] ); $mainLangLoader['sitesys'] = count( - $this->languages['components'][$this->langTag]['sitesys'] + $this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['sitesys'] ); } $values = array_unique(ArrayHelper::merge($values)); // get the other lang strings if there is any $this->multiLangString = $this->getMultiLangStrings($values); // update insert the current lang in to DB - $this->setLangPlaceholders($values, $this->componentID); + $this->setLangPlaceholders($values, CFactory::_('Config')->component_id); // remove old unused language strings - $this->purgeLanuageStrings($values, $this->componentID); + $this->purgeLanuageStrings($values, CFactory::_('Config')->component_id); // path to INI file - $getPAth = $this->templatePath . '/en-GB.com_admin.ini'; + $getPAth = CFactory::_('Utilities.Paths')->template_path . '/en-GB.com_admin.ini'; + // for plugin event TODO change event api signatures + $component_context = CFactory::_('Config')->component_context; // Trigger Event: jcb_ce_onBeforeBuildAllLangFiles - $this->triggerEvent( + CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildAllLangFiles', - array(&$this->componentContext, &$this->languages['components'], + array(&$component_context, &$this->languages['components'], &$this->langTag) ); + // for plugin event TODO change event api signatures + CFactory::_('Config')->lang_tag = $this->langTag; // now we insert the values into the files if (ArrayHelper::check($this->languages['components'])) { @@ -2709,27 +2133,27 @@ class Infusion extends Interpretation foreach ($this->languages['components'] as $tag => $areas) { // trim the tag - $tag = trim($tag); + $tag = trim((string) $tag); foreach ($areas as $area => $languageStrings) { // set naming convention $p = 'admin'; $t = ''; - if (strpos($area, 'site') !== false) + if (strpos((string) $area, 'site') !== false) { - if ($this->removeSiteFolder - && $this->removeSiteEditFolder) + if (CFactory::_('Config')->remove_site_folder + && CFactory::_('Config')->remove_site_edit_folder) { continue; } $p = 'site'; } - if (strpos($area, 'sys') !== false) + if (strpos((string) $area, 'sys') !== false) { $t = '.sys'; } // build the file name - $file_name = $tag . '.com_' . $this->componentCodeName . $t + $file_name = $tag . '.com_' . CFactory::_('Config')->component_code_name . $t . '.ini'; // check if language should be added if ($this->shouldLanguageBeAdded( @@ -2738,31 +2162,30 @@ class Infusion extends Interpretation )) { // build the path to place the lang file - $path = $this->componentPath . '/' . $p . '/language/' + $path = CFactory::_('Utilities.Paths')->component_path . '/' . $p . '/language/' . $tag . '/'; if (!Folder::exists($path)) { Folder::create($path); // count the folder created - $this->folderCount++; + CFactory::_('Utilities.Counter')->folder++; } // move the file to its place File::copy($getPAth, $path . $file_name); // count the file created - $this->fileCount++; + CFactory::_('Utilities.Counter')->file++; // add content to it $lang = array_map( - function ($langstring, $placeholder) { - return $placeholder . '="' . $langstring . '"'; - }, array_values($languageStrings), + fn($langstring, $placeholder) => $placeholder . '="' . $langstring . '"', + array_values($languageStrings), array_keys($languageStrings) ); // add to language file - $this->writeFile( + CFactory::_('Utilities.File')->write( $path . $file_name, implode(PHP_EOL, $lang) ); // set the line counter - $this->lineCount = $this->lineCount + count( + CFactory::_('Utilities.Counter')->line += count( (array) $lang ); unset($lang); @@ -2784,27 +2207,27 @@ class Infusion extends Interpretation if (isset($langXML['admin']) && ArrayHelper::check($langXML['admin'])) { - $replace[$this->hhh . 'ADMIN_LANGUAGES' . $this->hhh] - = implode(PHP_EOL . $this->_t(3), $langXML['admin']); + $replace[Placefix::_h('ADMIN_LANGUAGES')] + = implode(PHP_EOL . Indent::_(3), $langXML['admin']); } - if ((!$this->removeSiteFolder || !$this->removeSiteEditFolder) + if ((!CFactory::_('Config')->remove_site_folder || !CFactory::_('Config')->remove_site_edit_folder) && isset($langXML['site']) && ArrayHelper::check($langXML['site'])) { - $replace[$this->hhh . 'SITE_LANGUAGES' . $this->hhh] - = implode(PHP_EOL . $this->_t(2), $langXML['site']); + $replace[Placefix::_h('SITE_LANGUAGES')] + = implode(PHP_EOL . Indent::_(2), $langXML['site']); } // build xml path - $xmlPath = $this->componentPath . '/' . $this->componentCodeName + $xmlPath = CFactory::_('Utilities.Paths')->component_path . '/' . CFactory::_('Config')->component_code_name . '.xml'; // get the content in xml $componentXML = FileHelper::getContent( $xmlPath ); // update the xml content - $componentXML = $this->setPlaceholders($componentXML, $replace); + $componentXML = CFactory::_('Placeholder')->update($componentXML, $replace); // store the values back to xml - $this->writeFile($xmlPath, $componentXML); + CFactory::_('Utilities.File')->write($xmlPath, $componentXML); } } } diff --git a/admin/helpers/componentbuilder.php b/admin/helpers/componentbuilder.php index 98e6cfb74..32ea59243 100644 --- a/admin/helpers/componentbuilder.php +++ b/admin/helpers/componentbuilder.php @@ -12,13 +12,24 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +// add the autoloader for the composer classes +$composer_autoloader = JPATH_LIBRARIES . '/phpseclib3/vendor/autoload.php'; +if (file_exists($composer_autoloader)) +{ + require_once $composer_autoloader; +} + // register this component namespace spl_autoload_register(function ($class) { // project-specific base directories and namespace prefix - $search = array( + $search = [ + 'libraries/jcb_powers/VDM.Joomla.Openai' => 'VDM\\Joomla\\Openai', + 'libraries/jcb_powers/VDM.Joomla.Gitea' => 'VDM\\Joomla\\Gitea', + 'libraries/jcb_powers/VDM.Joomla.FOF' => 'VDM\\Joomla\\FOF', 'libraries/jcb_powers/VDM.Joomla' => 'VDM\\Joomla', - 'libraries/jcb_powers/VDM.Gitea' => 'VDM\\Gitea' - ); + 'libraries/jcb_powers/VDM.Minify' => 'VDM\\Minify', + 'libraries/jcb_powers/VDM.Psr' => 'VDM\\Psr' + ]; // Start the search and load if found $found = false; $found_base_dir = ""; @@ -40,7 +51,7 @@ spl_autoload_register(function ($class) { // check if we found a match if (!$found) { - // no, move to the next registered autoloader + // not found so move to the next registered autoloader return; } // get the relative class name @@ -56,6 +67,7 @@ spl_autoload_register(function ($class) { } }); +use Joomla\CMS\Filesystem\File; use Joomla\CMS\Language\Language; use Joomla\Registry\Registry; use Joomla\String\StringHelper; @@ -63,11 +75,21 @@ use Joomla\Utilities\ArrayHelper; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; -use Joomla\Archive\Archive; -use Joomla\CMS\Filesystem\File; -use Joomla\CMS\Filesystem\Folder; -use Joomla\CMS\Filesystem\Path; use VDM\Joomla\Utilities; +use Joomla\Archive\Archive; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Filesystem\Path; +use VDM\Joomla\Componentbuilder\Compiler\Factory; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\FieldHelper; +use VDM\Joomla\Utilities\Base64Helper; +use VDM\Joomla\FOF\Encrypt\AES; +use VDM\Joomla\Utilities\FormHelper; /** * Componentbuilder component helper. @@ -103,6 +125,11 @@ abstract class ComponentbuilderHelper } + /** + * Just to Add the OPEN AI api to JCB (soon) + * Factory + **/ + /** * Locked Libraries (we can not have these change) **/ @@ -257,7 +284,7 @@ abstract class ComponentbuilderHelper // combine method values $combinded = array(); // add comment if set - if (self::checkString($code->comment)) + if (UtilitiesStringHelper::check($code->comment)) { $comment = array_map('trim', (array) explode(PHP_EOL, base64_decode($code->comment))); $combinded[] = "\t" . implode(PHP_EOL . "\t ", $comment); @@ -266,7 +293,7 @@ abstract class ComponentbuilderHelper if ('method' === $type) { // set the method signature - if (self::checkString($code->arguments)) + if (UtilitiesStringHelper::check($code->arguments)) { $combinded[] = "\t" . $code->visibility . ' function ' . $code->name . '(' . base64_decode($code->arguments) . ')'; } @@ -277,7 +304,7 @@ abstract class ComponentbuilderHelper // set the method code $combinded[] = "\t" . "{"; // add code if set - if (self::checkString(trim($code->code))) + if (UtilitiesStringHelper::check(trim($code->code))) { $combinded[] = base64_decode($code->code); } @@ -289,7 +316,7 @@ abstract class ComponentbuilderHelper } else { - if (self::checkString($code->default)) + if (UtilitiesStringHelper::check($code->default)) { $code->default = base64_decode($code->default); if (is_int($code->default)) @@ -303,12 +330,12 @@ abstract class ComponentbuilderHelper $combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = ' . (float) $code->default . ';'; } elseif (('false' === $code->default || 'true' === $code->default) - || (self::checkString($code->default) && (strpos($code->default, 'array(') !== false || strpos($code->default, '"') !== false))) + || (UtilitiesStringHelper::check($code->default) && (strpos($code->default, 'array(') !== false || strpos($code->default, '"') !== false))) { // set the class property $combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = ' . $code->default . ';'; } - elseif (self::checkString($code->default) && strpos($code->default, '"') === false) + elseif (UtilitiesStringHelper::check($code->default) && strpos($code->default, '"') === false) { // set the class property $combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = "' . $code->default . '";'; @@ -342,11 +369,11 @@ abstract class ComponentbuilderHelper **/ public static function extractBoilerplateClassExtends(&$class, $type) { - if (($strings = self::getAllBetween($class, 'class ', '}')) !== false && self::checkArray($strings)) + if (($strings = GetHelper::allBetween($class, 'class ', '}')) !== false && UtilitiesArrayHelper::check($strings)) { foreach ($strings as $string) { - if (($extends = self::getBetween($string, 'extends ', '{')) !== false && self::checkString($extends)) + if (($extends = GetHelper::between($string, 'extends ', '{')) !== false && UtilitiesStringHelper::check($extends)) { return trim($extends); } @@ -366,10 +393,10 @@ abstract class ComponentbuilderHelper **/ public static function extractBoilerplateClassHeader(&$class, $extends, $type) { - if (($string = self::getBetween($class, "defined('_JEXEC')", 'extends ' . $extends)) !== false && self::checkString($string)) + if (($string = GetHelper::between($class, "defined('_JEXEC')", 'extends ' . $extends)) !== false && UtilitiesStringHelper::check($string)) { $headArray = explode(PHP_EOL, $string); - if (self::checkArray($headArray) && count($headArray) > 3) + if (UtilitiesArrayHelper::check($headArray) && count($headArray) > 3) { // remove first since it still has the [or die;] string in it array_shift($headArray); @@ -391,7 +418,7 @@ abstract class ComponentbuilderHelper } } // make sure we only return if we have values - if (self::checkArray($headArray)) + if (UtilitiesArrayHelper::check($headArray)) { return implode(PHP_EOL, $headArray); } @@ -411,10 +438,10 @@ abstract class ComponentbuilderHelper **/ public static function extractBoilerplateClassComment(&$class, $extends, $type) { - if (($string = self::getBetween($class, "defined('_JEXEC')", 'extends ' . $extends)) !== false && self::checkString($string)) + if (($string = GetHelper::between($class, "defined('_JEXEC')", 'extends ' . $extends)) !== false && UtilitiesStringHelper::check($string)) { $headArray = explode(PHP_EOL, $string); - if (self::checkArray($headArray) && count($headArray) > 3) + if (UtilitiesArrayHelper::check($headArray) && count($headArray) > 3) { $comment = array(); // remove the last since it has the class declaration @@ -435,7 +462,7 @@ abstract class ComponentbuilderHelper } } // make sure we only return if we have values - if (self::checkArray($comment)) + if (UtilitiesArrayHelper::check($comment)) { // set the correct order ksort($comment); @@ -464,7 +491,7 @@ abstract class ComponentbuilderHelper // get the class code, and remove the head $codeArrayTmp = explode('extends ' . $extends, $class); // make sure we have the correct result - if (self::checkArray($codeArrayTmp) && count($codeArrayTmp) == 2) + if (UtilitiesArrayHelper::check($codeArrayTmp) && count($codeArrayTmp) == 2) { // the triggers $triggers = array('public' => 1, 'protected' => 2, 'private' => 3); @@ -489,12 +516,12 @@ abstract class ComponentbuilderHelper // build filter $filters = array('extension_type' => $type); // add more data based on target - if ('method' === $target && self::checkArray($tmp)) + if ('method' === $target && UtilitiesArrayHelper::check($tmp)) { // clean the code self::cleanBoilerplateCode($tmp); // only load if there are values - if (self::checkArray($tmp, true)) + if (UtilitiesArrayHelper::check($tmp, true)) { $_tmp['code'] = implode(PHP_EOL, $tmp); } @@ -503,7 +530,7 @@ abstract class ComponentbuilderHelper $_tmp['code'] = ''; } // load arguments only if set - if (self::checkString($arg)) + if (UtilitiesStringHelper::check($arg)) { $_tmp['arguments'] = $arg; } @@ -511,13 +538,13 @@ abstract class ComponentbuilderHelper elseif ('property' === $target) { // load default only if set - if (self::checkString($arg)) + if (UtilitiesStringHelper::check($arg)) { $_tmp['default'] = $arg; } } // load comment only if set - if (self::checkArray($comment, true)) + if (UtilitiesArrayHelper::check($comment, true)) { $_tmp['comment'] = implode(PHP_EOL, $comment); } @@ -577,9 +604,9 @@ abstract class ComponentbuilderHelper { $target = 'method'; // get the name - $name = trim(self::getBetween($line, 'function ', '(')); + $name = trim(GetHelper::between($line, 'function ', '(')); // get the arguments - $arg = trim(self::getBetween($line, ' ' . $name . '(', ')')); + $arg = trim(GetHelper::between($line, ' ' . $name . '(', ')')); } else { @@ -587,14 +614,14 @@ abstract class ComponentbuilderHelper if (strpos($line, '=') !== false) { // get the name - $name = trim(self::getBetween($line, '$', '=')); + $name = trim(GetHelper::between($line, '$', '=')); // get the default - $arg = trim(self::getBetween($line, '=', ';')); + $arg = trim(GetHelper::between($line, '=', ';')); } else { // get the name - $name = trim(self::getBetween($line, '$', ';')); + $name = trim(GetHelper::between($line, '$', ';')); } } } @@ -636,7 +663,7 @@ abstract class ComponentbuilderHelper $query->where($db->quoteName('a.name') . ' = ' . $db->quote($name)); $query->where($db->quoteName('a.extension_type') . ' = ' . $db->quote($extension_type)); // add more filters - if (self::checkArray($filters)) + if (UtilitiesArrayHelper::check($filters)) { foreach($filters as $where => $value) { @@ -677,7 +704,7 @@ abstract class ComponentbuilderHelper $found = true; } // remove empty lines - elseif (!self::checkString(trim($code[$key]))) + elseif (!UtilitiesStringHelper::check(trim($code[$key]))) { unset($code[$key]); } @@ -706,7 +733,7 @@ abstract class ComponentbuilderHelper $last = 0; } // remove empty lines - elseif (!self::checkString(trim($code[$last]))) + elseif (!UtilitiesStringHelper::check(trim($code[$last]))) { unset($code[$last]); } @@ -744,7 +771,7 @@ abstract class ComponentbuilderHelper // change back to Joomla working directory chdir($joomla); // make sure we have an array - if (!self::checkArray($items)) + if (!UtilitiesArrayHelper::check($items)) { return false; } @@ -756,7 +783,7 @@ abstract class ComponentbuilderHelper self::set('_existing_validation_rules_VDM', json_encode($items)); } // make sure it is no longer json - if (self::checkJson($items)) + if (JsonHelper::check($items)) { $items = json_decode($items, true); } @@ -789,8 +816,8 @@ abstract class ComponentbuilderHelper case 'snippet': $path = self::$snippetPath.$filename; // get the file if available - $content = self::getFileContents($path); - if (self::checkJson($content)) + $content = FileHelper::getContent($path); + if (JsonHelper::check($content)) { $content = json_decode($content, true); } @@ -801,7 +828,7 @@ abstract class ComponentbuilderHelper break; } // see if we have content and all needed details - if (isset($content) && self::checkArray($content) + if (isset($content) && UtilitiesArrayHelper::check($content) && isset($content['contributor_company']) && isset($content['contributor_name']) && isset($content['contributor_email']) @@ -811,12 +838,12 @@ abstract class ComponentbuilderHelper return array('contributor_company' => $content['contributor_company'] ,'contributor_name' => $content['contributor_name'], 'contributor_email' => $content['contributor_email'], 'contributor_website' => $content['contributor_website'], 'origin' => 'file'); } // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } // get the global company details - if (!self::checkArray(self::$localCompany)) + if (!UtilitiesArrayHelper::check(self::$localCompany)) { // Set the person sharing information (default VDM ;) self::$localCompany['company'] = self::$params->get('export_company', 'Vast Development Method'); @@ -855,19 +882,19 @@ abstract class ComponentbuilderHelper // prepare the files $result = $db->loadObject(); // first we load the URLs - if (self::checkJson($result->addurls)) + if (JsonHelper::check($result->addurls)) { // convert to array $result->addurls = json_decode($result->addurls, true); // set urls - if (self::checkArray($result->addurls)) + if (UtilitiesArrayHelper::check($result->addurls)) { // build media folder path - $mediaPath = '/media/' . strtolower( preg_replace('/\s+/', '-', self::safeString($result->name, 'filename', ' ', false))); + $mediaPath = '/media/' . strtolower( preg_replace('/\s+/', '-', UtilitiesStringHelper::safe($result->name, 'filename', ' ', false))); // load the urls foreach($result->addurls as $url) { - if (isset($url['url']) && self::checkString($url['url'])) + if (isset($url['url']) && UtilitiesStringHelper::check($url['url'])) { // set the path if needed if (isset($url['type']) && $url['type'] > 1) @@ -906,12 +933,12 @@ abstract class ComponentbuilderHelper } } // load the local files - if (self::checkJson($result->addfiles)) + if (JsonHelper::check($result->addfiles)) { // convert to array $result->addfiles = json_decode($result->addfiles, true); // set files - if (self::checkArray($result->addfiles)) + if (UtilitiesArrayHelper::check($result->addfiles)) { foreach($result->addfiles as $file) { @@ -935,15 +962,15 @@ abstract class ComponentbuilderHelper } } // load the files in the folder - if (self::checkJson($result->addfolders)) + if (JsonHelper::check($result->addfolders)) { // convert to array $result->addfolders = json_decode($result->addfolders, true); // set folder - if (self::checkArray($result->addfolders)) + if (UtilitiesArrayHelper::check($result->addfolders)) { // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } @@ -960,7 +987,7 @@ abstract class ComponentbuilderHelper $customFolder = '/'.trim($folder['folder'], '/'); if (isset($folder['rename']) && 1 == $folder['rename']) { - if ($_paths = self::getAllFilePaths($customPath.$customFolder)) + if ($_paths = FileHelper::getPaths($customPath.$customFolder)) { $bucket[$_path] = $_paths; } @@ -968,7 +995,7 @@ abstract class ComponentbuilderHelper else { $path = $_path.$customFolder; - if ($_paths = self::getAllFilePaths($customPath.$customFolder)) + if ($_paths = FileHelper::getPaths($customPath.$customFolder)) { $bucket[$path] = $_paths; } @@ -976,7 +1003,7 @@ abstract class ComponentbuilderHelper } } // now load the script - if (self::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { foreach ($bucket as $root => $paths) { @@ -990,7 +1017,7 @@ abstract class ComponentbuilderHelper } } // return files if found - if (self::checkArray($files)) + if (UtilitiesArrayHelper::check($files)) { return $files; } @@ -1015,7 +1042,7 @@ abstract class ComponentbuilderHelper public static function fixPath(&$values, $targets = array()) { // if multiple to gets searched and fixed - if (self::checkArray($values) && self::checkArray($targets)) + if (UtilitiesArrayHelper::check($values) && UtilitiesArrayHelper::check($targets)) { foreach ($targets as $target) { @@ -1026,7 +1053,7 @@ abstract class ComponentbuilderHelper } } // if just a string - elseif (self::checkString($values) && strpos($values, '\\') !== false) + elseif (UtilitiesStringHelper::check($values) && strpos($values, '\\') !== false) { $values = str_replace('\\', '/', $values); } @@ -1071,8 +1098,6 @@ abstract class ComponentbuilderHelper { // import the Joomla librarys jimport('joomla.application.component.modellist'); - // include class to minify js - require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/js.php'; } // load only if smart if ('smart' === $type) @@ -1104,14 +1129,14 @@ abstract class ComponentbuilderHelper public static function convertRepeatable($item, $name) { // continue only if we have an array - if (self::checkArray($item)) + if (UtilitiesArrayHelper::check($item)) { $bucket = array(); foreach ($item as $key => $values) { foreach ($values as $nr => $value) { - if (!isset($bucket[$name . $nr]) || !self::checkArray($bucket[$name . $nr])) + if (!isset($bucket[$name . $nr]) || !UtilitiesArrayHelper::check($bucket[$name . $nr])) { $bucket[$name . $nr] = array(); } @@ -1140,19 +1165,19 @@ abstract class ComponentbuilderHelper if (isset($object->{$key})) { $isJson = false; - if (self::checkJson($object->{$key})) + if (JsonHelper::check($object->{$key})) { $object->{$key} = json_decode($object->{$key}, true); $isJson = true; } // check if this is old values for repeatable fields - if (self::checkArray($object->{$key}) && isset($object->{$key}[$sleutel])) + if (UtilitiesArrayHelper::check($object->{$key}) && isset($object->{$key}[$sleutel])) { // load it back $object->{$key} = self::convertRepeatable($object->{$key}, $key); // add to global updater if ( - self::checkArray($object->{$key}) && self::checkArray($updater) && + UtilitiesArrayHelper::check($object->{$key}) && UtilitiesArrayHelper::check($updater) && ( ( isset($updater['table']) && isset($updater['val']) && isset($updater['key']) ) || ( isset($updater['unique']) && isset($updater['unique'][$key]) && isset($updater['unique'][$key]['table']) && isset($updater['unique'][$key]['val']) && isset($updater['unique'][$key]['key']) ) @@ -1176,7 +1201,7 @@ abstract class ComponentbuilderHelper $_table = $updater['table']; } // continue only if values are valid - if (self::checkString($_table) && self::checkString($_key) && $_value > 0) + if (UtilitiesStringHelper::check($_table) && UtilitiesStringHelper::check($_key) && $_value > 0) { // set target table & item $target = trim($_table) . '.' . trim($_key) . '.' . trim($_value); @@ -1191,12 +1216,12 @@ abstract class ComponentbuilderHelper } } // no set back to json if came in as json - if ($isJson && self::checkArray($object->{$key})) + if ($isJson && UtilitiesArrayHelper::check($object->{$key})) { $object->{$key} = json_encode($object->{$key}); } // remove if not json or array - elseif (!self::checkArray($object->{$key}) && !self::checkJson($object->{$key})) + elseif (!UtilitiesArrayHelper::check($object->{$key}) && !JsonHelper::check($object->{$key})) { unset($object->{$key}); } @@ -1214,7 +1239,7 @@ abstract class ComponentbuilderHelper public static function runGlobalUpdater() { // check if any updates are set to run - if (self::checkArray(self::$globalUpdater)) + if (UtilitiesArrayHelper::check(self::$globalUpdater)) { // get the database object $db = JFactory::getDbo(); @@ -1252,7 +1277,7 @@ abstract class ComponentbuilderHelper if ($item = $model->getItem($id)) { // update values that should change - if (self::checkArray($config)) + if (UtilitiesArrayHelper::check($config)) { foreach($config as $key => $value) { @@ -1396,12 +1421,12 @@ abstract class ComponentbuilderHelper public static function newHash($hash, $name = 'backup', $type = 'hash', $key = '', $fileType = 'txt') { // make sure we have a hash - if (self::checkString($hash)) + if (UtilitiesStringHelper::check($hash)) { // first get the file path - $path_filename = self::getFilePath('path', $name.$type, $fileType, $key, JPATH_COMPONENT_ADMINISTRATOR); + $path_filename = FileHelper::getPath('path', $name.$type, $fileType, $key, JPATH_COMPONENT_ADMINISTRATOR); // set as read if not already set - if ($content = self::getFileContents($path_filename, false)) + if ($content = FileHelper::getContent($path_filename, false)) { if ($hash == $content) { @@ -1409,7 +1434,7 @@ abstract class ComponentbuilderHelper } } // set the hash - return self::writeFile($path_filename, $hash); + return FileHelper::write($path_filename, $hash); } return false; } @@ -1448,13 +1473,13 @@ abstract class ComponentbuilderHelper $ownerDetails .= ''; // provide some details to how the user can get a key - if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && self::checkString($info['getKeyFrom']['buy_link'])) + if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && UtilitiesStringHelper::check($info['getKeyFrom']['buy_link'])) { $ownerDetails .= '
'; $ownerDetails .= JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="'.$info['getKeyFrom']['buy_link'].'" target="_blank" title="get a key from '.$owner.'"', $owner); } // add more custom links - elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && self::checkArray($info['getKeyFrom']['buy_links'])) + elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && UtilitiesArrayHelper::check($info['getKeyFrom']['buy_links'])) { $buttons = array(); foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link) @@ -1479,7 +1504,7 @@ abstract class ComponentbuilderHelper public static function getPackageOwnerValue($key, &$info) { $source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : false); - if ($source && self::checkString($info[$source][$key])) + if ($source && UtilitiesStringHelper::check($info[$source][$key])) { return $info[$source][$key]; } @@ -1528,7 +1553,7 @@ abstract class ComponentbuilderHelper { // check if these components need a key $needKey = self::getPackageComponentsKeyStatus($info); - if (isset($info['name']) && self::checkArray($info['name'])) + if (isset($info['name']) && UtilitiesArrayHelper::check($info['name'])) { $cAmount = count((array) $info['name']); $class2 = ($cAmount == 1) ? 'span12' : 'span6'; @@ -1572,7 +1597,7 @@ abstract class ComponentbuilderHelper } $display[] = ''; // if we have a source link we add it - if (isset($info['joomla_source_link']) && self::checkArray($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && self::checkString($info['joomla_source_link'][$key])) + if (isset($info['joomla_source_link']) && UtilitiesArrayHelper::check($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && UtilitiesStringHelper::check($info['joomla_source_link'][$key])) { $display[] = 'source code'; } @@ -1611,9 +1636,9 @@ abstract class ComponentbuilderHelper $unique = ''; if (1 == $type) { - $unique = self::safeString($tableName) . '_'; + $unique = UtilitiesStringHelper::safe($tableName) . '_'; } - if (self::checkArray($columns)) + if (UtilitiesArrayHelper::check($columns)) { // build the return string $tableColumns = array(); @@ -1651,10 +1676,10 @@ abstract class ComponentbuilderHelper $tableName = ''; if (1 == $type) { - $tableName = self::safeString($result->name_single) . '_'; + $tableName = UtilitiesStringHelper::safe($result->name_single) . '_'; } $addfields = json_decode($result->addfields, true); - if (self::checkArray($addfields)) + if (UtilitiesArrayHelper::check($addfields)) { // reset all buckets $field = array(); @@ -1663,7 +1688,7 @@ abstract class ComponentbuilderHelper foreach ($addfields as $nr => $value) { $tmp = self::getFieldNameAndType((int) $value['field']); - if (self::checkArray($tmp)) + if (UtilitiesArrayHelper::check($tmp)) { $field[$nr] = $tmp; } @@ -1684,7 +1709,7 @@ abstract class ComponentbuilderHelper // load data foreach ($field as $n => $f) { - if (self::checkArray($f)) + if (UtilitiesArrayHelper::check($f)) { $fields[] = $as . "." . $f['name'] . " AS " . $tableName . $f['name']; } @@ -1753,11 +1778,11 @@ abstract class ComponentbuilderHelper } else { - $name = self::safeFieldName(self::getBetween($field->xml,'name="','"')); + $name = self::safeFieldName(GetHelper::between($field->xml,'name="','"')); } // use field core name only if not found in xml - if (!self::checkString($name)) + if (!UtilitiesStringHelper::check($name)) { $name = self::safeFieldName($field->name); } @@ -1887,159 +1912,158 @@ abstract class ComponentbuilderHelper } return false; } - /** * The array of dynamic content - * - * @var array + * + * @var array */ - protected static $dynamicContent = array( + protected static array $dynamicContent = [ // The banners by size (width - height) - 'banner' => array( - '728-90' => array( - array( - 'url' => 'https://cdn.joomla.org/volunteers/joomla-heart-wide.gif', + 'banner' => [ + '728-90' => [ + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/banner/joomla-heart-wide.gif', 'hash' => 'f857e3a38facaeac9eba3cffa912b620', - 'html' => 'Joomla! Volunteers Portal'), - array( - 'url' => 'https://magazine.joomla.org/images/banners/JCM_2010_728x90.png', - 'hash' => '4083c66f996279fd5a76adffc3a7d194', - 'html' => 'Joomla! Community Magazine | Because community matters...'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/banners/tlwebdesign_jcb_sponsor_728_90.png', + 'html' => 'Joomla! Volunteers Portal'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/banner/JCM_2010_120x600.png', + 'hash' => '5389cf3be8569cb3f6793e8bd4013d19', + 'html' => 'Joomla! Community Magazine | Because community matters...'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/banner/tlwebdesign_jcb_sponsor_728_90.png', 'hash' => 'd19be1f9f5b2049ff901096aafc246be', - 'html' => 'tlwebdesign a JCB sponsor | Because community matters...'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/banners/vdm_jcb_sponsor_728_90.gif', + 'html' => 'tlwebdesign a JCB sponsor | Because community matters...'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/banner/vdm_jcb_sponsor_728_90.gif', 'hash' => '84478dfa0cd880395815e0ee026812a4', - 'html' => 'VDM a JCB sponsor | Because community matters...'), - array( + 'html' => 'VDM a JCB sponsor | Because community matters...'], + [ 'url' => 'https://cms-experts.org/images/banners/agerix/agerix-loves-jcb-728-90.gif', 'hash' => 'b24c0726aa809cdcc04bcffe7e1e1529', - 'html' => 'Agerix a JCB sponsor | Because community matters...') - ), - '160-600' => array( - array( - 'url' => 'https://cdn.joomla.org/volunteers/joomla-heart-tall.gif', + 'html' => 'Agerix a JCB sponsor | Because community matters...'] + ], + '160-600' => [ + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/banner/joomla-heart-tall.gif', 'hash' => '9a75e4929b86c318128b53cf78251678', - 'html' => 'Joomla! Volunteers Portal'), - array( - 'url' => 'https://magazine.joomla.org/images/banners/JCM_2010_120x600.png', + 'html' => 'Joomla! Volunteers Portal'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/banner/JCM_2010_120x600.png', 'hash' => '5389cf3be8569cb3f6793e8bd4013d19', - 'html' => 'Joomla! Community Magazine | Because community matters...') - ) - ), + 'html' => 'Joomla! Community Magazine | Because community matters...'] + ] + ], // The build-gif by size (width - height) - 'builder-gif' => array( + 'builder-gif' => [ // original gif ;) - '480-272' => array( - array( + '480-272' => [ + [ 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/original.gif', 'hash' => '676e37a949add8f4573381195cd1061c', 'html' => '' - ) - ), + ] + ], // new gif artwork since 2021 - '480-540' => array( - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/1.gif', + '480-540' => [ + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/1.gif', 'hash' => 'ce6e36456fa794ba95d981547b2f54f8', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/2.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/2.gif', 'hash' => '0a54dbc393359747e33db90cabb1e2d7', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/3.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/3.gif', 'hash' => '4e5498713ff69a64a0a79dbf620372a3', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/4.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/4.gif', 'hash' => '3554ffab2a6df95a116fd9f0db63925c', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/5.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/5.gif', 'hash' => '08f0cdf188593eca65c6dafd7af27ef9', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/6.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/6.gif', 'hash' => '103b46a7ac3fcb974e25d06f417a4e87', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/7.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/7.gif', 'hash' => 'ffa8547099b7286f89ab7ff5a140dd90', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/8.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/8.gif', 'hash' => '316df780f9e4ce81200a65d3c4303c41', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/9.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/9.gif', 'hash' => '9ab6ba78b6e63a285fdef2ff5e447c93', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/10.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/10.gif', 'hash' => 'cd9abaa1cb95f51a70916da6b70614f2', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/11.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/11.gif', 'hash' => 'cfe53095b5249618e2348223b89262b9', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/12.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/12.gif', 'hash' => '15a6690647d5160d67c80ce4dd1f5602', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/13.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/13.gif', 'hash' => '2f77562e92c8a3b7c47664c98f551fe8', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/14.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/14.gif', 'hash' => '46db15517ef5bd063be85134e1cc575d', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/15.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/15.gif', 'hash' => 'e6c96eff157ea648ceb1583f2cc22544', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/16.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/16.gif', 'hash' => '76010b7d1f99952eb9645df660467ae8', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/17.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/17.gif', 'hash' => '021219ddd72d8fcfc7f80bd4a874d651', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/18.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/18.gif', 'hash' => '383af3179d4ae27301c1292e630d7155', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/19.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/19.gif', 'hash' => '8537e6d7be93447241b521f851e8a61d', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/20.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/20.gif', 'hash' => '10d96f70e3d43086a925b00a7dc0022e', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/21.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/21.gif', 'hash' => '161de9865b171b44039353b8d50491d3', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/22.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/22.gif', 'hash' => '6a2354e43eb97d278d74bb2c12890988', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/23.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/23.gif', 'hash' => '2cb6e2f9562a8dc8eef6d5d8d1a84f5e', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'), - array( - 'url' => 'https://www.joomlacomponentbuilder.com/images/builder/24.gif', + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'], + [ + 'url' => 'https://git.vdm.dev/joomla/jcb-external/raw/branch/master/src/images/builder/24.gif', 'hash' => '745b3fb5e16515689132432bf02ab1b4', - 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
') - ) - ) - ); + 'html' => '
Animation produced with 3D Particle Explorations by Jack Rugile.
'] + ] + ] + ]; /** * get the dynamic content array size @@ -2050,10 +2074,10 @@ abstract class ComponentbuilderHelper * @return int on success number of items in array type,size * */ - public static function getDynamicContentSize($type, $size) + public static function getDynamicContentSize(string $type, string $size): int { if (isset(self::$dynamicContent[$type]) && isset(self::$dynamicContent[$type][$size]) - && ($nr = self::checkArray(self::$dynamicContent[$type][$size]))) + && ($nr = UtilitiesArrayHelper::check(self::$dynamicContent[$type][$size]))) { return $nr; } @@ -2063,16 +2087,16 @@ abstract class ComponentbuilderHelper /** * get the dynamic content * - * @param string $type The type of content - * @param string $size The size of the content - * @param mix $default The default to return - * @param int $try Retry tracker (when bigger then array size it stops) - * @param mix $getter The specific getter number (not zero based) + * @param string $type The type of content + * @param string $size The size of the content + * @param mixed $default The default to return + * @param int $try Retry tracker (when bigger then array size it stops) + * @param mixed $getter The specific getter number (not zero based) * * @return string on success html string * */ - public static function getDynamicContent($type, $size, $default = '', $try = 1, $getter = null) + public static function getDynamicContent(string $type, string $size, $default = '', int $try = 1, $getter = null) { if (($nr = self::getDynamicContentSize($type, $size)) !== 0) { @@ -2099,12 +2123,12 @@ abstract class ComponentbuilderHelper // set the local path (in admin area so when the component uninstall these images get removed as well) $path = JPATH_ROOT . "/administrator/components/com_componentbuilder/assets/images/$type/$file_name"; // check if file exist or if it changed - if (($image_data = self::getFileContents($path, false)) === false || + if (($image_data = FileHelper::getContent($path, false)) === false || md5($image_data) !== $target['hash']) { // since the file does not exist or has changed (so we have a new hash) // therefore we download it to validate - if (($image_data = self::getFileContents($target['url'], false)) !== false && + if (($image_data = FileHelper::getContent($target['url'], false)) !== false && md5($image_data) === $target['hash']) { // create the JCB type path if it does not exist @@ -2113,7 +2137,7 @@ abstract class ComponentbuilderHelper Folder::create(JPATH_ROOT . "/administrator/components/com_componentbuilder/assets/images/$type"); } // only set the image if the data match the hash - self::writeFile($path, $image_data); + FileHelper::write($path, $image_data); } // we retry array size times (unless specific getter is used) elseif ($try <= $nr && !$getter) @@ -2127,7 +2151,8 @@ abstract class ComponentbuilderHelper } } return $default; - } + } + /** * Tab/spacer bucket (to speed-up the build) @@ -2179,7 +2204,7 @@ abstract class ComponentbuilderHelper **/ public static function loadSession() { - if (!isset(self::$session) || !self::checkObject(self::$session)) + if (!isset(self::$session) || !ObjectHelper::check(self::$session)) { self::$session = JFactory::getSession(); } @@ -2192,7 +2217,7 @@ abstract class ComponentbuilderHelper **/ public static function set($key, $value) { - if (!isset(self::$session) || !self::checkObject(self::$session)) + if (!isset(self::$session) || !ObjectHelper::check(self::$session)) { self::$session = JFactory::getSession(); } @@ -2207,7 +2232,7 @@ abstract class ComponentbuilderHelper **/ public static function get($key, $default = null) { - if (!isset(self::$session) || !self::checkObject(self::$session)) + if (!isset(self::$session) || !ObjectHelper::check(self::$session)) { self::$session = JFactory::getSession(); } @@ -2275,10 +2300,10 @@ abstract class ComponentbuilderHelper $field['values_description'] .= '
'; foreach ($properties as $property) { - $example = (isset($property['example']) && self::checkString($property['example'])) ? $property['example'] : ''; + $example = (isset($property['example']) && UtilitiesStringHelper::check($property['example'])) ? $property['example'] : ''; $field['values_description'] .= ''; // check if we should load the value - $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); + $value = FieldHelper::getValue($xml, $property['name'], $confirmation); // check if this is a php field $addPHP = false; if (strpos($property['name'], 'type_php') !== false) @@ -2299,7 +2324,7 @@ abstract class ComponentbuilderHelper } } // was the settings for the property passed - if(self::checkArray($settings) && isset($settings[$property['name']])) + if(UtilitiesArrayHelper::check($settings) && isset($settings[$property['name']])) { // add the xml values $field['values'] .= PHP_EOL . "\t" . $property['name'] . '="'. $settings[$property['name']] . '" '; @@ -2338,7 +2363,7 @@ abstract class ComponentbuilderHelper $nr++; } // check if all php is loaded using the tracker - if (self::checkString($xml) && isset($phpTracker) && self::checkArray($phpTracker)) + if (UtilitiesStringHelper::check($xml) && isset($phpTracker) && UtilitiesArrayHelper::check($phpTracker)) { foreach ($phpTracker as $phpKey => $start) { @@ -2348,7 +2373,7 @@ abstract class ComponentbuilderHelper foreach(range(2, 30) as $t_nr) { $get_ = $phpKey . '_' . $t_nr; - if (!isset($field['php'][$phpKey]['value'][$t_nr]) && ($value = self::getValueFromXMLstring($xml, $get_, $confirmation)) !== $confirmation) + if (!isset($field['php'][$phpKey]['value'][$t_nr]) && ($value = FieldHelper::getValue($xml, $get_, $confirmation)) !== $confirmation) { $field['php'][$phpKey]['value'][$t_nr] = $value; } @@ -2378,18 +2403,19 @@ abstract class ComponentbuilderHelper return false; } + /** + * Get a field value from the XML stored string + * + * @param string $xml The xml string of the field + * @param string $get The value key to get from the string + * @param string $confirmation The value to confirm found value + * + * @return string The field value from xml + * @deprecated 3.3 Use FieldHelper::getValue($xml, $get, $confirmation); + */ public static function getValueFromXMLstring(&$xml, &$get, $confirmation = '') { - if (self::checkString($xml)) - { - // if we have a PHP value, we must base64 decode it - if (strpos($get, 'type_php') !== false) - { - return self::openValidBase64(self::getBetween($xml, $get.'="', '"', $confirmation)); - } - return self::getBetween($xml, $get . '="', '"', $confirmation); - } - return $confirmation; + return FieldHelper::getValue($xml, $get, $confirmation); } @@ -2438,12 +2464,12 @@ abstract class ComponentbuilderHelper // add if no objection is found $add = true; // check if we have exclude - if (self::checkArray($exclude) && in_array($property->name, $exclude)) + if (UtilitiesArrayHelper::check($exclude) && in_array($property->name, $exclude)) { continue; } // check if we have filter - if (self::checkArray($filter)) + if (UtilitiesArrayHelper::check($filter)) { foreach($filter as $key => $val) { @@ -2490,76 +2516,79 @@ abstract class ComponentbuilderHelper /** * Remove folders with files * - * @param string $dir The path to folder to remove - * @param boolean $ignore The folders and files to ignore and not remove + * @param string $path The path to folder to remove + * @param array|null $ignore The folders and files to ignore and not remove * - * @return boolean True in all is removed - * + * @return bool True if all are removed */ - public static function removeFolder($dir, $ignore = false) + public static function removeFolder(string $path, ?array $ignore = null): bool { - if (Folder::exists($dir)) + if (!Folder::exists($path)) { - $it = new RecursiveDirectoryIterator($dir); - $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); - // remove ending / - $dir = rtrim($dir, '/'); - // now loop the files & folders - foreach ($it as $file) - { - if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; - // set file dir - $file_dir = $file->getPathname(); - // check if this is a dir or a file - if ($file->isDir()) - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file_dir, $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - Folder::delete($file_dir); - } - else - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file_dir, $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - File::delete($file_dir); - } - } - // delete the root folder if not ignore found - if (!self::checkArray($ignore)) - { - return Folder::delete($dir); - } - return true; + return false; } - return false; + + $it = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); + $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); + + // Prepare a base path without trailing slash for comparison + $basePath = rtrim($path, '/'); + + foreach ($files as $fileinfo) + { + $filePath = $fileinfo->getRealPath(); + + if (self::removeFolderShouldIgnore($basePath, $filePath, $ignore)) + { + continue; + } + + if ($fileinfo->isDir()) + { + Folder::delete($filePath); + } + else + { + File::delete($filePath); + } + } + + // Delete the root folder if ignore not set + if (!UtilitiesArrayHelper::check($ignore)) + { + return Folder::delete($path); + } + + return true; } + /** + * Check if the current path should be ignored. + * + * @param string $basePath The base directory path + * @param string $filePath The current file or directory path + * @param array|null $ignore List of items to ignore + * + * @return boolean True if the path should be ignored + * @since 3.2.0 + */ + protected static function removeFolderShouldIgnore(string $basePath, string $filePath, ?array $ignore = null): bool + { + if (!$ignore || !UtilitiesArrayHelper::check($ignore)) + { + return false; + } + + foreach ($ignore as $item) + { + if (strpos($filePath, $basePath . '/' . $item) !== false) + { + return true; + } + } + + return false; + } /** * The github access token @@ -2606,12 +2635,12 @@ abstract class ComponentbuilderHelper if (self::urlExists($_url)) { // get the data from github - if (($repoData = self::getFileContents($_url)) !== false && self::checkJson($repoData)) + if (($repoData = FileHelper::getContent($_url)) !== false && JsonHelper::check($repoData)) { $github_returned = json_decode($repoData); - if (self::checkString($target) && - ( (self::checkObject($github_returned) && isset($github_returned->{$target}) && self::checkArray($github_returned->{$target})) || - (self::checkArray($github_returned) && isset($github_returned[$target]) && self::checkArray($github_returned[$target])) )) + if (UtilitiesStringHelper::check($target) && + ( (ObjectHelper::check($github_returned) && isset($github_returned->{$target}) && UtilitiesArrayHelper::check($github_returned->{$target})) || + (UtilitiesArrayHelper::check($github_returned) && isset($github_returned[$target]) && UtilitiesArrayHelper::check($github_returned[$target])) )) { if ('nomemory' !== $type) { @@ -2619,7 +2648,7 @@ abstract class ComponentbuilderHelper self::set($type, $repoData); } } - elseif (!self::checkString($target) && (self::checkArray($github_returned) || (self::checkObject($github_returned) && !isset($github_returned->message)))) + elseif (!UtilitiesStringHelper::check($target) && (UtilitiesArrayHelper::check($github_returned) || (ObjectHelper::check($github_returned) && !isset($github_returned->message)))) { if ('nomemory' !== $type) { @@ -2630,7 +2659,7 @@ abstract class ComponentbuilderHelper // check if we have error message from github elseif (($errorMessage = self::githubErrorHandeler(array('error' => null), $github_returned, $type)) !== false) { - if (isset($errorMessage['error']) && self::checkString($errorMessage['error'])) + if (isset($errorMessage['error']) && UtilitiesStringHelper::check($errorMessage['error'])) { // set the error in the application JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); @@ -2639,7 +2668,7 @@ abstract class ComponentbuilderHelper } return false; } - elseif (self::checkString($target)) + elseif (UtilitiesStringHelper::check($target)) { // setup error string $error = JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DID_NOT_RETURN_S_DATA', $url, $target); @@ -2698,7 +2727,7 @@ abstract class ComponentbuilderHelper } } // check if we could find packages - if (isset($repoData) && self::checkJson($repoData)) + if (isset($repoData) && JsonHelper::check($repoData)) { if ('object' === $return_type) { @@ -2721,12 +2750,12 @@ abstract class ComponentbuilderHelper */ protected static function githubErrorHandeler($message, &$github, $type) { - if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) + if (ObjectHelper::check($github) && isset($github->message) && UtilitiesStringHelper::check($github->message)) { // set the message $errorMessage = $github->message; // add the documentation URL - if (isset($github->documentation_url) && self::checkString($github->documentation_url)) + if (isset($github->documentation_url) && UtilitiesStringHelper::check($github->documentation_url)) { $errorMessage = $errorMessage . '
' . $github->documentation_url; } @@ -2760,17 +2789,17 @@ abstract class ComponentbuilderHelper if (strpos($url, 'access_token=') !== false) { // make sure the token is loaded - if (!self::checkString(self::$gitHubAccessToken)) + if (!UtilitiesStringHelper::check(self::$gitHubAccessToken)) { // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } self::$gitHubAccessToken = self::$params->get('github_access_token', null); } // make sure the token is loaded at this point - if (self::checkString(self::$gitHubAccessToken)) + if (UtilitiesStringHelper::check(self::$gitHubAccessToken)) { $url .= '&access_token=' . self::$gitHubAccessToken; } @@ -3517,6 +3546,7 @@ abstract class ComponentbuilderHelper /** * Field Grouping https://docs.joomla.org/Form_field + * @deprecated 3.3 **/ protected static $fieldGroups = array( 'default' => array( @@ -3550,6 +3580,9 @@ abstract class ComponentbuilderHelper ), 'special' => array( 'contentlanguage', 'moduleposition', 'plugin', 'repeatable', 'subform' + ), + 'search' => array( + 'editor', 'email', 'tel', 'text', 'textarea', 'url', 'subform' ) ); @@ -3560,83 +3593,44 @@ abstract class ComponentbuilderHelper * @param boolean $option The field grouping * * @return boolean if the field was found + * @deprecated 3.3 Use Factory::_('Field.Groups')->check($type, $option); */ public static function fieldCheck($type, $option = 'default') { - // now check - if (isset(self::$fieldGroups[$option]) && in_array($type, self::$fieldGroups[$option])) - { - return true; - } - return false; + return Factory::_('Field.Groups')->check($type, $option); } /** * get the field types id -> name of a group or groups * * @return array ids of the spacer field types + * @deprecated 3.3 Use Factory::_('Field.Groups')->types($groups); */ public static function getFieldTypesByGroup($groups = array()) { - // make sure we have a group - if (($ids = self::getFieldTypesIdsByGroup($groups)) !== false) - { - // get the database object to use quote - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array('id', 'name'))); - $query->from($db->quoteName('#__componentbuilder_fieldtype')); - $query->where($db->quoteName('published') . ' = 1'); - $query->where($db->quoteName('id') . ' IN (' . implode(',',$ids) . ')'); - // Reset the query using our newly populated query object. - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadAssocList('id', 'name'); - } - } - return false; + return Factory::_('Field.Groups')->types($groups); } /** * get the field types IDs of a group or groups * * @return array ids of the spacer field types + * @deprecated 3.3 Use Factory::_('Field.Groups')->typesIds($groups); */ public static function getFieldTypesIdsByGroup($groups = array()) { - // make sure we have a group - if (self::checkArray($groups)) - { - $merge_groups = array(); - foreach ($groups as $group) - { - if (isset(self::$fieldGroups[$group])) - { - $merge_groups[] = self::$fieldGroups[$group]; - } - } - // make sure we have these types of groups - if (self::checkArray($merge_groups)) - { - // get the database object to use quote - $db = JFactory::getDbo(); - return self::getVars('fieldtype', (array) array_map(function($name) use($db) { return $db->quote(ucfirst($name)); }, self::mergeArrays($merge_groups)), 'name', 'id'); - } - } - return false; + return Factory::_('Field.Groups')->typesIds($groups); } /** * get the spacer IDs * * @return array ids of the spacer field types + * @deprecated 3.3 Use Factory::_('Field.Groups')->spacerIds(); */ public static function getSpacerIds() { - return self::getFieldTypesIdsByGroup($groups = array('spacer')); + return Factory::_('Field.Groups')->spacerIds(); } @@ -3648,60 +3642,41 @@ abstract class ComponentbuilderHelper * @param string $default The default switch * * @return string The opened string - * + * @deprecated 3.3 Use Base64Helper::open($data, $key, $default); */ public static function openValidBase64($data, $key = '__.o0=base64=Oo.__', $default = 'string') { - // check that we have a string - if (self::checkString($data)) - { - // check if we have a key - if (self::checkString($key)) - { - if (strpos($data, $key) !== false) - { - return base64_decode(str_replace($key, '', $data)); - } - } - // fallback to this, not perfect method - if (base64_encode(base64_decode($data, true)) === $data) - { - return base64_decode($data); - } - } - // check if we should just return the string - if ('string' === $default) - { - return $data; - } - return $default; + return Base64Helper::open($data, $key, $default); } - - /** - * prepare base64 string for url - **/ - public static function base64_urlencode($string, $encode = false) - { - if ($encode) - { - $string = base64_encode($string); - } - return str_replace(array('+', '/'), array('-', '_'), $string); - } - - /** - * prepare base64 string form url - **/ - public static function base64_urldecode($string, $decode = false) - { - $string = str_replace(array('-', '_'), array('+', '/'), $string); - if ($decode) - { - $string = base64_decode($string); - } - return $string; - } + /** + * prepare base64 string for url + * + * @deprecate Use urlencode(); + */ + public static function base64_urlencode($string, $encode = false) + { + if ($encode) + { + $string = base64_encode($string); + } + return str_replace(array('+', '/'), array('-', '_'), $string); + } + + /** + * prepare base64 string form url + * + * @deprecate + */ + public static function base64_urldecode($string, $decode = false) + { + $string = str_replace(array('-', '_'), array('+', '/'), $string); + if ($decode) + { + $string = base64_decode($string); + } + return $string; + } /** @@ -3718,12 +3693,12 @@ abstract class ComponentbuilderHelper public static function getFolderPath($type = 'path', $target = 'folderpath', $default = '', $createIfNotSet = true) { // make sure to always have a string/path - if(!self::checkString($default)) + if(!UtilitiesStringHelper::check($default)) { $default = JPATH_SITE . '/images/'; } // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } @@ -3785,7 +3760,7 @@ abstract class ComponentbuilderHelper $key = $type; } // check if it was already set - if (isset(self::$CRYPT[$key]) && self::checkObject(self::$CRYPT[$key])) + if (isset(self::$CRYPT[$key]) && ObjectHelper::check(self::$CRYPT[$key])) { return self::$CRYPT[$key]; } @@ -3806,31 +3781,31 @@ abstract class ComponentbuilderHelper switch ($mode) { case 'CTR': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_CTR); + self::$CRYPT[$key] = new $CLASS('ctr'); break; case 'ECB': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_ECB); + self::$CRYPT[$key] = new $CLASS('ecb'); break; case 'CBC': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_CBC); + self::$CRYPT[$key] = new $CLASS('cbc'); break; case 'CBC3': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_CBC3); + self::$CRYPT[$key] = new $CLASS('cbc3'); break; case 'CFB': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_CFB); + self::$CRYPT[$key] = new $CLASS('cfb'); break; case 'CFB8': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_CFB8); + self::$CRYPT[$key] = new $CLASS('cfb8'); break; case 'OFB': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_OFB); + self::$CRYPT[$key] = new $CLASS('ofb'); break; case 'GCM': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_GCM); + self::$CRYPT[$key] = new $CLASS('gcm'); break; case 'STREAM': - self::$CRYPT[$key] = new $CLASS($CLASS::MODE_STREAM); + self::$CRYPT[$key] = new $CLASS('stream'); break; default: // No valid mode has been specified @@ -3841,7 +3816,7 @@ abstract class ComponentbuilderHelper } else { - // set the + // set the default self::$CRYPT[$key] = new $CLASS(); } // return the object @@ -3882,7 +3857,7 @@ abstract class ComponentbuilderHelper // get the remote path $remote_path = '/' . trim($server->jcb_remote_server_path[(int) $serverID], '/') . '/' . $fileName; // now move the file - if (!$server->put($remote_path, self::getFileContents($localPath, null))) + if (!$server->put($remote_path, FileHelper::getContent($localPath, null))) { JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_BSB_FILE_COULD_NOT_BE_MOVED_TO_BSB_PATH_ON_BSB_SERVER', $fileName, $server->jcb_remote_server_path[(int) $serverID], $server->jcb_remote_server_name[(int) $serverID]), 'Error'); return false; @@ -3946,7 +3921,7 @@ abstract class ComponentbuilderHelper if ($server = self::getServerDetails($serverID, 2, $permission)) { // check if it was already set - if (!isset(self::$sftp[$server->cache]) || !self::checkObject(self::$sftp[$server->cache])) + if (!isset(self::$sftp[$server->cache]) || !ObjectHelper::check(self::$sftp[$server->cache])) { // make sure we have the composer classes loaded self::composerAutoload('phpseclib'); @@ -3975,15 +3950,15 @@ abstract class ComponentbuilderHelper } break; case 2: // private key file - if (self::checkObject(self::crypt('RSA'))) + if (ObjectHelper::check(self::crypt('RSA'))) { // check if we have a passprase - if (self::checkString($server->secret)) + if (UtilitiesStringHelper::check($server->secret)) { self::crypt('RSA')->setPassword($server->secret); } // now load the key file - if (!self::crypt('RSA')->loadKey(self::getFileContents($server->private, null))) + if (!self::crypt('RSA')->loadKey(FileHelper::getContent($server->private, null))) { JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER', $server->name), 'Error'); unset(self::$sftp[$server->cache]); @@ -3999,15 +3974,15 @@ abstract class ComponentbuilderHelper } break; case 3: // both password and private key file - if (self::checkObject(self::crypt('RSA'))) + if (ObjectHelper::check(self::crypt('RSA'))) { // check if we have a passphrase - if (self::checkString($server->secret)) + if (UtilitiesStringHelper::check($server->secret)) { self::crypt('RSA')->setPassword($server->secret); } // now load the key file - if (!self::crypt('RSA')->loadKey(self::getFileContents($server->private, null))) + if (!self::crypt('RSA')->loadKey(FileHelper::getContent($server->private, null))) { JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER', $server->name), 'Error'); unset(self::$sftp[$server->cache]); @@ -4023,10 +3998,10 @@ abstract class ComponentbuilderHelper } break; case 4: // private key field - if (self::checkObject(self::crypt('RSA'))) + if (ObjectHelper::check(self::crypt('RSA'))) { // check if we have a passprase - if (self::checkString($server->secret)) + if (UtilitiesStringHelper::check($server->secret)) { self::crypt('RSA')->setPassword($server->secret); } @@ -4047,10 +4022,10 @@ abstract class ComponentbuilderHelper } break; case 5: // both password and private key field - if (self::checkObject(self::crypt('RSA'))) + if (ObjectHelper::check(self::crypt('RSA'))) { // check if we have a passphrase - if (self::checkString($server->secret)) + if (UtilitiesStringHelper::check($server->secret)) { self::crypt('RSA')->setPassword($server->secret); } @@ -4073,7 +4048,7 @@ abstract class ComponentbuilderHelper } } // only continue if object is set - if (isset(self::$sftp[$server->cache]) && self::checkObject(self::$sftp[$server->cache])) + if (isset(self::$sftp[$server->cache]) && ObjectHelper::check(self::$sftp[$server->cache])) { // set the unique buckets if (!isset(self::$sftp[$server->cache]->jcb_remote_server_name)) @@ -4083,7 +4058,7 @@ abstract class ComponentbuilderHelper } // always set the name and remote server path self::$sftp[$server->cache]->jcb_remote_server_name[$serverID] = $server->name; - self::$sftp[$server->cache]->jcb_remote_server_path[$serverID] = (self::checkString($server->path) && $server->path !== '/') ? $server->path : ''; + self::$sftp[$server->cache]->jcb_remote_server_path[$serverID] = (UtilitiesStringHelper::check($server->path) && $server->path !== '/') ? $server->path : ''; // return the sftp object return self::$sftp[$server->cache]; } @@ -4123,12 +4098,12 @@ abstract class ComponentbuilderHelper } } // make sure we have a string and it is not default or empty - if (self::checkString($server->signature)) + if (UtilitiesStringHelper::check($server->signature)) { // turn into variables parse_str($server->signature); // because of this I am using strange variable naming to avoid any collisions. // set options - if (isset($options) && self::checkArray($options)) + if (isset($options) && UtilitiesArrayHelper::check($options)) { foreach ($options as $o__p0t1on => $vAln3) { @@ -4197,7 +4172,7 @@ abstract class ComponentbuilderHelper if (!JFactory::getUser()->authorise($permission, 'com_componentbuilder')) { // set message to inform the user that permission was denied - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO', self::safeString($permission, 'w')), 'Error'); + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO', UtilitiesStringHelper::safe($permission, 'w')), 'Error'); return false; } // now insure we have correct values @@ -4233,7 +4208,7 @@ abstract class ComponentbuilderHelper // Get the basic encryption. $basickey = self::getCryptKey('basic', 'Th1sMnsTbL0ck@d'); // Get the encryption object. - $basic = new FOFEncryptAes($basickey, 128); + $basic = new AES($basickey, 128); // start cache keys $keys = array(); // unlock the needed fields @@ -4252,7 +4227,7 @@ abstract class ComponentbuilderHelper } } // check if cache keys were found - if (self::checkArray($keys)) + if (UtilitiesArrayHelper::check($keys)) { // now set cache $server->cache = md5(implode('', $keys)); @@ -4320,7 +4295,7 @@ abstract class ComponentbuilderHelper public static function lock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true) { // get the global settings - if (!$key || !self::checkString($key)) + if (!$key || !UtilitiesStringHelper::check($key)) { // set temp timer $timer = 2; @@ -4344,12 +4319,12 @@ abstract class ComponentbuilderHelper $key .= self::salt($salt, $dynamic); } // get the locker settings - if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key])) + if (!isset(self::$locker[$key]) || !ObjectHelper::check(self::$locker[$key])) { - self::$locker[$key] = new FOFEncryptAes($key, 128); + self::$locker[$key] = new AES($key, 128); } // convert array or object to string - if (self::checkArray($string) || self::checkObject($string)) + if (UtilitiesArrayHelper::check($string) || ObjectHelper::check($string)) { $string = serialize($string); } @@ -4376,7 +4351,7 @@ abstract class ComponentbuilderHelper public static function unlock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true) { // get the global settings - if (!$key || !self::checkString($key)) + if (!$key || !UtilitiesStringHelper::check($key)) { // set temp timer $timer = 2; @@ -4400,9 +4375,9 @@ abstract class ComponentbuilderHelper $key .= self::salt($salt, $dynamic); } // get the locker settings - if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key])) + if (!isset(self::$locker[$key]) || !ObjectHelper::check(self::$locker[$key])) { - self::$locker[$key] = new FOFEncryptAes($key, 128); + self::$locker[$key] = new AES($key, 128); } // make sure we have real base64 if ($urlencode && method_exists(get_called_class(), "base64_urldecode")) @@ -4436,7 +4411,7 @@ abstract class ComponentbuilderHelper // get dynamic replacement salt $dynamic = self::getDynamicSalt($dynamic); // get the key timer - if (!self::checkObject(self::$keytimer)) + if (!ObjectHelper::check(self::$keytimer)) { // load the date time object self::$keytimer = new DateTime; @@ -4466,7 +4441,7 @@ abstract class ComponentbuilderHelper $format = 'Y-m-d \o\n H:' . self::periodFix(self::$keytimer->format('i')); } // get key - if (self::checkArray($dynamic)) + if (UtilitiesArrayHelper::check($dynamic)) { return md5(str_replace(array_keys($dynamic), array_values($dynamic), self::$keytimer->format($format) . ' @ VDM.I0')); } @@ -4502,7 +4477,7 @@ abstract class ComponentbuilderHelper public static function getDynamicSalt($dynamic = null) { // load global if not manually set - if (!self::checkArray($dynamic)) + if (!UtilitiesArrayHelper::check($dynamic)) { return self::getGlobalSalt(); } @@ -4525,7 +4500,7 @@ abstract class ComponentbuilderHelper $string = self::randomkey($size); } // convert string to array - $string = self::safeString($string); + $string = UtilitiesStringHelper::safe($string); // convert string to array $array = str_split($string); // insure only unique values are used @@ -4542,19 +4517,19 @@ abstract class ComponentbuilderHelper public static function getGlobalSalt() { // load from memory if found - if (!self::checkArray(self::$globalSalt)) + if (!UtilitiesArrayHelper::check(self::$globalSalt)) { // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } // check if we have a global dynamic replacement array available (format --> ' 1->!,3->E,4->A') $tmp = self::$params->get('dynamic_salt', null); - if (self::checkString($tmp) && strpos($tmp, ',') !== false && strpos($tmp, '->') !== false) + if (UtilitiesStringHelper::check($tmp) && strpos($tmp, ',') !== false && strpos($tmp, '->') !== false) { $salt = array_map('trim', (array) explode(',', $tmp)); - if (self::checkArray($salt )) + if (UtilitiesArrayHelper::check($salt )) { foreach($salt as $replace) { @@ -4568,7 +4543,7 @@ abstract class ComponentbuilderHelper } } // return global if found - if (self::checkArray(self::$globalSalt)) + if (UtilitiesArrayHelper::check(self::$globalSalt)) { return self::$globalSalt; } @@ -4666,7 +4641,7 @@ abstract class ComponentbuilderHelper */ public static function hasWork(&$function) { - if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function])) + if (isset(self::$worker[$function]) && UtilitiesArrayHelper::check(self::$worker[$function])) { return count( (array) self::$worker[$function]); } @@ -4685,7 +4660,7 @@ abstract class ComponentbuilderHelper public static function setWorkerUrl(&$function, &$url) { // set the URL if found - if (self::checkString($url)) + if (UtilitiesStringHelper::check($url)) { // make sure task function url is up self::$workerURL[$function] = $url; @@ -4704,7 +4679,7 @@ abstract class ComponentbuilderHelper public static function setWorkerHeaders(&$function, &$headers) { // set the Headers if found - if (self::checkArray($headers)) + if (UtilitiesArrayHelper::check($headers)) { // make sure task function headers are set self::$workerHEADER[$function] = $headers; @@ -4761,7 +4736,7 @@ abstract class ComponentbuilderHelper // build headers $headers = array('VDM-TASK: ' .$task); // build dynamic headers - if (isset(self::$workerHEADER[$function]) && self::checkArray(self::$workerHEADER[$function])) + if (isset(self::$workerHEADER[$function]) && UtilitiesArrayHelper::check(self::$workerHEADER[$function])) { foreach (self::$workerHEADER[$function] as $header) { @@ -4771,7 +4746,7 @@ abstract class ComponentbuilderHelper // build worker options $options = array(); // make sure worker is up - if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function])) + if (isset(self::$worker[$function]) && UtilitiesArrayHelper::check(self::$worker[$function])) { // this load method is for each if (1 == $perTask) @@ -4800,7 +4775,7 @@ abstract class ComponentbuilderHelper self::$worker[$function] = array(); } // do the execution - if (self::checkArray($options)) + if (UtilitiesArrayHelper::check($options)) { if (isset(self::$workerURL[$function])) { @@ -4841,7 +4816,7 @@ abstract class ComponentbuilderHelper return false; } // make sure we have an url - if (self::checkString($url)) + if (UtilitiesStringHelper::check($url)) { // make sure the thread size isn't greater than the # of _options $threadSize = (count($_options) < $threadSize) ? count($_options) : $threadSize; @@ -4932,17 +4907,17 @@ abstract class ComponentbuilderHelper // get URL $url = self::getEditURL($item, $view, $views, $ref, $component); // check if we found any - if (self::checkString($url)) + if (UtilitiesStringHelper::check($url)) { // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } // get UIKIT version $uikit = self::$params->get('uikit_version', 2); // check that we have the ID - if (self::checkObject($item) && isset($item->id)) + if (ObjectHelper::check($item) && isset($item->id)) { // check if the checked_out is available if (isset($item->checked_out)) @@ -4954,7 +4929,7 @@ abstract class ComponentbuilderHelper $checked_out = self::getVar($view, $item->id, 'id', 'checked_out', '=', str_replace('com_', '', $component)); } } - elseif (self::checkArray($item) && isset($item['id'])) + elseif (UtilitiesArrayHelper::check($item) && isset($item['id'])) { // check if the checked_out is available if (isset($item['checked_out'])) @@ -4971,9 +4946,9 @@ abstract class ComponentbuilderHelper $checked_out = self::getVar($view, $item, 'id', 'checked_out', '=', str_replace('com_', '', $component)); } // set the link title - $title = self::safeString(JText::_('COM_COMPONENTBUILDER_EDIT') . ' ' . $view, 'W'); + $title = UtilitiesStringHelper::safe(JText::_('COM_COMPONENTBUILDER_EDIT') . ' ' . $view, 'W'); // check that there is a check message - if (self::checkString($headsup)) + if (UtilitiesStringHelper::check($headsup)) { if (3 == $uikit) { @@ -4999,7 +4974,7 @@ abstract class ComponentbuilderHelper { return ' '; } - return ' '; + return ' '; } // return normal edit link return ' '; @@ -5012,7 +4987,7 @@ abstract class ComponentbuilderHelper { return ' '; } - return ' '; + return ' '; } // return normal edit link return ' '; @@ -5037,24 +5012,24 @@ abstract class ComponentbuilderHelper public static function getEditTextButton($text, &$item, $view, $views, $ref = '', $component = 'com_componentbuilder', $jRoute = true, $class = 'uk-button', $headsup = 'COM_COMPONENTBUILDER_ALL_UNSAVED_WORK_ON_THIS_PAGE_WILL_BE_LOST_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE') { // make sure we have text - if (!self::checkString($text)) + if (!UtilitiesStringHelper::check($text)) { return self::getEditButton($item, $view, $views, $ref, $component, $headsup); } // get URL $url = self::getEditURL($item, $view, $views, $ref, $component, $jRoute); // check if we found any - if (self::checkString($url)) + if (UtilitiesStringHelper::check($url)) { // get the global settings - if (!self::checkObject(self::$params)) + if (!ObjectHelper::check(self::$params)) { self::$params = JComponentHelper::getParams('com_componentbuilder'); } // get UIKIT version $uikit = self::$params->get('uikit_version', 2); // check that we have the ID - if (self::checkObject($item) && isset($item->id)) + if (ObjectHelper::check($item) && isset($item->id)) { // check if the checked_out is available if (isset($item->checked_out)) @@ -5066,7 +5041,7 @@ abstract class ComponentbuilderHelper $checked_out = self::getVar($view, $item->id, 'id', 'checked_out', '=', str_replace('com_', '', $component)); } } - elseif (self::checkArray($item) && isset($item['id'])) + elseif (UtilitiesArrayHelper::check($item) && isset($item['id'])) { // check if the checked_out is available if (isset($item['checked_out'])) @@ -5083,9 +5058,9 @@ abstract class ComponentbuilderHelper $checked_out = self::getVar($view, $item, 'id', 'checked_out', '=', str_replace('com_', '', $component)); } // set the link title - $title = self::safeString(JText::_('COM_COMPONENTBUILDER_EDIT') . ' ' . $view, 'W'); + $title = UtilitiesStringHelper::safe(JText::_('COM_COMPONENTBUILDER_EDIT') . ' ' . $view, 'W'); // check that there is a check message - if (self::checkString($headsup)) + if (UtilitiesStringHelper::check($headsup)) { if (3 == $uikit) { @@ -5111,7 +5086,7 @@ abstract class ComponentbuilderHelper { return ' ' . $text . ''; } - return ' ' . $text . ''; + return ' ' . $text . ''; } // return normal edit link return ' ' . $text . ''; @@ -5124,7 +5099,7 @@ abstract class ComponentbuilderHelper { return ' ' . $text . ''; } - return ' ' . $text . ''; + return ' ' . $text . ''; } // return normal edit link return ' ' . $text . ''; @@ -5202,7 +5177,7 @@ abstract class ComponentbuilderHelper // we start with false. $can_edit = false; // check that we have the ID - if (self::checkObject($item) && isset($item->id)) + if (ObjectHelper::check($item) && isset($item->id)) { $record->id = (int) $item->id; // check if created_by is available @@ -5211,7 +5186,7 @@ abstract class ComponentbuilderHelper $record->created_by = (int) $item->created_by; } } - elseif (self::checkArray($item) && isset($item['id'])) + elseif (UtilitiesArrayHelper::check($item) && isset($item['id'])) { $record->id = (int) $item['id']; // check if created_by is available @@ -5489,7 +5464,7 @@ abstract class ComponentbuilderHelper self::$subformLayouts = JComponentHelper::getParams('com_componentbuilder')->get('subform_layouts', false); } // check what we found (else) return default - if (self::checkObject(self::$subformLayouts)) + if (ObjectHelper::check(self::$subformLayouts)) { // looking for $target = $view . '.' . $field; @@ -5509,571 +5484,6 @@ abstract class ComponentbuilderHelper } - /** - * get extensions grouped list xml - **/ - public static function getExtensionGroupedListXml() - { - // the extension types - $extensions = array( - 'joomla_component' => 'COM_COMPONENTBUILDER_COMPONENT', - 'joomla_module' => 'COM_COMPONENTBUILDER_MODULE', - 'joomla_plugin' => 'COM_COMPONENTBUILDER_PLUGIN' - ); - // get the extension values - foreach ($extensions as $extension => $label) - { - ${$extension} = self::getByTypeTheIdsSystemNames($extension); - } - - $xml = new DOMDocument(); - $xml->formatOutput = true; - - $root = $xml->createElement('field'); - $root->setAttributeNode(new DOMAttr('name', 'extension')); - $root->setAttributeNode(new DOMAttr('type', 'groupedlist')); - $root->setAttributeNode(new DOMAttr('onchange', 'this.form.submit();')); - - $root - ->appendChild($xml->createElement('option', '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_EXTENSION') . ' -')) - ->setAttributeNode(new DOMAttr('value', '')); - - foreach ($extensions as $extension => $label) - { - $extension_node = $xml->createElement('group'); - $extension_node->setAttributeNode(new DOMAttr('label', $label)); - if (!self::checkArray(${$extension})) - { - $extension_node - ->appendChild($xml->createElement('option', '- ' . JText::_('COM_COMPONENTBUILDER_NONE') . ' -')) - ->setAttributeNode(new DOMAttr('disabled', 'true')); - } - else - { - foreach (${$extension} as $id => $element) - { - $extension_node - ->appendChild($xml->createElement('option', $element)) - ->setAttributeNode(new DOMAttr('value', $extension . '__' . $id)); - } - } - $root->appendChild($extension_node); - } - $xml->appendChild($root); - return $xml->saveXML(); - } - - /** - * get by type the ids and system names - **/ - public static function getByTypeTheIdsSystemNames($type, $limiter = null) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - $query - ->select($db->quoteName(array('id', 'system_name'))) - ->from($db->quoteName('#__componentbuilder_' . $type)) - ->where($db->quoteName('published') . ' >= 1') - ->order($db->quoteName('modified') . ' desc') - ->order($db->quoteName('created') . ' desc'); - // check if we have a limter for admin views - if ($type === 'admin_view' && $limiter) - { - // first get all views - $adminviewIds = array(); - // if this is a plugin or a module, then no views - if (strpos($limiter, 'joomla_component') !== false) - { - $component = (int) str_replace('joomla_component__', '', $limiter); - // get the views of this component - if ($addViews = self::getVar('component_admin_views', (int) $component, 'joomla_component', 'addadmin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['adminview'])) - { - $adminviewIds[(int) $addView['adminview']] = (int) $addView['adminview']; - } - } - } - } - } - } - // now check if we still have admin views - if (self::checkArray($adminviewIds)) - { - $query->where($db->quoteName('id') . ' IN (' . implode(',', $adminviewIds) . ')'); - } - else - { - return false; - } - } - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadAssocList('id', 'system_name'); - } - return false; - } - - - /** - * get any area linked IDs - */ - public static function getAreaLinkedIDs($extension, $type) - { - // What ever... - if ($type === 'joomla_component_admin_views') - { - return self::getComponentAdminViewsIDs($extension); - } - elseif ($type === 'joomla_component_custom_admin_views') - { - return self::getComponentCustomAdminViewsIDs($extension); - } - elseif ($type === 'joomla_component_site_views') - { - return self::getComponentSiteViewsIDs($extension); - } - elseif ($type === 'joomla_component') - { - return self::getComponentFieldsIDs($extension); - } - elseif ($type === 'joomla_module') - { - return self::getModuleFieldsIDs($extension); - } - elseif ($type === 'joomla_plugin') - { - return self::getPluginFieldsIDs($extension); - } - elseif ($type === 'admin_view') - { - return self::getAdminViewFieldsIDs($extension); - } - return false; - } - - /** - * get a component admin views IDs - */ - public static function getComponentAdminViewsIDs($id) - { - // get all this components views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['adminview'])) - { - $adminviewIds[(int) $addView['adminview']] = (int) $addView['adminview']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($adminviewIds)) - { - return array_values($adminviewIds); - } - return false; - } - - /** - * get a component custom admin views IDs - */ - public static function getComponentCustomAdminViewsIDs($id) - { - // get all this components views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_custom_admin_views', (int) $id, 'joomla_component', 'addcustom_admin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['customadminview'])) - { - $adminviewIds[(int) $addView['customadminview']] = (int) $addView['customadminview']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($adminviewIds)) - { - return array_values($adminviewIds); - } - return false; - } - - /** - * get a component site views IDs - */ - public static function getComponentSiteViewsIDs($id) - { - // get all this components views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_site_views', (int) $id, 'joomla_component', 'addsite_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['siteview'])) - { - $adminviewIds[(int) $addView['siteview']] = (int) $addView['siteview']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($adminviewIds)) - { - return array_values($adminviewIds); - } - return false; - } - - /** - * get a component fields IDs - */ - public static function getComponentFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - // first get all views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['adminview'])) - { - $adminviewIds[(int) $addView['adminview']] = (int) $addView['adminview']; - } - } - } - } - } - // check that we have views - if (self::checkArray($adminviewIds)) - { - foreach ($adminviewIds as $adminView) - { - // get all the fields linked to the admin view - if ($addFields = self::getVar('admin_fields', (int) $adminView, 'admin_view', 'addfields')) - { - if (self::checkJson($addFields)) - { - $addFields = json_decode($addFields, true); - if (self::checkArray($addFields)) - { - foreach($addFields as $addField) - { - if (isset($addField['field'])) - { - $fieldIds[(int) $addField['field']] = (int) $addField['field']; - } - } - } - } - } - } - } - // get config values - if ($addconfig = self::getVar('component_config', (int) $id, 'joomla_component', 'addconfig')) - { - if (self::checkJson($addconfig)) - { - $addconfig = json_decode($addconfig, true); - if (self::checkArray($addconfig)) - { - foreach($addconfig as $addconf) - { - if (isset($addconf['field'])) - { - $fieldIds[(int) $addconf['field']] = (int) $addconf['field']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get a module fields IDs - */ - public static function getModuleFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - if ($fields = self::getVar('joomla_module', (int) $id, 'id', 'fields')) - { - if (self::checkJson($fields)) - { - $fields = json_decode($fields, true); - if (self::checkArray($fields)) - { - foreach($fields as $form) - { - if (isset($form['fields']) && self::checkArray($form['fields'])) - { - foreach ($form['fields'] as $field) - { - if (isset($field['field'])) - { - $fieldIds[(int) $field['field']] = (int) $field['field']; - } - } - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get a plugin fields IDs - */ - public static function getPluginFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - if ($fields = self::getVar('joomla_plugin', (int) $id, 'id', 'fields')) - { - if (self::checkJson($fields)) - { - $fields = json_decode($fields, true); - if (self::checkArray($fields)) - { - foreach($fields as $form) - { - if (isset($form['fields']) && self::checkArray($form['fields'])) - { - foreach ($form['fields'] as $field) - { - if (isset($field['field'])) - { - $fieldIds[(int) $field['field']] = (int) $field['field']; - } - } - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get an admin view fields IDs - */ - public static function getAdminViewFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - // get all the fields linked to the admin view - if ($addFields = self::getVar('admin_fields', (int) $id, 'admin_view', 'addfields')) - { - if (self::checkJson($addFields)) - { - $addFields = json_decode($addFields, true); - if (self::checkArray($addFields)) - { - foreach($addFields as $addField) - { - if (isset($addField['field'])) - { - $fieldIds[(int) $addField['field']] = (int) $addField['field']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get translation extension ids - **/ - public static function getTranslationExtensionsIds($extension, $type) - { - // only allow these columns (extension types) - $columns = array( - 'joomla_component' => 'components', - 'joomla_module' => 'modules', - 'joomla_plugin' => 'plugins' - ); - // check if the column name is correct - if (isset($columns[$type])) - { - $column = $columns[$type]; - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $query - ->select($db->quoteName(array('id', $column))) - ->from($db->quoteName('#__componentbuilder_language_translation')) - ->where($db->quoteName($column) . ' != ' . $db->quote('')); - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - $results = $db->loadAssocList(); - $matches = array(); - foreach ($results as $k => $v) - { - $value = json_decode($v[$column], true); - if (in_array($extension, $value)) - { - $matches[$v['id']] = $v['id']; - } - } - // Checks that we found matches - if (self::checkArray($matches)) - { - return array_values($matches); - } - } - } - return false; - } - - /** - * get translation ids - **/ - public static function getTranslationIds($language, $translated = true) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - $query - ->select($db->quoteName('id')) - ->from($db->quoteName('#__componentbuilder_language_translation')); - - // Build the where condition - if ($translated === true) // Translated - { - if ($language === 'all') - { - if (($languages = self::getAvailableLanguages()) !== false) - { - $wheres = array(); - foreach ($languages as $k => $v) - { - $wheres[] = $db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $k . '%'); - } - $query->where($wheres); - } - } - else - { - $query->where($db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $language . '%')); - } - } - else // Not translated - { - if ($language === 'none') - { - $query->where( - array( - $db->quoteName('translation') . ' = ' . $db->quote(''), - $db->quoteName('translation') . ' = ' . $db->quote('[]'), - $db->quoteName('translation') . ' = ' . $db->quote('{}') - ), 'OR' - ); - } - else - { - $query->where($db->quoteName('translation') . ' NOT LIKE ' . $db->quote('%' . $language . '%')); - } - } - - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return array_unique($db->loadColumn()); - } - return false; - } - - /** - * get available languages - **/ - public static function getAvailableLanguages() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $query - ->select($db->quoteName(array('langtag', 'name'))) - ->from($db->quoteName('#__componentbuilder_language')) - ->where($db->quoteName('published') . ' = 1') - ->order($db->quoteName('name') . ' desc'); - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadAssocList('langtag', 'name'); - } - return false; - } - - /** * Check if a row already exist * @@ -6099,7 +5509,7 @@ abstract class ComponentbuilderHelper { $query->from($db->quoteName('#__'.$main.'_'.$table)); } - if (self::checkArray($where)) + if (UtilitiesArrayHelper::check($where)) { foreach ($where as $key => $value) { @@ -6119,7 +5529,7 @@ abstract class ComponentbuilderHelper $query->where($db->quoteName($key) . ' ' . $operator . ' ' . (bool) $value); } // we do not allow arrays at this point - elseif (!self::checkArray($value)) + elseif (!UtilitiesArrayHelper::check($value)) { $query->where($db->quoteName($key) . ' ' . $operator . ' ' . $db->quote( (string) $value)); } @@ -6330,6 +5740,11 @@ abstract class ComponentbuilderHelper { JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_POWERS'), 'index.php?option=com_componentbuilder&view=powers', $submenu === 'powers'); } + // Access control (search.access && search.submenu). + if ($user->authorise('search.access', 'com_componentbuilder') && $user->authorise('search.submenu', 'com_componentbuilder')) + { + JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_SEARCH'), 'index.php?option=com_componentbuilder&view=search', $submenu === 'search'); + } if ($user->authorise('admin_view.access', 'com_componentbuilder') && $user->authorise('admin_view.submenu', 'com_componentbuilder')) { JHtmlSidebar::addEntry(JText::_('COM_COMPONENTBUILDER_SUBMENU_ADMIN_VIEWS'), 'index.php?option=com_componentbuilder&view=admin_views', $submenu === 'admin_views'); @@ -7140,35 +6555,12 @@ abstract class ComponentbuilderHelper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param mixed $node A SimpleXMLElement node to append to the XML element reference, or a stdClass object containing a comment attribute to be injected before the XML node and a fieldXML attribute containing a SimpleXMLElement * - * @return null - * + * @return void + * @deprecated 3.3 Use FormHelper::append($xml, $node); */ public static function xmlAppend(&$xml, $node) { - if (!$node) - { - // element was not returned - return; - } - switch (get_class($node)) - { - case 'stdClass': - if (property_exists($node, 'comment')) - { - self::xmlComment($xml, $node->comment); - } - if (property_exists($node, 'fieldXML')) - { - self::xmlAppend($xml, $node->fieldXML); - } - break; - case 'SimpleXMLElement': - $domXML = dom_import_simplexml($xml); - $domNode = dom_import_simplexml($node); - $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); - $xml = simplexml_import_dom($domXML); - break; - } + FormHelper::append($xml, $node); } /** @@ -7177,16 +6569,12 @@ abstract class ComponentbuilderHelper * @param SimpleXMLElement $xml The XML element reference in which to inject a comment * @param string $comment The comment to inject * - * @return null - * + * @return void + * @deprecated 3.3 Use FormHelper::comment($xml, $comment); */ public static function xmlComment(&$xml, $comment) { - $domXML = dom_import_simplexml($xml); - $domComment = new DOMComment($comment); - $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); - $domXML->appendChild($nodeTarget); - $xml = simplexml_import_dom($domXML); + FormHelper::comment($xml, $comment); } /** @@ -7196,14 +6584,11 @@ abstract class ComponentbuilderHelper * @param array $attributes The attributes to apply to the XML element * * @return null - * + * @deprecated 3.3 Use FormHelper::attributes($xml, $attributes); */ public static function xmlAddAttributes(&$xml, $attributes = array()) { - foreach ($attributes as $key => $value) - { - $xml->addAttribute($key, $value); - } + FormHelper::attributes($xml, $attributes); } /** @@ -7213,16 +6598,11 @@ abstract class ComponentbuilderHelper * @param array $options The options to apply to the XML element * * @return void - * + * @deprecated 3.3 Use FormHelper::options($xml, $options); */ public static function xmlAddOptions(&$xml, $options = array()) { - foreach ($options as $key => $value) - { - $addOption = $xml->addChild('option'); - $addOption->addAttribute('value', $key); - $addOption[] = $value; - } + FormHelper::options($xml, $options); } /** @@ -7233,28 +6613,11 @@ abstract class ComponentbuilderHelper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use FormHelper::field($attributes, $default, $options); */ public static function getFieldObject(&$attributes, $default = '', $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes) && isset($attributes['type'])) - { - // make sure the form helper class is loaded - if (!method_exists('JFormHelper', 'loadFieldType')) - { - jimport('joomla.form.form'); - } - // get field type - $field = JFormHelper::loadFieldType($attributes['type'], true); - // get field xml - $XML = self::getFieldXML($attributes, $options); - // setup the field - $field->setup($XML, $default); - // return the field object - return $field; - } - return false; + return FormHelper::field($attributes, $default, $options); } /** @@ -7264,27 +6627,11 @@ abstract class ComponentbuilderHelper * @param array $options The options to apply to the XML element * * @return object - * + * @deprecated 3.3 Use FormHelper::xml($attributes, $options); */ public static function getFieldXML(&$attributes, $options = null) { - // make sure we have attributes and a type value - if (self::checkArray($attributes)) - { - // start field xml - $XML = new SimpleXMLElement(''); - // load the attributes - self::xmlAddAttributes($XML, $attributes); - // check if we have options - if (self::checkArray($options)) - { - // load the options - self::xmlAddOptions($XML, $options); - } - // return the field xml - return $XML; - } - return false; + return FormHelper::xml($attributes, $options); } /** diff --git a/admin/helpers/extrusion/a_mapping.php b/admin/helpers/extrusion/a_mapping.php index 468544f92..d5149def1 100644 --- a/admin/helpers/extrusion/a_mapping.php +++ b/admin/helpers/extrusion/a_mapping.php @@ -26,6 +26,11 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\ArrayHelper; + /** * Mapping class */ @@ -102,7 +107,7 @@ class Mapping // set the app to insure messages can be set $this->app = JFactory::getApplication(); // check that we have data - if (ComponentbuilderHelper::checkArray($data)) + if (ArrayHelper::check($data)) { // make sure we have an id if (isset($data['id']) && $data['id'] > 0) @@ -117,15 +122,15 @@ class Mapping { case 'base64': // set needed value - $this->$key = base64_decode($value); + $this->$key = base64_decode((string) $value); break; case 'json': // set needed value - $this->$key = json_decode($value, true); + $this->$key = json_decode((string) $value, true); break; case 'safeString': // set needed value - $this->$key = ComponentbuilderHelper::safeString($value); + $this->$key = StringHelper::check($value); break; default : $this->$key = $value; @@ -134,10 +139,10 @@ class Mapping } } // get linked admin views - $addadmin_views = ComponentbuilderHelper::getVar('component_admin_views', $data['id'], 'joomla_component', 'addadmin_views'); - if (ComponentbuilderHelper::checkJson($addadmin_views)) + $addadmin_views = GetHelper::var('component_admin_views', $data['id'], 'joomla_component', 'addadmin_views'); + if (JsonHelper::check($addadmin_views)) { - $this->addadmin_views = json_decode($addadmin_views, true); + $this->addadmin_views = json_decode((string)$addadmin_views, true); } // set the map of the views needed if ($this->setMap()) @@ -173,7 +178,7 @@ class Mapping { // start parsing the sql dump data $queries = JDatabaseDriver::splitSql($this->buildcompsql); - if (ComponentbuilderHelper::checkArray($queries)) + if (ArrayHelper::check($queries)) { foreach ($queries as $query) { @@ -208,7 +213,7 @@ class Mapping } } // check if the mapping was done - if (ComponentbuilderHelper::checkArray($this->map)) + if (ArrayHelper::check($this->map)) { return true; } @@ -224,12 +229,12 @@ class Mapping if (strpos($query, '`#__') !== false) { // get table name - $tableName = ComponentbuilderHelper::getBetween($query, '`#__', "`"); + $tableName = GetHelper::between($query, '`#__', "`"); } elseif (strpos($query, "'#__") !== false) { // get table name - $tableName = ComponentbuilderHelper::getBetween($query, "'#__", "'"); + $tableName = GetHelper::between($query, "'#__", "'"); } // if it still was not found if (!isset($tableName) || !ComponentbuilderHelper::checkString($tableName)) @@ -267,12 +272,12 @@ class Mapping if (0 === strpos($row, '`')) { // get field name - $name = ComponentbuilderHelper::getBetween($row, '`', '`'); + $name = GetHelper::between($row, '`', '`'); } if (0 === strpos($row, "'")) { // get field name - $name = ComponentbuilderHelper::getBetween($row, "'", "'"); + $name = GetHelper::between($row, "'", "'"); } // check if the name was found if (ComponentbuilderHelper::checkString($name)) @@ -289,7 +294,7 @@ class Mapping { $field['row'] = $row; $field['name'] = $name; - $field['label'] = ComponentbuilderHelper::safeString($name, 'W'); + $field['label'] = StringHelper::check($name, 'W'); $field['fieldType'] = $fieldType; $field['size'] = $this->getSize($row, $field); $field['sizeOther'] = ''; @@ -319,7 +324,7 @@ class Mapping } } } - if (ComponentbuilderHelper::checkArray($fields)) + if (ArrayHelper::check($fields)) { return $fields; } @@ -352,7 +357,7 @@ class Mapping { if (in_array($field['dataType'], $this->dataSize)) { - return ComponentbuilderHelper::getBetween($row, $field['dataType'].'(', ')'); + return GetHelper::between($row, $field['dataType'].'(', ')'); } return ''; } @@ -365,12 +370,12 @@ class Mapping // get default value if (strpos($row, 'DEFAULT "') !== false) // to sure it this is correct... { - return ComponentbuilderHelper::getBetween($row, 'DEFAULT "', '"'); + return GetHelper::between($row, 'DEFAULT "', '"'); } // get default value if (strpos($row, "DEFAULT '") !== false) { - return ComponentbuilderHelper::getBetween($row, "DEFAULT '", "'"); + return GetHelper::between($row, "DEFAULT '", "'"); } return ''; } diff --git a/admin/helpers/extrusion/b_builder.php b/admin/helpers/extrusion/b_builder.php index 49500600f..81e145cc0 100644 --- a/admin/helpers/extrusion/b_builder.php +++ b/admin/helpers/extrusion/b_builder.php @@ -26,6 +26,10 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Componentbuilder\Compiler\Factory as CFactory; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; + /** * Builder class */ @@ -102,7 +106,7 @@ class Builder extends Mapping { // set the view object $object = new stdClass(); - $object->system_name = ComponentbuilderHelper::safeString($name, 'W') . ' (dynamic build)'; + $object->system_name = StringHelper::check($name, 'W') . ' (dynamic build)'; $object->name_single = $name; $object->name_list = $name. 's'; $object->short_description = $name. ' view (dynamic build)'; @@ -191,7 +195,7 @@ class Builder extends Mapping */ protected function setField(&$view, &$field) { - if ($fieldType = $this->getFieldType($field['fieldType'])) + if ($fieldType = CFactory::_('Field.Type.Name')->get($field['fieldType'])) { // set the field object $object = new stdClass(); @@ -257,14 +261,14 @@ class Builder extends Mapping } return false; } - + /** * get the field type id from system */ protected function getFieldType($fieldName) { // load the field settings - return ComponentbuilderHelper::getVar('fieldtype', $fieldName, 'name', 'id'); + return GetHelper::var('fieldtype', $fieldName, 'name', 'id'); } /** diff --git a/admin/helpers/extrusion/c_extrusion.php b/admin/helpers/extrusion/c_extrusion.php index 81b2ffed4..718858cbf 100644 --- a/admin/helpers/extrusion/c_extrusion.php +++ b/admin/helpers/extrusion/c_extrusion.php @@ -26,6 +26,9 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\ArrayHelper; + /** * Extrusion class */ @@ -58,10 +61,10 @@ class Extrusion extends Builder protected function setAdminViews(&$component_id) { // check if views were set - if (ComponentbuilderHelper::checkArray($this->views)) + if (ArrayHelper::check($this->views)) { $count = 0; - if (ComponentbuilderHelper::checkArray($this->addadmin_views)) + if (ArrayHelper::check($this->addadmin_views)) { $count = (int) count((array)$this->addadmin_views) + 3; } @@ -84,7 +87,7 @@ class Extrusion extends Builder $this->addadmin_views['addadmin_views'.$pointer]['order'] = $pointer + 1; } } - if (isset($this->addadmin_views) && ComponentbuilderHelper::checkArray($this->addadmin_views)) + if (isset($this->addadmin_views) && ArrayHelper::check($this->addadmin_views)) { // set the field object $object = new stdClass(); @@ -94,7 +97,7 @@ class Extrusion extends Builder $object->created_by = $this->user->id; $object->published = 1; // check if it is already set - if ($item_id = ComponentbuilderHelper::getVar('component_admin_views', $component_id, 'joomla_component', 'id')) + if ($item_id = GetHelper::var('component_admin_views', $component_id, 'joomla_component', 'id')) { // set ID $object->id = (int) $item_id; diff --git a/admin/helpers/keywords_after.txt b/admin/helpers/keywords_after.txt deleted file mode 100644 index 7ad651f54..000000000 --- a/admin/helpers/keywords_after.txt +++ /dev/null @@ -1,7 +0,0 @@ -in -public -extends -private -protected -implements -instanceof \ No newline at end of file diff --git a/admin/helpers/keywords_before.txt b/admin/helpers/keywords_before.txt deleted file mode 100644 index c63026039..000000000 --- a/admin/helpers/keywords_before.txt +++ /dev/null @@ -1,28 +0,0 @@ -do -in -let -new -var -case -else -enum -void -with -class -const -yield -delete -export -import -public -return -static -typeof -extends -package -private -continue -function -protected -implements -instanceof \ No newline at end of file diff --git a/admin/helpers/keywords_reserved.txt b/admin/helpers/keywords_reserved.txt deleted file mode 100644 index 626306fe5..000000000 --- a/admin/helpers/keywords_reserved.txt +++ /dev/null @@ -1,47 +0,0 @@ -do -if -in -for -let -new -try -var -case -else -enum -eval -null -this -true -void -with -break -catch -class -const -false -super -throw -while -yield -delete -export -import -public -return -static -switch -typeof -default -extends -finally -package -private -continue -debugger -function -arguments -interface -protected -implements -instanceof \ No newline at end of file diff --git a/admin/helpers/minify.php b/admin/helpers/minify.php deleted file mode 100644 index b126a1f58..000000000 --- a/admin/helpers/minify.php +++ /dev/null @@ -1,381 +0,0 @@ - - @github Joomla Component Builder - @copyright Copyright (C) 2015. All Rights Reserved - @license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html - - Builds Complex Joomla Components - -/-----------------------------------------------------------------------------------------------------------------------------*/ - -// No direct access to this file -defined('_JEXEC') or die('Restricted access'); - -/** - * Abstract minifier class. - * - * Please report bugs on https://github.com/matthiasmullie/minify/issues - * - * @author Matthias Mullie - * - * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved. - * @license MIT License - */ -abstract class Minify -{ - /** - * The data to be minified - * - * @var string[] - */ - protected $data = array(); - - /** - * Array of patterns to match. - * - * @var string[] - */ - protected $patterns = array(); - - /** - * This array will hold content of strings and regular expressions that have - * been extracted from the JS source code, so we can reliably match "code", - * without having to worry about potential "code-like" characters inside. - * - * @var string[] - */ - public $extracted = array(); - - /** - * Init the minify class - optionally, code may be passed along already. - */ - public function __construct(/* $data = null, ... */) - { - // it's possible to add the source through the constructor as well ;) - if (func_num_args()) { - call_user_func_array(array($this, 'add'), func_get_args()); - } - } - - /** - * Add a file or straight-up code to be minified. - * - * @param string $data - */ - public function add($data /* $data = null, ... */) - { - // bogus "usage" of parameter $data: scrutinizer warns this variable is - // not used (we're using func_get_args instead to support overloading), - // but it still needs to be defined because it makes no sense to have - // this function without argument :) - $args = array($data) + func_get_args(); - - // this method can be overloaded - foreach ($args as $data) { - // redefine var - $data = (string) $data; - - // load data - $value = $this->load($data); - $key = ($data != $value) ? $data : count($this->data); - - // store data - $this->data[$key] = $value; - } - } - - /** - * Load data. - * - * @param string $data Either a path to a file or the content itself. - * @return string - */ - protected function load($data) - { - // check if the data is a file - if (@file_exists($data) && is_file($data)) { - $data = @file_get_contents($data); - - // strip BOM, if any - if (substr($data, 0, 3) == "\xef\xbb\xbf") { - $data = substr($data, 3); - } - } - - return $data; - } - - /** - * Save to file - * - * @param string $content The minified data. - * @param string $path The path to save the minified data to. - * @throws Exception - */ - protected function save($content, $path) - { - // create file & open for writing - if (($handler = @fopen($path, 'w')) === false) { - throw new Exception('The file "'.$path.'" could not be opened. Check if PHP has enough permissions.'); - } - - // write to file - if (@fwrite($handler, $content) === false) { - throw new Exception('The file "'.$path.'" could not be written to. Check if PHP has enough permissions.'); - } - - // close the file - @fclose($handler); - } - - /** - * Minify the data & (optionally) saves it to a file. - * - * @param string[optional] $path Path to write the data to. - * @return string The minified data. - */ - public function minify($path = null) - { - $content = $this->execute($path); - - // save to path - if ($path !== null) { - $this->save($content, $path); - } - - return $content; - } - - /** - * Minify & gzip the data & (optionally) saves it to a file. - * - * @param string[optional] $path Path to write the data to. - * @param int[optional] $level Compression level, from 0 to 9. - * @return string The minified & gzipped data. - */ - public function gzip($path = null, $level = 9) - { - $content = $this->execute($path); - $content = gzencode($content, $level, FORCE_GZIP); - - // save to path - if ($path !== null) { - $this->save($content, $path); - } - - return $content; - } - - /** - * Minify the data. - * - * @param string[optional] $path Path to write the data to. - * @return string The minified data. - */ - abstract protected function execute($path = null); - - /** - * Register a pattern to execute against the source content. - * - * @param string $pattern PCRE pattern. - * @param string|callable $replacement Replacement value for matched pattern. - * @throws Exception - */ - protected function registerPattern($pattern, $replacement = '') - { - // study the pattern, we'll execute it more than once - $pattern .= 'S'; - - $this->patterns[] = array($pattern, $replacement); - } - - /** - * We can't "just" run some regular expressions against JavaScript: it's a - * complex language. E.g. having an occurrence of // xyz would be a comment, - * unless it's used within a string. Of you could have something that looks - * like a 'string', but inside a comment. - * The only way to accurately replace these pieces is to traverse the JS one - * character at a time and try to find whatever starts first. - * - * @param string $content The content to replace patterns in. - * @return string The (manipulated) content. - */ - protected function replace($content) - { - $processed = ''; - $positions = array_fill(0, count($this->patterns), -1); - $matches = array(); - - while ($content) { - // find first match for all patterns - foreach ($this->patterns as $i => $pattern) { - list($pattern, $replacement) = $pattern; - - // no need to re-run matches that are still in the part of the - // content that hasn't been processed - if ($positions[$i] >= 0) { - continue; - } - - $match = null; - if (preg_match($pattern, $content, $match)) { - $matches[$i] = $match; - - // we'll store the match position as well; that way, we - // don't have to redo all preg_matches after changing only - // the first (we'll still know where those others are) - $positions[$i] = strpos($content, $match[0]); - } else { - // if the pattern couldn't be matched, there's no point in - // executing it again in later runs on this same content; - // ignore this one until we reach end of content - unset($matches[$i]); - $positions[$i] = strlen($content); - } - } - - // no more matches to find: everything's been processed, break out - if (!$matches) { - $processed .= $content; - break; - } - - // see which of the patterns actually found the first thing (we'll - // only want to execute that one, since we're unsure if what the - // other found was not inside what the first found) - $discardLength = min($positions); - $firstPattern = array_search($discardLength, $positions); - $match = $matches[$firstPattern][0]; - - // execute the pattern that matches earliest in the content string - list($pattern, $replacement) = $this->patterns[$firstPattern]; - $replacement = $this->replacePattern($pattern, $replacement, $content); - - // figure out which part of the string was unmatched; that's the - // part we'll execute the patterns on again next - $content = substr($content, $discardLength); - $unmatched = (string) substr($content, strpos($content, $match) + strlen($match)); - - // move the replaced part to $processed and prepare $content to - // again match batch of patterns against - $processed .= substr($replacement, 0, strlen($replacement) - strlen($unmatched)); - $content = $unmatched; - - // first match has been replaced & that content is to be left alone, - // the next matches will start after this replacement, so we should - // fix their offsets - foreach ($positions as $i => $position) { - $positions[$i] -= $discardLength + strlen($match); - } - } - - return $processed; - } - - /** - * This is where a pattern is matched against $content and the matches - * are replaced by their respective value. - * This function will be called plenty of times, where $content will always - * move up 1 character. - * - * @param string $pattern Pattern to match. - * @param string|callable $replacement Replacement value. - * @param string $content Content to match pattern against. - * @return string - */ - protected function replacePattern($pattern, $replacement, $content) - { - if (is_callable($replacement)) { - return preg_replace_callback($pattern, $replacement, $content, 1, $count); - } else { - return preg_replace($pattern, $replacement, $content, 1, $count); - } - } - - /** - * Strings are a pattern we need to match, in order to ignore potential - * code-like content inside them, but we just want all of the string - * content to remain untouched. - * - * This method will replace all string content with simple STRING# - * placeholder text, so we've rid all strings from characters that may be - * misinterpreted. Original string content will be saved in $this->extracted - * and after doing all other minifying, we can restore the original content - * via restoreStrings() - * - * @param string[optional] $chars - */ - protected function extractStrings($chars = '\'"') - { - // PHP only supports $this inside anonymous functions since 5.4 - $minifier = $this; - $callback = function ($match) use ($minifier) { - if (!$match[1]) { - /* - * Empty strings need no placeholder; they can't be confused for - * anything else anyway. - * But we still needed to match them, for the extraction routine - * to skip over this particular string. - */ - return $match[0]; - } - - $count = count($minifier->extracted); - $placeholder = $match[1].$count.$match[1]; - $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1]; - - return $placeholder; - }; - - /* - * The \\ messiness explained: - * * Don't count ' or " as end-of-string if it's escaped (has backslash - * in front of it) - * * Unless... that backslash itself is escaped (another leading slash), - * in which case it's no longer escaping the ' or " - * * So there can be either no backslash, or an even number - * * multiply all of that times 4, to account for the escaping that has - * to be done to pass the backslash into the PHP string without it being - * considered as escape-char (times 2) and to get it in the regex, - * escaped (times 2) - */ - $this->registerPattern('/(['.$chars.'])(.*?((?extracted. - * - * @param string $content - * @return string - */ - protected function restoreExtractedData($content) - { - if (!$this->extracted) { - // nothing was extracted, nothing to restore - return $content; - } - - $content = strtr($content, $this->extracted); - - $this->extracted = array(); - - return $content; - } -} diff --git a/admin/helpers/operators_after.txt b/admin/helpers/operators_after.txt deleted file mode 100644 index 68b7943d3..000000000 --- a/admin/helpers/operators_after.txt +++ /dev/null @@ -1,45 +0,0 @@ -+ -- -* -/ -% -= -+= --= -*= -/= -%= -<<= ->>= ->>>= -&= -^= -|= -& -| -^ -~ -<< ->> ->>> -== -=== -!= -!== -> -< ->= -<= -&& -|| -. -[ -] -? -: -, -; -( -) -{ -} \ No newline at end of file diff --git a/admin/helpers/operators_before.txt b/admin/helpers/operators_before.txt deleted file mode 100644 index 3bc220ac7..000000000 --- a/admin/helpers/operators_before.txt +++ /dev/null @@ -1,43 +0,0 @@ -+ -- -* -/ -% -= -+= --= -*= -/= -%= -<<= ->>= ->>>= -&= -^= -|= -& -| -^ -~ -<< ->> ->>> -== -=== -!= -!== -> -< ->= -<= -&& -|| -! -. -[ -? -: -, -; -( -{ \ No newline at end of file diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index a4cb1bba7..64e38e12e 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -6,6 +6,7 @@ COM_COMPONENTBUILDER_ACCEPTS_ONLY_THE_VALUES_ZERO_ONE_TRUE_OR_FALSE_CASEINSENSIT COM_COMPONENTBUILDER_ACCESS="Access" COM_COMPONENTBUILDER_ACCESS_BULK_TOOLS="Access Bulk Tools" COM_COMPONENTBUILDER_ACCESS_DENIED="Access denied!" +COM_COMPONENTBUILDER_ACTIVATE_SUPER_POWERS="Activate Super Powers?" COM_COMPONENTBUILDER_ACTIVE_ONLY_FOUR_TEXT_FIELD="Active (only 4 text_field)" COM_COMPONENTBUILDER_ADD="Add" COM_COMPONENTBUILDER_ADD_ACCESS="Add Access" @@ -24,7 +25,7 @@ COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_ACCESS_DESC="Allows the users in this gr COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_OPTIONS="Batch process the selected Admins Custom Tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_TIP="All changes will be applied to all selected Admins Custom Tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_USE="Admins Custom Tabs Batch Use" -COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins custom tabs" +COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_CREATE="Admins Custom Tabs Create" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_CREATE_DESC="Allows the users in this group to create create admins custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_DELETE="Admins Custom Tabs Delete" @@ -40,7 +41,7 @@ COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_STATE="Admins Custom Tabs Edit State" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_VERSION="Admins Custom Tabs Edit Version" -COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins custom tabs" +COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_N_ITEMS_ARCHIVED="%s Admins Custom Tabs archived." COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_N_ITEMS_ARCHIVED_1="%s Admin Custom Tabs archived." COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_N_ITEMS_CHECKED_IN_0="No Admin Custom Tabs successfully checked in." @@ -66,14 +67,14 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_ACCESS_DESC="Allows the users in this group t COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_OPTIONS="Batch process the selected Admins Fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_TIP="All changes will be applied to all selected Admins Fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_USE="Admins Fields Batch Use" -COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins fields" +COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS="Admins Fields Conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_ACCESS="Admins Fields Conditions Access" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_ACCESS_DESC="Allows the users in this group to access access admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_OPTIONS="Batch process the selected Admins Fields Conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_TIP="All changes will be applied to all selected Admins Fields Conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_USE="Admins Fields Conditions Batch Use" -COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins fields conditions" +COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_CREATE="Admins Fields Conditions Create" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_CREATE_DESC="Allows the users in this group to create create admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_DELETE="Admins Fields Conditions Delete" @@ -89,7 +90,7 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_STATE="Admins Fields Conditions Edit State" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_VERSION="Admins Fields Conditions Edit Version" -COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins fields conditions" +COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_N_ITEMS_ARCHIVED="%s Admins Fields Conditions archived." COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_N_ITEMS_ARCHIVED_1="%s Admin Fields Conditions archived." COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_N_ITEMS_CHECKED_IN_0="No Admin Fields Conditions successfully checked in." @@ -124,7 +125,7 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_STATE="Admins Fields Edit State" COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_VERSION="Admins Fields Edit Version" -COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins fields" +COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_N_ITEMS_ARCHIVED="%s Admins Fields archived." COM_COMPONENTBUILDER_ADMINS_FIELDS_N_ITEMS_ARCHIVED_1="%s Admin Fields archived." COM_COMPONENTBUILDER_ADMINS_FIELDS_N_ITEMS_CHECKED_IN_0="No Admin Fields successfully checked in." @@ -150,7 +151,7 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_ACCESS_DESC="Allows the users in th COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_OPTIONS="Batch process the selected Admins Fields Relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_TIP="All changes will be applied to all selected Admins Fields Relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_USE="Admins Fields Relations Batch Use" -COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins fields relations" +COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_CREATE="Admins Fields Relations Create" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_CREATE_DESC="Allows the users in this group to create create admins fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_DELETE="Admins Fields Relations Delete" @@ -166,7 +167,7 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_STATE="Admins Fields Relations Edit State" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_VERSION="Admins Fields Relations Edit Version" -COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins fields relations" +COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_N_ITEMS_ARCHIVED="%s Admins Fields Relations archived." COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_N_ITEMS_ARCHIVED_1="%s Admin Fields Relations archived." COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_N_ITEMS_CHECKED_IN_0="No Admin Fields Relations successfully checked in." @@ -371,8 +372,7 @@ COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_MODIFIED_DATE_DESC="The date this Admin Fields Relations was modified." COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_NEW="A New Admin Fields Relations" -COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_NOTE_ON_RELATIONS_DESCRIPTION="

Here you are able to combine/join multiple fields into one for display in the list view of the admin area.

-

You are able to add calculations, or even model the values into one result.

" +COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_NOTE_ON_RELATIONS_DESCRIPTION="

Here you are able to combine/join multiple fields into one for display in the list view of the admin area.

You are able to add calculations, or even model the values into one result.

" COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_NOTE_ON_RELATIONS_LABEL="Relations Implementation" COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_PERMISSION="Permissions" @@ -413,11 +413,9 @@ COM_COMPONENTBUILDER_ADMIN_VIEWS_ACCESS_DESC="Allows the users in this group to COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_OPTIONS="Batch process the selected Admin Views" COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_TIP="All changes will be applied to all selected Admin Views" COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_USE="Admin Views Batch Use" -COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admin views" +COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_CREATE="Admin Views Create" COM_COMPONENTBUILDER_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create admin views" -COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_ADD="Admin Views Dashboard Add" -COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of admin view" COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_LIST="Admin Views Dashboard List" COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of admin view" COM_COMPONENTBUILDER_ADMIN_VIEWS_DELETE="Admin Views Delete" @@ -434,7 +432,7 @@ COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the users in this group t COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_STATE="Admin Views Edit State" COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin view" COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_VERSION="Admin Views Edit Version" -COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admin views" +COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_EXPORT="Admin Views Export" COM_COMPONENTBUILDER_ADMIN_VIEWS_EXPORT_DESC="Allows the users in this group to export export admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_IMPORT="Admin Views Import" @@ -864,14 +862,12 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_HINT="Name Here" COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LABEL="Name" COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LIST_DESCRIPTION="The name of the list of records in this view" COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LIST_HINT="List of Records Name Here" -COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LIST_LABEL="Name (list of records)
-Naming Conventions" +COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LIST_LABEL="Name (list of records)
Naming Conventions" COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LIST_MESSAGE="Error! Please add list of records name here." COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_SINGLE_DESCRIPTION="Type null if single record view is not to be set" COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_SINGLE_HINT="Single Record Name Here" -COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_SINGLE_LABEL="Name (single record)
-Naming Conventions" +COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_SINGLE_LABEL="Name (single record)
Naming Conventions" COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_SINGLE_MESSAGE="Error! Please add single record name here." COM_COMPONENTBUILDER_ADMIN_VIEW_NEW="A New Admin View" COM_COMPONENTBUILDER_ADMIN_VIEW_NEW_TAB="New Tab" @@ -890,15 +886,7 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_BEGINNER_IMPORT_LABEL="Beginners notice." COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CATEGORY_MENU_SWITCH_DESCRIPTION="You can now choose whether this view's category is added to the sub-menu." COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CATEGORY_MENU_SWITCH_LABEL="Category Menu Switch" COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CREATE_EDIT_BUTTONS_DESCRIPTION="Some Shortcut Buttons
" -COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CREATE_EDIT_DISPLAY_DESCRIPTION="
-

Linked Fields

-
Display of the fields will load here!
-
-

Field Relations

-
Display of the fields relations will load here!
-
-

Field Conditions

-
Display of the fields conditions will load here!
" +COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CREATE_EDIT_DISPLAY_DESCRIPTION="

Linked Fields

Display of the fields will load here!

Field Relations

Display of the fields relations will load here!

Field Conditions

Display of the fields conditions will load here!
" COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CREATE_EDIT_NOTICE_DESCRIPTION="
Welcome to the new improved fields and conditions layout.

We had to remove the repeatable fields layouts since Joomla has depreciated it. With this new improved layout we trust your experience will be better then ever before.

You can still watch the tutorials, and though it was made during the time repeatable fields were still being used, the various concepts and layouts still look mostly the same.

" COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CREATE_EDIT_NOTICE_LABEL="Fields & Conditions" COM_COMPONENTBUILDER_ADMIN_VIEW_NOTE_CUSTOM_TABS_NOTE_DESCRIPTION="You can add more custom tabs to this admin view, these tabs are generally used for static HTML content or Ajax generated fields/content. You can not have an admin view with only custom tabs, they can only be used as an add-on, not a stand alone." @@ -1286,12 +1274,15 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_YES="Yes" COM_COMPONENTBUILDER_ADMIN_VIEW_YOUTUBE="Youtube" COM_COMPONENTBUILDER_ADMIN_VIEW_ZOOM_IN="Zoom In" COM_COMPONENTBUILDER_ADMIN_VIEW_ZOOM_OUT="Zoom Out" +COM_COMPONENTBUILDER_ADVANCED_OPTIONS="Advanced Options" COM_COMPONENTBUILDER_AHEAD="Ahead" COM_COMPONENTBUILDER_AHEAD_MEANS_YOUR_BLOCAL_SNIPPETB_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_A_BNEWER_MODIFIED_DATEB_THEN_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE="Ahead means your local snippet (with the same name, library and type) has a newer modified date then the community snippet (with the same name, library and type)." COM_COMPONENTBUILDER_AJAX="Ajax" COM_COMPONENTBUILDER_ALIAS="Alias" COM_COMPONENTBUILDER_ALIGNMENT="Alignment" COM_COMPONENTBUILDER_ALL="All" +COM_COMPONENTBUILDER_ALLOWS_YOU_TO_OVERRIDE_THE_BUILD_DATE_BY_SELECTING_A_DATE_MANUALLY_FROM_THE_CALENDER="Allows you to override the build date by selecting a date manually from the calender." +COM_COMPONENTBUILDER_ALL_FOUND_INSTANCES_IN_S_WHERE_REPLACED="All found instances in %s where replaced" COM_COMPONENTBUILDER_ALL_IS_GOOD_PLEASE_CHECK_AGAIN_LATTER="All is good, please check again latter." COM_COMPONENTBUILDER_ALL_IS_GOOD_THERE_IS_NO_NOTICE_AT_THIS_TIME="All is good, there is no notice at this time." COM_COMPONENTBUILDER_ALL_OF_THESE_PACKAGES_ARE_A_FULLY_DEVELOPEDMAPPED_COMPONENTS_FOR_JCB_THEY_CAN_BE_SEEN_AS_DEMO_CONTENT_OR_BASE_IMAGES_FROM_WHICH_TO_START_YOUR_PROJECTBR_ALWAYS_MAKE_SURE_YOU_ARE_ON_THE_LATEST_VERSION_OF_JCB_BEFORE_IMPORTING_ANY_OF_THESE_PACKAGES_SHOULD_ANY_OF_THEM_FAIL_TO_IMPORT_A_S_PLEASE_LET_US_KNOWA="All of these packages are a fully developed/mapped components for JCB. They can be seen as demo content, or base images from which to start your project.
Always make sure you are on the latest version of JCB before importing any of these packages, should any of them fail to import please let us know." @@ -1301,6 +1292,7 @@ COM_COMPONENTBUILDER_ALREADY_SELECTED_TRY_ANOTHER="Already selected, try another COM_COMPONENTBUILDER_ALREADY_TRANSLATED_INTO="Already translated into" COM_COMPONENTBUILDER_ALWAYS_ADD="Always Add" COM_COMPONENTBUILDER_ALWAYS_INSURE_THAT_YOU_HAVE_YOUR_LOCAL_COMPONENTS_BACKED_UP_BY_MAKING_AN_EXPORT_OF_ALL_YOUR_LOCAL_COMPONENTS_BEFORE_IMPORTING_ANY_NEW_COMPONENTS_SMALLMAKE_BSUREB_TO_MOVE_THIS_ZIPPED_BACKUP_PACKAGE_OUT_OF_THE_TMP_FOLDER_BEFORE_DOING_AN_IMPORTSMALLBR_IF_YOU_ARE_IMPORTING_A_PACKAGE_OF_A_THREERD_PARTY_JCB_PACKAGE_DEVELOPER_BMAKE_SURE_IT_IS_A_REPUTABLE_JCB_PACKAGE_DEVELOPERSB_A_SFIND_OUT_WHYA="Always insure that you have your local components backed up, by making an export of all your local components before importing any new components. (Make SURE to move this zipped backup package out of the tmp folder before doing an import)
If you are importing a package of a 3rd party JCB package developer, make sure it is a reputable JCB package developers! Find out why!" +COM_COMPONENTBUILDER_AND_FINISHED_THE_SEARCH_IN="and finished the search in" COM_COMPONENTBUILDER_ANY_LANGUAGE="Any language" COM_COMPONENTBUILDER_ANY_SELECTION_ONLY_FOUR_LISTRADIOCHECKBOXESDYNAMIC_LIST="Any Selection (only 4 list/radio/checkboxes/dynamic_list)" COM_COMPONENTBUILDER_AN_ERROR_HAS_OCCURRED="An error has occurred" @@ -1311,12 +1303,14 @@ COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_CONTINUE="Are you sure you w COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_REPLACE_YOUR_LOCAL_SNIPPET_WITH_THIS_JCB_COMMUNITY_SNIPPET="Are you sure you would like to replace your local snippet with this JCB community snippet?" COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_UPDATE_YOUR_LOCAL_SNIPPET_WITH_THIS_NEWER_JCB_COMMUNITY_SNIPPET="Are you sure you would like to update your local snippet with this newer JCB community snippet?" COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_UPDATE_YOUR_LOCAL_SNIPPET_WITH_THIS_OLDER_JCB_COMMUNITY_SNIPPET="Are you sure you would like to update your local snippet with this older JCB community snippet?" +COM_COMPONENTBUILDER_ARE_YOU_THEREFORE_ABSOLUTELY_SURE_YOU_WANT_TO_CONTINUE="Are you therefore absolutely sure you want to continue?" COM_COMPONENTBUILDER_AUTHOR="Author" COM_COMPONENTBUILDER_AUTHOR_EMAIL="Author Email" COM_COMPONENTBUILDER_AUTHOR_NAME="Author Name" COM_COMPONENTBUILDER_AUTHOR_WEBSITE="Author Website" COM_COMPONENTBUILDER_AUTO_CHECKIN="Auto Check-in" COM_COMPONENTBUILDER_AVAILABLE_LIBRARIES="Available Libraries" +COM_COMPONENTBUILDER_A_METHOD_SETDYNAMICFZEROLDTHREERS_WAS_ADDED_TO_THE_INSTALL_BSCRIPTPHPB_OF_THIS_PACKAGE_TO_INSURE_THAT_THE_FOLDERS_ARE_COPIED_INTO_THE_CORRECT_PLACE_WHEN_THIS_COMPONENT_IS_INSTALLED="A method (setDynamicF0ld3rs) was added to the install script.php of this package to insure that the folder(s) are copied into the correct place when this component is installed!" COM_COMPONENTBUILDER_A_S_SPAN_CLASSICONFLAG_SPANREPORT_BROKEN_PACKAGEA=" Report Broken Package" COM_COMPONENTBUILDER_BACK="Back" COM_COMPONENTBUILDER_BACKUP="Backup" @@ -1330,9 +1324,12 @@ COM_COMPONENTBUILDER_BASIC_TUTORIAL_ON_GIT_BSB="Basic Tutorial on git: %s COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_WE_COULD_NOT_LOAD_THE_CHECKSUM_FOR_THIS_PACKAGE_AND_SO_NO_VALIDATION_WAS_POSSIBLE_THIS_MAY_BE_DUE_TO_YOUR_NETWORK_OR_A_CHANGE_TO_THAT_PACKAGE_NAME="Best to not continue!
We could not load the checksum for this package, and so no validation was possible. This may be due to your network, or a change to that package name." COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_YOU_CAN_REFRESH_AND_TRY_AGAINBR_BUT_NOTE_THAT_THIS_PACKAGE_BFAILEDB_CHECKSUM_VALIDATION_THIS_COULD_BE_A_SERIOUS_SECURITY_BREACH_DO_NOT_CONTINUE="Best to not continue!
You can Refresh and try again.
But note that this package FAILED checksum validation, this could be a serious security breach! DO NOT CONTINUE!!!" COM_COMPONENTBUILDER_BCUSTOM_FILESB_NOT_MOVED_TO_CORRECT_LOCATION="Custom files not moved to correct location!" +COM_COMPONENTBUILDER_BECOME_A_CONTRIBUTOR="Become a Contributor" +COM_COMPONENTBUILDER_BEHAVIOUR="Behaviour" COM_COMPONENTBUILDER_BEHIND="Behind" COM_COMPONENTBUILDER_BEHIND_MEANS_YOUR_BLOCAL_SNIPPETB_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_A_BOLDER_MODIFIED_DATEB_THEN_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE="Behind means your local snippet (with the same name, library and type) has a older modified date then the community snippet (with the same name, library and type)." COM_COMPONENTBUILDER_BETA_RELEASE="Beta Release" +COM_COMPONENTBUILDER_BE_A_PART_OF_JCB="Be a Part of JCB" COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE="Be cautious! Do not continue unless you trust the origin of this package!" COM_COMPONENTBUILDER_BFIELD_TYPEB_IDS_MISMATCH_IN_BSB="Field type id:%s mismatch in %s." COM_COMPONENTBUILDER_BFIELD_TYPEB_NOT_SET_FOR_BSB="Field type not set for %s." @@ -1350,6 +1347,7 @@ COM_COMPONENTBUILDER_BTHE_EXPANSION_WAS_SUCCESSFULLYB_TO_SEE_MORE_INFORMATION_CH COM_COMPONENTBUILDER_BTHE_TMP_FOLDER_HAS_BEEN_CLEAR_SUCCESSFULLYB="The tmp folder has been clear successfully!" COM_COMPONENTBUILDER_BUILD="Build" COM_COMPONENTBUILDER_BUILDIN="Build-in" +COM_COMPONENTBUILDER_BUILD_DATE="Build Date" COM_COMPONENTBUILDER_BULK="Bulk" COM_COMPONENTBUILDER_BULK_GET_ALL_NEW_SNIPPETS="Bulk Get All New Snippets" COM_COMPONENTBUILDER_BULK_TOOLS="Bulk Tools" @@ -1367,7 +1365,7 @@ COM_COMPONENTBUILDER_CLASS_EXTENDINGS_ACCESS_DESC="Allows the users in this grou COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_OPTIONS="Batch process the selected Class Extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_TIP="All changes will be applied to all selected Class Extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_USE="Class Extendings Batch Use" -COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch class extendings" +COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch class extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_CREATE="Class Extendings Create" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_CREATE_DESC="Allows the users in this group to create create class extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_DELETE="Class Extendings Delete" @@ -1383,7 +1381,7 @@ COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_STATE="Class Extendings Edit State" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_STATE_DESC="Allows the users in this group to update the state of the class extends" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_VERSION="Class Extendings Edit Version" -COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version class extendings" +COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version class extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_N_ITEMS_ARCHIVED="%s Class Extendings archived." COM_COMPONENTBUILDER_CLASS_EXTENDINGS_N_ITEMS_ARCHIVED_1="%s Class Extends archived." COM_COMPONENTBUILDER_CLASS_EXTENDINGS_N_ITEMS_CHECKED_IN_0="No Class Extends successfully checked in." @@ -1405,11 +1403,7 @@ COM_COMPONENTBUILDER_CLASS_EXTENDINGS_N_ITEMS_UNPUBLISHED="%s Class Extendings u COM_COMPONENTBUILDER_CLASS_EXTENDINGS_N_ITEMS_UNPUBLISHED_1="%s Class Extends unpublished." COM_COMPONENTBUILDER_CLASS_EXTENDS="Class Extends" COM_COMPONENTBUILDER_CLASS_EXTENDS_COMMENT_DESCRIPTION="The class comment" -COM_COMPONENTBUILDER_CLASS_EXTENDS_COMMENT_HINT="/** - * [NAME] - * - * @package [COMPONENT_NAME] - */" +COM_COMPONENTBUILDER_CLASS_EXTENDS_COMMENT_HINT="/** * [NAME] * * @package [COMPONENT_NAME] */" COM_COMPONENTBUILDER_CLASS_EXTENDS_COMMENT_LABEL="Class Comment" COM_COMPONENTBUILDER_CLASS_EXTENDS_COMPONENTS="components" COM_COMPONENTBUILDER_CLASS_EXTENDS_CREATED_BY_DESC="The user that created this Class Extends." @@ -1451,7 +1445,7 @@ COM_COMPONENTBUILDER_CLASS_METHODS_ACCESS_DESC="Allows the users in this group t COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_OPTIONS="Batch process the selected Class Methods" COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_TIP="All changes will be applied to all selected Class Methods" COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_USE="Class Methods Batch Use" -COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch class methods" +COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch class methods" COM_COMPONENTBUILDER_CLASS_METHODS_CREATE="Class Methods Create" COM_COMPONENTBUILDER_CLASS_METHODS_CREATE_DESC="Allows the users in this group to create create class methods" COM_COMPONENTBUILDER_CLASS_METHODS_DELETE="Class Methods Delete" @@ -1467,7 +1461,7 @@ COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_STATE="Class Methods Edit State" COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_STATE_DESC="Allows the users in this group to update the state of the class method" COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_VERSION="Class Methods Edit Version" -COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version class methods" +COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version class methods" COM_COMPONENTBUILDER_CLASS_METHODS_EXPORT="Class Methods Export" COM_COMPONENTBUILDER_CLASS_METHODS_EXPORT_DESC="Allows the users in this group to export export class methods" COM_COMPONENTBUILDER_CLASS_METHODS_IMPORT="Class Methods Import" @@ -1497,12 +1491,7 @@ COM_COMPONENTBUILDER_CLASS_METHOD_ARGUMENTS_LABEL="Params
Method Arg COM_COMPONENTBUILDER_CLASS_METHOD_CODE_DESCRIPTION="Add the code here." COM_COMPONENTBUILDER_CLASS_METHOD_CODE_LABEL="Code" COM_COMPONENTBUILDER_CLASS_METHOD_COMMENT_DESCRIPTION="The comment" -COM_COMPONENTBUILDER_CLASS_METHOD_COMMENT_HINT="/** - * [NAME] - * - * [PARAMS] - * - */" +COM_COMPONENTBUILDER_CLASS_METHOD_COMMENT_HINT="/** * [NAME] * * [PARAMS] * */" COM_COMPONENTBUILDER_CLASS_METHOD_COMMENT_LABEL="DocBlock" COM_COMPONENTBUILDER_CLASS_METHOD_COMPONENTS="components" COM_COMPONENTBUILDER_CLASS_METHOD_CREATED_BY_DESC="The user that created this Class Method." @@ -1553,7 +1542,7 @@ COM_COMPONENTBUILDER_CLASS_PROPERTIES_ACCESS_DESC="Allows the users in this grou COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_OPTIONS="Batch process the selected Class Properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_TIP="All changes will be applied to all selected Class Properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_USE="Class Properties Batch Use" -COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch class properties" +COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_CREATE="Class Properties Create" COM_COMPONENTBUILDER_CLASS_PROPERTIES_CREATE_DESC="Allows the users in this group to create create class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_DELETE="Class Properties Delete" @@ -1569,7 +1558,7 @@ COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_STATE="Class Properties Edit State" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_STATE_DESC="Allows the users in this group to update the state of the class property" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_VERSION="Class Properties Edit Version" -COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version class properties" +COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EXPORT="Class Properties Export" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EXPORT_DESC="Allows the users in this group to export export class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_IMPORT="Class Properties Import" @@ -1595,12 +1584,7 @@ COM_COMPONENTBUILDER_CLASS_PROPERTIES_N_ITEMS_UNPUBLISHED="%s Class Properties u COM_COMPONENTBUILDER_CLASS_PROPERTIES_N_ITEMS_UNPUBLISHED_1="%s Class Property unpublished." COM_COMPONENTBUILDER_CLASS_PROPERTY="Class Property" COM_COMPONENTBUILDER_CLASS_PROPERTY_COMMENT_DESCRIPTION="The comment" -COM_COMPONENTBUILDER_CLASS_PROPERTY_COMMENT_HINT="/** - * [NAME] - * - * [PARAMS] - * - */" +COM_COMPONENTBUILDER_CLASS_PROPERTY_COMMENT_HINT="/** * [NAME] * * [PARAMS] * */" COM_COMPONENTBUILDER_CLASS_PROPERTY_COMMENT_LABEL="DocBlock" COM_COMPONENTBUILDER_CLASS_PROPERTY_COMPONENTS="components" COM_COMPONENTBUILDER_CLASS_PROPERTY_CREATED_BY_DESC="The user that created this Class Property." @@ -1649,6 +1633,7 @@ COM_COMPONENTBUILDER_CLASS_PROPERTY_VERSION_DESC="A count of the number of times COM_COMPONENTBUILDER_CLASS_PROPERTY_VERSION_LABEL="Version" COM_COMPONENTBUILDER_CLASS_PROPERTY_VISIBILITY_DESCRIPTION="The visibility of a function/method or property can be defined by prefixing the declaration with the keywords public, protected or private. You also have the option to make function/method or property static." COM_COMPONENTBUILDER_CLASS_PROPERTY_VISIBILITY_LABEL="Visibility" +COM_COMPONENTBUILDER_CLEAR="Clear" COM_COMPONENTBUILDER_CLEAR_TMP="Clear tmp" COM_COMPONENTBUILDER_CLONE="Clone" COM_COMPONENTBUILDER_CLONE_FAILED="Clone failed!" @@ -1684,7 +1669,7 @@ COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_ACCESS_DESC="Allows the users in thi COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_OPTIONS="Batch process the selected Components Admin Views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_TIP="All changes will be applied to all selected Components Admin Views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_USE="Components Admin Views Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components admin views" +COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_CREATE="Components Admin Views Create" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create components admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_DELETE="Components Admin Views Delete" @@ -1700,7 +1685,7 @@ COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the users in t COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_STATE="Components Admin Views Edit State" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_VERSION="Components Admin Views Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components admin views" +COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_ARCHIVED="%s Components Admin Views archived." COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_ARCHIVED_1="%s Component Admin Views archived." COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_CHECKED_IN_0="No Component Admin Views successfully checked in." @@ -1720,13 +1705,14 @@ COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNFEATURED="%s Components Ad COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNFEATURED_1="%s Component Admin Views unfeatured." COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNPUBLISHED="%s Components Admin Views unpublished." COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNPUBLISHED_1="%s Component Admin Views unpublished." +COM_COMPONENTBUILDER_COMPONENTS_BR_SMALLDISABLED_SOONSMALL="Components
(disabled... soon!)" COM_COMPONENTBUILDER_COMPONENTS_CONFIG="Components Config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_ACCESS="Components Config Access" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_ACCESS_DESC="Allows the users in this group to access access components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_OPTIONS="Batch process the selected Components Config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_TIP="All changes will be applied to all selected Components Config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_USE="Components Config Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components config" +COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_CREATE="Components Config Create" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_CREATE_DESC="Allows the users in this group to create create components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_DELETE="Components Config Delete" @@ -1742,7 +1728,7 @@ COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_OWN_DESC="Allows the users in this g COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_STATE="Components Config Edit State" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_STATE_DESC="Allows the users in this group to update the state of the component config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_VERSION="Components Config Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components config" +COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_N_ITEMS_ARCHIVED="%s Components Config archived." COM_COMPONENTBUILDER_COMPONENTS_CONFIG_N_ITEMS_ARCHIVED_1="%s Component Config archived." COM_COMPONENTBUILDER_COMPONENTS_CONFIG_N_ITEMS_CHECKED_IN_0="No Component Config successfully checked in." @@ -1768,7 +1754,7 @@ COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_ACCESS_DESC="Allows the users COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_OPTIONS="Batch process the selected Components Custom Admin Menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_TIP="All changes will be applied to all selected Components Custom Admin Menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_USE="Components Custom Admin Menus Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components custom admin menus" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_CREATE="Components Custom Admin Menus Create" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_CREATE_DESC="Allows the users in this group to create create components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_DELETE="Components Custom Admin Menus Delete" @@ -1784,7 +1770,7 @@ COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_OWN_DESC="Allows the use COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_STATE="Components Custom Admin Menus Edit State" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_VERSION="Components Custom Admin Menus Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components custom admin menus" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_N_ITEMS_ARCHIVED="%s Components Custom Admin Menus archived." COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_N_ITEMS_ARCHIVED_1="%s Component Custom Admin Menus archived." COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_N_ITEMS_CHECKED_IN_0="No Component Custom Admin Menus successfully checked in." @@ -1810,7 +1796,7 @@ COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_ACCESS_DESC="Allows the users COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_OPTIONS="Batch process the selected Components Custom Admin Views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_TIP="All changes will be applied to all selected Components Custom Admin Views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_USE="Components Custom Admin Views Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components custom admin views" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_CREATE="Components Custom Admin Views Create" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_DELETE="Components Custom Admin Views Delete" @@ -1826,7 +1812,7 @@ COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the use COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_STATE="Components Custom Admin Views Edit State" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_VERSION="Components Custom Admin Views Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components custom admin views" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_N_ITEMS_ARCHIVED="%s Components Custom Admin Views archived." COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_N_ITEMS_ARCHIVED_1="%s Component Custom Admin Views archived." COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_N_ITEMS_CHECKED_IN_0="No Component Custom Admin Views successfully checked in." @@ -1852,7 +1838,7 @@ COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_ACCESS_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_OPTIONS="Batch process the selected Components Dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_TIP="All changes will be applied to all selected Components Dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_USE="Components Dashboard Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components dashboard" +COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_CREATE="Components Dashboard Create" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_CREATE_DESC="Allows the users in this group to create create components dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_DELETE="Components Dashboard Delete" @@ -1868,7 +1854,7 @@ COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_OWN_DESC="Allows the users in thi COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_STATE="Components Dashboard Edit State" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_STATE_DESC="Allows the users in this group to update the state of the component dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_VERSION="Components Dashboard Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components dashboard" +COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_N_ITEMS_ARCHIVED="%s Components Dashboard archived." COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_N_ITEMS_ARCHIVED_1="%s Component Dashboard archived." COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_N_ITEMS_CHECKED_IN_0="No Component Dashboard successfully checked in." @@ -1894,7 +1880,7 @@ COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_ACCESS_DESC="Allows the users in t COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_OPTIONS="Batch process the selected Components Files & Folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_TIP="All changes will be applied to all selected Components Files & Folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_USE="Components Files Folders Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components files folders" +COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_CREATE="Components Files Folders Create" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_CREATE_DESC="Allows the users in this group to create create components files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_DELETE="Components Files Folders Delete" @@ -1910,7 +1896,7 @@ COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_STATE="Components Files Folders Edit State" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_VERSION="Components Files Folders Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components files folders" +COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_N_ITEMS_ARCHIVED="%s Components Files & Folders archived." COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_N_ITEMS_ARCHIVED_1="%s Component Files & Folders archived." COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_N_ITEMS_CHECKED_IN_0="No Component Files & Folders successfully checked in." @@ -1936,7 +1922,7 @@ COM_COMPONENTBUILDER_COMPONENTS_MODULES_ACCESS_DESC="Allows the users in this gr COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_OPTIONS="Batch process the selected Components Modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_TIP="All changes will be applied to all selected Components Modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_USE="Components Modules Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components modules" +COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_CREATE="Components Modules Create" COM_COMPONENTBUILDER_COMPONENTS_MODULES_CREATE_DESC="Allows the users in this group to create create components modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_DELETE="Components Modules Delete" @@ -1952,7 +1938,7 @@ COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_STATE="Components Modules Edit State" COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_STATE_DESC="Allows the users in this group to update the state of the component modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_VERSION="Components Modules Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components modules" +COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_N_ITEMS_ARCHIVED="%s Components Modules archived." COM_COMPONENTBUILDER_COMPONENTS_MODULES_N_ITEMS_ARCHIVED_1="%s Component Modules archived." COM_COMPONENTBUILDER_COMPONENTS_MODULES_N_ITEMS_CHECKED_IN_0="No Component Modules successfully checked in." @@ -1978,7 +1964,7 @@ COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_ACCESS_DESC="Allows the users in th COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_OPTIONS="Batch process the selected Components mysql Tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_TIP="All changes will be applied to all selected Components mysql Tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_USE="Components Mysql Tweaks Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components mysql tweaks" +COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_CREATE="Components Mysql Tweaks Create" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_CREATE_DESC="Allows the users in this group to create create components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_DELETE="Components Mysql Tweaks Delete" @@ -1994,7 +1980,7 @@ COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_STATE="Components Mysql Tweaks Edit State" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION="Components Mysql Tweaks Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components mysql tweaks" +COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_ARCHIVED="%s Components mysql Tweaks archived." COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_ARCHIVED_1="%s Component mysql Tweaks archived." COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_N_ITEMS_CHECKED_IN_0="No Component mysql Tweaks successfully checked in." @@ -2020,7 +2006,7 @@ COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS_DESC="Allows the users in th COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_OPTIONS="Batch process the selected Components Placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_TIP="All changes will be applied to all selected Components Placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE="Components Placeholders Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE="Components Placeholders Create" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_DELETE="Components Placeholders Delete" @@ -2036,7 +2022,7 @@ COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE="Components Placeholders Edit State" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION="Components Placeholders Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_ARCHIVED="%s Components Placeholders archived." COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_ARCHIVED_1="%s Component Placeholders archived." COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_N_ITEMS_CHECKED_IN_0="No Component Placeholders successfully checked in." @@ -2062,7 +2048,7 @@ COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_ACCESS_DESC="Allows the users in this gr COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_OPTIONS="Batch process the selected Components Plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_TIP="All changes will be applied to all selected Components Plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_USE="Components Plugins Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components plugins" +COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_CREATE="Components Plugins Create" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_CREATE_DESC="Allows the users in this group to create create components plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_DELETE="Components Plugins Delete" @@ -2078,7 +2064,7 @@ COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_STATE="Components Plugins Edit State" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_VERSION="Components Plugins Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components plugins" +COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_N_ITEMS_ARCHIVED="%s Components Plugins archived." COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_N_ITEMS_ARCHIVED_1="%s Component Plugins archived." COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_N_ITEMS_CHECKED_IN_0="No Component Plugins successfully checked in." @@ -2104,7 +2090,7 @@ COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_OPTIONS="Batch process the selected Components Site Views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_TIP="All changes will be applied to all selected Components Site Views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE="Components Site Views Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components site views" +COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_CREATE="Components Site Views Create" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_CREATE_DESC="Allows the users in this group to create create components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_DELETE="Components Site Views Delete" @@ -2120,7 +2106,7 @@ COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_OWN_DESC="Allows the users in th COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_STATE="Components Site Views Edit State" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_VERSION="Components Site Views Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components site views" +COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_N_ITEMS_ARCHIVED="%s Components Site Views archived." COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_N_ITEMS_ARCHIVED_1="%s Component Site Views archived." COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_N_ITEMS_CHECKED_IN_0="No Component Site Views successfully checked in." @@ -2146,7 +2132,7 @@ COM_COMPONENTBUILDER_COMPONENTS_UPDATES_ACCESS_DESC="Allows the users in this gr COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_OPTIONS="Batch process the selected Components Updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_TIP="All changes will be applied to all selected Components Updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_USE="Components Updates Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components updates" +COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_CREATE="Components Updates Create" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_CREATE_DESC="Allows the users in this group to create create components updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_DELETE="Components Updates Delete" @@ -2162,7 +2148,7 @@ COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_STATE="Components Updates Edit State" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the component updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_VERSION="Components Updates Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components updates" +COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_N_ITEMS_ARCHIVED="%s Components Updates archived." COM_COMPONENTBUILDER_COMPONENTS_UPDATES_N_ITEMS_ARCHIVED_1="%s Component Updates archived." COM_COMPONENTBUILDER_COMPONENTS_UPDATES_N_ITEMS_CHECKED_IN_0="No Component Updates successfully checked in." @@ -2531,8 +2517,7 @@ COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_MODIFIED_DATE_DESC="The date t COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_CODE_DESCRIPTION="Add Name in Code Here" COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_CODE_HINT="codename" -COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_CODE_LABEL="Name in Code
-Naming Conventions" +COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_CODE_LABEL="Name in Code
Naming Conventions" COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_CODE_MESSAGE="Error! Please add name in code here." COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_DESCRIPTION="Enter Name Here" COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_HINT="Name Here" @@ -2826,11 +2811,7 @@ COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HEADER_DESCRIPTION="Enter Header Here" COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HEADER_HINT="Header Here" COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HEADER_LABEL="Header" COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HEADER_MESSAGE="Error! Please add header here." -COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HTML_HINT="// Add the tab HTML here. -// To access php values methodname->value; ?> -// Note the convention, if in the PHP area above you added a method called getMethodName() -// Then [MethodName] becomes a class variable called $this->methodname -// Which will hold the value/s your method returned." +COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HTML_HINT="// Add the tab HTML here.// To access php values methodname->value; ?>// Note the convention, if in the PHP area above you added a method called getMethodName()// Then [MethodName] becomes a class variable called $this->methodname// Which will hold the value/s your method returned." COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_HTML_LABEL="HTML" COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_ID="Id" COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_JOOMLA_COMPONENT_DESCRIPTION="Select a Joomla Component" @@ -2906,42 +2887,7 @@ COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_ADD_FOLDERS_DESCRIPTION="You c COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_ADD_FOLDERS_FULLPATH_DESCRIPTION="You can any folders to the component, by using the full system path. Example: /home/user/folder (make sure that php has permission to read the folder)
Please note that you can also use constant paths in your full path (directly without quotes), this is highly recommended to insure portability.
To see a list of constant paths please read the notes below. Example: JPATH_ROOT/folder or JPATH_ROOT/components/com_yourcomponentname/helpers/folder" COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_ADD_FOLDERS_FULLPATH_LABEL="Adding Folders" COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" -COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_HOW_TO_CLONE_DESCRIPTION="There has often been the case that we have two or more components_files_folders that should be exactly the same. Just selecting that component_files_folders and clicking save, will overwrite this component_files_folders with that selected component_files_folders data." COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_HOW_TO_CLONE_LABEL="How to clone another component_files_folders's values into this one." @@ -3228,8 +3174,12 @@ COM_COMPONENTBUILDER_COMPONENT_UPDATES_YES="Yes" COM_COMPONENTBUILDER_CONCATENATE="Concatenate" COM_COMPONENTBUILDER_CONDITIONS="Conditions" COM_COMPONENTBUILDER_CONFIG_ACTIVE="Active" +COM_COMPONENTBUILDER_CONFIG_ADD_CUSTOM_GITEA_URL_DESCRIPTION="Switch to set your own Gitea url." +COM_COMPONENTBUILDER_CONFIG_ADD_CUSTOM_GITEA_URL_LABEL="Target Gitea URL" COM_COMPONENTBUILDER_CONFIG_ADD_MENU_PREFIX_DESCRIPTION="Would you like to add a prefix to the Joomla menu name of your components" COM_COMPONENTBUILDER_CONFIG_ADD_MENU_PREFIX_LABEL="Add Menu Prefix" +COM_COMPONENTBUILDER_CONFIG_ADD_PLACEHOLDERS_DESCRIPTION="Should JCB insert the custom code placeholders? This is only applicable if this component has custom code." +COM_COMPONENTBUILDER_CONFIG_ADD_PLACEHOLDERS_LABEL="Add Custom Code Placeholders" COM_COMPONENTBUILDER_CONFIG_ADMIN_CUSTOM_TABS_TABS="Admin Custom Tabs (tabs)" COM_COMPONENTBUILDER_CONFIG_ADMIN_FIELDS_ADDFIELDS="Admin Fields (addfields)" COM_COMPONENTBUILDER_CONFIG_ADMIN_FIELDS_CONDITIONS_ADDCONDITIONS="Admin Fields Conditions (addconditions)" @@ -3239,9 +3189,8 @@ COM_COMPONENTBUILDER_CONFIG_ALPHANUMERIC="Alphanumeric" COM_COMPONENTBUILDER_CONFIG_ALPHANUMERICDOT="Alphanumeric+dot" COM_COMPONENTBUILDER_CONFIG_API_DESCRIPTION="This User will be used to log the API call." COM_COMPONENTBUILDER_CONFIG_API_LABEL="API User" -COM_COMPONENTBUILDER_CONFIG_ASSETS_TABLE_FIX_DESCRIPTION="How to apply the assets table fix in JCB.
-SQL (add&remove) this is the default which adds the SQL fix and removes it once the component is uninstalled.
-Intelligent (add&remove+if) same as default, but on uninstall will only remove this fix if no other component needs it. Note that this option will only work with other components that also use the intelligent path." +COM_COMPONENTBUILDER_CONFIG_APPROVED_PATHS_LABEL="Super Powers Repository Paths" +COM_COMPONENTBUILDER_CONFIG_ASSETS_TABLE_FIX_DESCRIPTION="How to apply the assets table fix in JCB.
SQL (add&remove) this is the default which adds the SQL fix and removes it once the component is uninstalled.
Intelligent (add&remove+if) same as default, but on uninstall will only remove this fix if no other component needs it. Note that this option will only work with other components that also use the intelligent path." COM_COMPONENTBUILDER_CONFIG_ASSETS_TABLE_FIX_LABEL="Assets Table Fix" COM_COMPONENTBUILDER_CONFIG_AUTHOR="Author Info" COM_COMPONENTBUILDER_CONFIG_AUTHOR_EMAIL_DESC="The email address of the author of this component." @@ -3250,58 +3199,7 @@ COM_COMPONENTBUILDER_CONFIG_AUTHOR_NAME_DESC="The name of the author of this com COM_COMPONENTBUILDER_CONFIG_AUTHOR_NAME_LABEL="Author Name" COM_COMPONENTBUILDER_CONFIG_AUTO_BACKUP="Auto Backup" COM_COMPONENTBUILDER_CONFIG_AUTO_LOAD="Auto" -COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_DESCRIPTION="You can run a cronjob that will backup all your components as they are mapped in JCB.

USE THE FOLLOWING: loading...

Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677 -" +COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_DESCRIPTION="You can run a cronjob that will backup all your components as they are mapped in JCB.

USE THE FOLLOWING: loading...

Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677" COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_LABEL="Backup JCB Mapped Components" COM_COMPONENTBUILDER_CONFIG_BACKUP_DESCRIPTION="Should the zipped package of the component be moved to the local backup and remote sales server? This is only applicable if this component has those values set." COM_COMPONENTBUILDER_CONFIG_BACKUP_EMAIL_DESCRIPTION="Enter the email where the backup key should be send. It will only send an email if a key change is detected, and not on every backup." @@ -3321,6 +3219,8 @@ COM_COMPONENTBUILDER_CONFIG_BASIC_KEY_DESC="Set the basic local key here." COM_COMPONENTBUILDER_CONFIG_BASIC_KEY_LABEL="Basic Key" COM_COMPONENTBUILDER_CONFIG_BASIC_KEY_NOTE_DESC="When using the basic encryption please use set a 32 character passphrase.
Never change this passphrase once it is set! DATA WILL GET CORRUPTED IF YOU DO!" COM_COMPONENTBUILDER_CONFIG_BASIC_KEY_NOTE_LABEL="Basic Encryption" +COM_COMPONENTBUILDER_CONFIG_BRANCH_HINT="[branch]" +COM_COMPONENTBUILDER_CONFIG_BRANCH_LABEL="Branch" COM_COMPONENTBUILDER_CONFIG_BUILDER_GIF_SIZE_DESCRIPTION="Select the artwork you would like to show during compilation of your projects in the compiler area." COM_COMPONENTBUILDER_CONFIG_BUILDER_GIF_SIZE_LABEL="Compiler Artwork Options" COM_COMPONENTBUILDER_CONFIG_CHECK_TIMER_DESC="Set the intervals for the auto checkin fuction of tables that checks out the items to an user." @@ -3341,12 +3241,12 @@ COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_LABEL="Compiler Folder Path" COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_MESSAGE="Error! Please add some text here." COM_COMPONENTBUILDER_CONFIG_COMPILER_PLUGIN_DESCRIPTION="Select the plugin you would like to use in JCB's compiler" COM_COMPONENTBUILDER_CONFIG_COMPILER_PLUGIN_LABEL="Activate Compiler Plugins" -COM_COMPONENTBUILDER_CONFIG_COMPONENT="Component" COM_COMPONENTBUILDER_CONFIG_COMPONENT_ADMIN_VIEWS_ADDADMIN_VIEWS="Component Admin Views (addadmin_views)" COM_COMPONENTBUILDER_CONFIG_COMPONENT_CUSTOM_ADMIN_MENUS_ADDCUSTOMMENUS="Component Custom Admin Menus (addcustommenus)" COM_COMPONENTBUILDER_CONFIG_COMPONENT_CUSTOM_ADMIN_VIEWS_ADDCUSTOM_ADMIN_VIEWS="Component Custom Admin Views (addcustom_admin_views)" COM_COMPONENTBUILDER_CONFIG_COMPONENT_DASHBOARD_DASHBOARD_TAB="Component Dashboard (dashboard_tab)" -COM_COMPONENTBUILDER_CONFIG_COMPONENT_LABEL="Component" +COM_COMPONENTBUILDER_CONFIG_COMPONENT_ID="Component Id" +COM_COMPONENTBUILDER_CONFIG_COMPONENT_ID_LABEL="Component" COM_COMPONENTBUILDER_CONFIG_COMPONENT_SITE_VIEWS_ADDSITE_VIEWS="Component Site Views (addsite_views)" COM_COMPONENTBUILDER_CONFIG_COMPONENT_UPDATES_VERSION_UPDATE="Component Updates (version_update)" COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_DESCRIPTION="Here you can set the path to where all components are backed up to." @@ -3357,10 +3257,18 @@ COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_SERVER_DESCRIPTION="Select your backu COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_SERVER_LABEL="Cronjob Backup Server" COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_TYPE_DESCRIPTION="Select how you would like to backup JCB" COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_TYPE_LABEL="Cronjob Backup type" +COM_COMPONENTBUILDER_CONFIG_CUSTOMGITEA="custom.gitea" COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_DESCRIPTION="Here you can set the path to the custom folder" COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_HINT="/home/user/custom" COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_LABEL="Custom Folder Path" COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_MESSAGE="Error! Please add folder path here." +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_TOKEN_DESCRIPTION="This token is used to access private repositories as needed to get the super powers." +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_TOKEN_HINT="Gitea Access Tokens" +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_TOKEN_LABEL="Gitea Access Token
Get token from your Gitea at: /user/settings/applications." +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_URL_DESCRIPTION="Enter Gitea Address" +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_URL_HINT="https://git.vdm.dev" +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_URL_LABEL="Gitea URL" +COM_COMPONENTBUILDER_CONFIG_CUSTOM_GITEA_URL_MESSAGE="Error! Please add website here." COM_COMPONENTBUILDER_CONFIG_DEFAULT="Default" COM_COMPONENTBUILDER_CONFIG_DEVELOPMENT_METHOD="Development Method" COM_COMPONENTBUILDER_CONFIG_DEVELOPMENT_METHOD_DESCRIPTION="Select what development method you would like to use." @@ -3416,34 +3324,7 @@ COM_COMPONENTBUILDER_CONFIG_EVERY_MINUTE="Every Minute" COM_COMPONENTBUILDER_CONFIG_EVERY_SESSION="Every Session" COM_COMPONENTBUILDER_CONFIG_EVERY_WEEK="Every Week" COM_COMPONENTBUILDER_CONFIG_EXPANSION="Expansion" -COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_DESCRIPTION="You must run a cronjob that will trigger the expansion events for JCB.

USE THE FOLLOWING: loading...

Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677 -" +COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_DESCRIPTION="You must run a cronjob that will trigger the expansion events for JCB.

USE THE FOLLOWING: loading...

Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677" COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_LABEL="Expansion Cronjob" COM_COMPONENTBUILDER_CONFIG_EXPANSION_DESCRIPTION="Properties for this field" COM_COMPONENTBUILDER_CONFIG_EXPANSION_LABEL="Expansion" @@ -3491,6 +3372,7 @@ COM_COMPONENTBUILDER_CONFIG_GITEA_TOKEN_LABEL="VDM Access Token
Get COM_COMPONENTBUILDER_CONFIG_GITHUB_ACCESS_TOKEN_DESCRIPTION="This is only needed when you are on a shared IP or/and have reached the public free limit of API queries to gitHub. So unless you have seen some kind of error that directed you here to add an access token you can just ignore this field." COM_COMPONENTBUILDER_CONFIG_GITHUB_ACCESS_TOKEN_HINT="OAUTH-TOKEN" COM_COMPONENTBUILDER_CONFIG_GITHUB_ACCESS_TOKEN_LABEL="gitHub Access Token
Check https://developer.github.com/v3/#authentication for more info." +COM_COMPONENTBUILDER_CONFIG_GITVDMDEV="git.vdm.dev" COM_COMPONENTBUILDER_CONFIG_GIT_FOLDER_PATH_DESCRIPTION="Here you can set the path to the git folder." COM_COMPONENTBUILDER_CONFIG_GIT_FOLDER_PATH_HINT="/home/user/git" COM_COMPONENTBUILDER_CONFIG_GIT_FOLDER_PATH_LABEL="Git Folder Path" @@ -3499,6 +3381,7 @@ COM_COMPONENTBUILDER_CONFIG_GLOBAL="Global" COM_COMPONENTBUILDER_CONFIG_GLOBAL_DESC="The Global Parameters" COM_COMPONENTBUILDER_CONFIG_GLOBAL_LABEL="Global" COM_COMPONENTBUILDER_CONFIG_GRADIANT_LOAD="Gradient" +COM_COMPONENTBUILDER_CONFIG_HIDE="Hide" COM_COMPONENTBUILDER_CONFIG_IMPORT_GUID_ONLY_DESCRIPTION="Force that all JCB package import (search for local items) is done with GUID value only." COM_COMPONENTBUILDER_CONFIG_IMPORT_GUID_ONLY_LABEL="Import by GUID only!" COM_COMPONENTBUILDER_CONFIG_INACTIVE="Inactive" @@ -3515,9 +3398,17 @@ COM_COMPONENTBUILDER_CONFIG_JCB_POWERS_PATH_LABEL="JCB Powers Path
e COM_COMPONENTBUILDER_CONFIG_JCB_POWERS_PATH_MESSAGE="Error! Please add folder path here." COM_COMPONENTBUILDER_CONFIG_JOOMLA_MODULE_UPDATES_VERSION_UPDATE="Joomla Module Updates (version_update)" COM_COMPONENTBUILDER_CONFIG_JOOMLA_PLUGIN_UPDATES_VERSION_UPDATE="Joomla Plugin Updates (version_update)" +COM_COMPONENTBUILDER_CONFIG_JQUERY_LOAD="Load jQuery" +COM_COMPONENTBUILDER_CONFIG_JQUERY_LOAD_DESC="Would you like to load the Joomla jQuery Framework?" +COM_COMPONENTBUILDER_CONFIG_JQUERY_LOAD_LABEL="Load Joomla jQuery" +COM_COMPONENTBUILDER_CONFIG_JQUERY_REMOVE="Remove jQuery" COM_COMPONENTBUILDER_CONFIG_LANGUAGE_LABEL="Language" COM_COMPONENTBUILDER_CONFIG_LAYOUT_LABEL="Layout" COM_COMPONENTBUILDER_CONFIG_LOCAL_FOLDER="Local Folder" +COM_COMPONENTBUILDER_CONFIG_LOCAL_POWERS_REPOSITORY_PATH_DESCRIPTION="Here you can set the path to the super powers local repository folder, where [layer:core] and all targeted [layer:own] sub paths will be placed with their selective [switch:approved] powers." +COM_COMPONENTBUILDER_CONFIG_LOCAL_POWERS_REPOSITORY_PATH_HINT="/home/power" +COM_COMPONENTBUILDER_CONFIG_LOCAL_POWERS_REPOSITORY_PATH_LABEL="Local Powers Repository Path" +COM_COMPONENTBUILDER_CONFIG_LOCAL_POWERS_REPOSITORY_PATH_MESSAGE="Error! Please add some text here." COM_COMPONENTBUILDER_CONFIG_MAILER_DESCRIPTION="Select what mailer you would like to use to send emails." COM_COMPONENTBUILDER_CONFIG_MAILER_LABEL="Mailer" COM_COMPONENTBUILDER_CONFIG_MAILONLINE_DESCRIPTION="Warning this will stop all emails from going out." @@ -3526,17 +3417,9 @@ COM_COMPONENTBUILDER_CONFIG_MAIL_CONFIGURATION="Mail Configuration" COM_COMPONENTBUILDER_CONFIG_MANAGE_JCB_PACKAGE_DIRECTORIES_DESCRIPTION="Here you can choose to manually select what directories should show, or turn them off altogether." COM_COMPONENTBUILDER_CONFIG_MANAGE_JCB_PACKAGE_DIRECTORIES_LABEL="Manage JCB Package Directories" COM_COMPONENTBUILDER_CONFIG_MANUAL_SELECTION="Manual Selection" -COM_COMPONENTBUILDER_CONFIG_MEDIUM_KEY_DESC="Set the full path to where the key file must be stored. Make sure it is behind the root folder of your website, so that it is not public accessible." -COM_COMPONENTBUILDER_CONFIG_MEDIUM_KEY_LABEL="Medium Key (Path)" -COM_COMPONENTBUILDER_CONFIG_MEDIUM_KEY_NOTE_DESC="When using the medium encryption option, the system generates its own key and stores it in a file at the folder/path you set here.
Never change this key once it is set, or remove the key file! DATA WILL GET CORRUPTED IF YOU DO! Also make sure the full path to where the the key file should be stored, is behind the root folder of your website/system, so that it is not public accessible. Making a backup of this key file over a secure connection is recommended!" -COM_COMPONENTBUILDER_CONFIG_MEDIUM_KEY_NOTE_LABEL="Medium Encryption" -COM_COMPONENTBUILDER_CONFIG_MEDIUM_KEY_PATH_ERROR="Medium key path (for encryption of various fields) does not exist, or is not writable. Please check the path and update it in the global option of this component." COM_COMPONENTBUILDER_CONFIG_MENU_PREFIX_DESCRIPTION="Add the prefix you would like to use. Make sure that it is HTML Character Entities since it is being used in XML." COM_COMPONENTBUILDER_CONFIG_MENU_PREFIX_HINT="»" -COM_COMPONENTBUILDER_CONFIG_MENU_PREFIX_LABEL="Prefix
-Check out these lists:
-Char-ref or -Emoji
" +COM_COMPONENTBUILDER_CONFIG_MENU_PREFIX_LABEL="Prefix
Check out these lists:
Char-ref or Emoji
" COM_COMPONENTBUILDER_CONFIG_MENU_PREFIX_MESSAGE="Error! Please add some text here." COM_COMPONENTBUILDER_CONFIG_MINIFY_DESCRIPTION="Should the JavaScript be minified when compiled." COM_COMPONENTBUILDER_CONFIG_MINIFY_LABEL="Minify JS" @@ -3549,63 +3432,39 @@ COM_COMPONENTBUILDER_CONFIG_NOTE_COMPILER_FOLDER_PATH_DESCRIPTION="The compiler COM_COMPONENTBUILDER_CONFIG_NOTE_COMPILER_FOLDER_PATH_LABEL="Moving The Compiler Folder" COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_DESCRIPTION="The custom folder is where all files and folders that you would like to include in your components are stored, the default location is [administrator/components/com_componentbuilder/custom]. You can move this folder by adding your own path here. Remember to move the content of the default custom folder to this new location." COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_LABEL="Moving The Custom Folder" -COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_DESCRIPTION="

This method is basically the way JCB has always worked by default.

-

So once you have made changes, you go to the compiler view and compile your component. Then you have the option to install and/or distribute the Joomla installation package.

This option will always be active to those with permission to access the compiler. You can change this permission in the Permissions tab with the option called Compiler Access.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_GITEA_URL_DESCRIPTION="

Each JCB system can only target one Gitea system at a time. Setting your own Gitea URL means you are decoupling from the git.vdm.dev system and will no longer be loading your super powers from the git.vdm.dev system!

This will affect the [layers:all], so JCB will not search for any Powers on the git.vdm.dev system at all.

This option is ideal for managing your own Core Super Powers and your own private Super Powers on your own, or another Gitea System, and allows you to use the Super Power integration completely independent from VDM. Our hope is that this gives you enough freedom and liberty to use our system or your own. Let's decentralize our systems so that we can start focusing on what we are building, and not be worried that some large conglomerate is stealing our ideas and building their empires on our hard work.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_GITEA_URL_LABEL="Decentralize Super Powers, Yea!" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_DESCRIPTION="

This method is basically the way JCB has always worked by default.

So once you have made changes, you go to the compiler view and compile your component. Then you have the option to install and/or distribute the Joomla installation package.

This option will always be active to those with permission to access the compiler. You can change this permission in the Permissions tab with the option called Compiler Access.

" COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_LABEL="Default Development Method" -COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="

This method adds easy compile and install of multiple components to the current Joomla system. This automated action is called expansion.

-

Expansion can be achieved in two ways.

-

Button Expansion Option

-

The first and most common way is to click on any of the Run Expansion buttons found at the top of some of the JCB admin views.

-

Cronjob Expansion Option

-

The second is by running a cronjob as explained bellow the area of selection in this tab. So you do not need to manually compile and install the selected components any more, the system does all that automatically for you. The latency of the workflow is based on your cronjob frequency and the size of your component.

-

Expansion is pause for a component in a few ways, one by actually checking out/opening the Joomla Component view of the component in JCB, or changing the state to unpublish, archive or trashed, or simply remove if from the list below.

-

The Expansion method is there to speedup development testing.

-

Below you should set the behaviour of a selected set of components that will be auto build and installed when the expansion module is run.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="

This method adds easy compile and install of multiple components to the current Joomla system. This automated action is called expansion.

Expansion can be achieved in two ways.

Button Expansion Option

The first and most common way is to click on any of the Run Expansion buttons found at the top of some of the JCB admin views.

Cronjob Expansion Option

The second is by running a cronjob as explained bellow the area of selection in this tab. So you do not need to manually compile and install the selected components any more, the system does all that automatically for you. The latency of the workflow is based on your cronjob frequency and the size of your component.

Expansion is pause for a component in a few ways, one by actually checking out/opening the Joomla Component view of the component in JCB, or changing the state to unpublish, archive or trashed, or simply remove if from the list below.

The Expansion method is there to speedup development testing.

Below you should set the behaviour of a selected set of components that will be auto build and installed when the expansion module is run.

" COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_LABEL="Expansion Development Method" -COM_COMPONENTBUILDER_CONFIG_NOTE_DKIM_USE_DESCRIPTION="

Using the below details, you need to configure your DNS by adding a TXT record on your domain:

-" +COM_COMPONENTBUILDER_CONFIG_NOTE_DKIM_USE_DESCRIPTION="

Using the below details, you need to configure your DNS by adding a TXT record on your domain:

" COM_COMPONENTBUILDER_CONFIG_NOTE_DKIM_USE_LABEL="Server Configuration" COM_COMPONENTBUILDER_CONFIG_NOTE_GIT_FOLDER_PATH_DESCRIPTION="You must set the folder where all the components should be deployed for git. You will have to still do your git commit and other git commands yourself. Each component will create their own folder inside this git folder." COM_COMPONENTBUILDER_CONFIG_NOTE_GIT_FOLDER_PATH_LABEL="Adding git to your compiler method" COM_COMPONENTBUILDER_CONFIG_NOTE_LANGUAGE_GLOBAL_DESCRIPTION="

Here you can select the main/global language that you are using to build components. This is the language you use for field label, descriptions. view names and well everything language related across the whole JCB build interface.

You should not change this global language option once you have set it as this will cause major confusion, that will cause languages to get mixed-up very badly.

Also make sure that if you import a JCB package from other developers that they use the same language as you selected here.

At this time best practice is to use en-GB since this has been the default language since the start of the project and will remain VDM's default for years to come, and if you import our JCB packages all the source language strings are in en-GB. English GB is also the source/main language for Joomla.

" COM_COMPONENTBUILDER_CONFIG_NOTE_LANGUAGE_GLOBAL_LABEL="Global Language Source" +COM_COMPONENTBUILDER_CONFIG_NOTE_NOT_READY_SUPER_POWERS_LABEL="THIS AREA IS STILL IN DEVELOPMENT, WE WILL REMOVE THIS NOTICE WHEN ITS READY TO USE." +COM_COMPONENTBUILDER_CONFIG_NOTE_POWERS_REPOSITORY_PATH_DESCRIPTION="The powers repository local path is where [layer:core] and all [layer:own] powers are placed. So you can with git add your powers to your own profile on https://git.vdm.dev/[username]/power for easy reuse between projects." +COM_COMPONENTBUILDER_CONFIG_NOTE_POWERS_REPOSITORY_PATH_LABEL="Local Powers Repository Path" +COM_COMPONENTBUILDER_CONFIG_NOTE_SUPER_POWERS_DESCRIPTION="

Joomla Component Builder (JCB), has super powers. Which is another way of saying it now allows for powers to be pulled in from a global array of areas, over which you have full control. This allows for easy sharing of your powers between your JCB instances with your own power repositories on https://git.vdm.dev/[username]/my-powers. While at the same time be able to use the JCB core powers where needed.

Let's explain:
This feature called super-powers, manages powers by use of layers, events, tasks, methods, switches, and algorithms that all work in combination of different ways to achieve super powers.

The [powers] are:

  • [guid] => Each power has a global unique identifier used to control the power global identity. This [power:guid] looks like this: b836c1b1-b6b1-44f7-b8a2-9a763a4185b1
  • [code] => The actual code of the power that is found in a PHP file
  • [settings] => The settings define the power details, relationships, and more. They are stored in a Json formatted file in [layer:repo] and/or [layer:local] and/or as column values in the [layer:database]
The [layers] are:
  • [database] This JCB instance's Database
  • [repo] The https://git.vdm.dev/ git website that holds all repos, and which is managed by Vast Development Method
  • [core] The core super-power repo of JCB https://git.vdm.dev/joomla/super-powers (this target can be changed in global options)
  • [own] Your own super-powers repos https://git.vdm.dev/[username]/my-powers (sub-paths)
  • [local] Local path, and its sub-paths that hold [core] and [own] repositories.
The [events] are:
  • [compile] Compilation of a component
  • [sync] Synchronisation of selected powers with [algorithm:cascading]
  • [init] Uploads all powers from all active [layers] into [layer:database] if not already exist in [layer:database]
  • [reset] Force synchronisation of selected powers with [layer:core]
The [tasks] are:
  • [get] To get powers from any of the layers
  • [set] To set powers to database or local paths
The [methods] are:
  • [auto] When JCB automatically does this for you
  • [manual] When you must manually do something
The [switches] are:
  • [activate] This switch activates super-powers, and allows for [layer:local] path to be set
  • [token] This is the VDM access token from the global tab.
  • [super] This switch allows for [layer:own] paths to be set
  • [approved] This switch allows a power to be added to a [layer:core] or [layer:own] paths

The [algorithms] are:
  • [cascading] The is the way in which JCB [task:get] a power during the [events] so that it can use the power in your component, and store in [layer:database]

These terminologies and ideas are what you need to remember whenever you read any of the comments and other information about super-powers in JCB.

JCB uses powers as the foundation of all it builds. You can build things with JCB without knowing how to use or work with powers. But JCB cannot build anything without powers. That means JCB needs to load powers from the [layer:core] and usually will do this whenever an [event] is triggered based on the [algorithm:cascading].

All these events can possibly move powers into your [layer:database]. These [events] have the [method:auto] behaviour, and therefore we make use of the [algorithm:cascading] that allows for overriding any power in any way you like. Beware that divergence from the core powers may have side effects and therefore should only be done with knowledge and full understanding on your part.

Let's Explain the [algorithm:cascading]
During [events] we must [auto] load powers, and so there is a search path for each event.

The [event:compile] when building your component, here is the [algorithm:cascading]:

  1. [layer:database]
  2. [layer:local IF switch:activate AND switch:approved]
  3. [layer:own IF switch:token AND switch:activate AND switch:super AND switch:approved]
  4. [layer:core]

This means, that if JCB gets a [power:guid] in the [layer:database] it stops the search and uses that found power. But if not, it will continue until it finds the power, or it will show an error that the power could not be found. Once it finds the power, it will make sure that the power is in [layer:database], and if [layer:local] is active, it will update those as well as determined by the approved path selection of each power.

The [event:sync] when the sync button is clicked, here is the [algorithm:cascading]:

  1. [layer:own IF switch:token AND switch:activate AND switch:super AND switch:approved]
  2. [layer:local IF switch:activate AND switch:approved]
  3. [layer:core]

This means, that if JCB gets a [power:guid] in any of the targeted [layer:own] it stops the search for that power at the first instance it finds that power. Then JCB will update your [layer:database] with the found power, irrespective of modify or creation date. The [power:guid] is used as the key, and should JCB therefore have a power in any of your [layer:own] it will override the [layer:core] and [layer:local] version of any power, and update the [layer:database].

The [event:reset] when the reset button is clicked, will update [layer:database] with [layer:core] version of the selected powers if found in [layer:core], irrespective of modify or creation date.

The [event:init] when the init button is clicked, will initialise [layer:database] with all [layers] powers not found in [layer:database]. Should you have the same power in multiple of the layers, here is the [algorithm:cascading]:

  1. [layer:own IF switch:token AND switch:activate AND switch:super AND switch:approved]
  2. [layer:local IF switch:activate]
  3. [layer:core IF_NOT layer:database]

This means, that if JCB gets a [power:guid] in any of the targeted [layer:own] it will not use any of the other [layers] versions. JCB will add this first found power to your [layer:database] unless it's already in [layer:database], in which case it will be ignored. Use [event:sync] or [event:reset] should you like to update [layer:database] existing powers.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_SUPER_POWERS_LABEL="Super Powers" +COM_COMPONENTBUILDER_CONFIG_NOTE_SUPER_POWERS_REPOSITORIES_DESCRIPTION="

Add the paths to those repositories you would like to target with this instance of JCB.

You only need to add the path, so if your repository is located here: https://git.vdm.dev/Llewellyn/workshop.
Then the path will be: Llewellyn/workshop

We will use these paths in all [events] based on the [algorithm:cascading]

" +COM_COMPONENTBUILDER_CONFIG_NOTE_SUPER_POWERS_REPOSITORIES_LABEL="Super Powers Repositories [layer:local:own]" COM_COMPONENTBUILDER_CONFIG_OFF="Off" COM_COMPONENTBUILDER_CONFIG_ON="On" COM_COMPONENTBUILDER_CONFIG_ONLY_BOOLEAN="Only Boolean" COM_COMPONENTBUILDER_CONFIG_ONLY_EXTRA="Only Extra" COM_COMPONENTBUILDER_CONFIG_ORIGINAL_VDM="Original (VDM)" +COM_COMPONENTBUILDER_CONFIG_OWNER_HINT="[owner]" +COM_COMPONENTBUILDER_CONFIG_OWNER_LABEL="Owner" COM_COMPONENTBUILDER_CONFIG_PACKAGE_NAME_PLAEHOLDERS_DESCRIPTION="[YEAR] [MONTH] [DAY] [HOUR] [MINUTE]" COM_COMPONENTBUILDER_CONFIG_PACKAGE_NAME_PLAEHOLDERS_LABEL="Package Name Placeholders" COM_COMPONENTBUILDER_CONFIG_PERCENTAGELANGUAGEADD_DESCRIPTION="Select percentage any language should be translated before the system should add the language to the component during compilation." COM_COMPONENTBUILDER_CONFIG_PERCENTAGELANGUAGEADD_LABEL="Add Language if %? ready." COM_COMPONENTBUILDER_CONFIG_PHP_MAIL="PHP Mail" -COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_DESCRIPTION="Should JCB insert the custom code placeholders? This is only applicable if this component has custom code." -COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_LABEL="Add Custom Code Placeholders" +COM_COMPONENTBUILDER_CONFIG_POWERS_REPOSITORY_DESCRIPTION="This adds powers to a local repository folder. All approved powers, linked to a component, will during compiling be moved to your local powers repository folder into their selective target paths." +COM_COMPONENTBUILDER_CONFIG_POWERS_REPOSITORY_LABEL="Activate Super Powers?" COM_COMPONENTBUILDER_CONFIG_REMOTE_SERVER="Remote Server" COM_COMPONENTBUILDER_CONFIG_REPEATABLETABLE_JOOMLA="Repeatable-table (joomla)" COM_COMPONENTBUILDER_CONFIG_REPEATABLE_JOOMLA="Repeatable (Joomla)" @@ -3615,6 +3474,8 @@ COM_COMPONENTBUILDER_CONFIG_REPLYNAME_HINT="Reply Name Here" COM_COMPONENTBUILDER_CONFIG_REPLYNAME_LABEL="Reply to Name" COM_COMPONENTBUILDER_CONFIG_REPOSITORY_DESCRIPTION="Should the component be moved to your local repository folder?" COM_COMPONENTBUILDER_CONFIG_REPOSITORY_LABEL="Add to Repository Folder" +COM_COMPONENTBUILDER_CONFIG_REPO_HINT="[repo]" +COM_COMPONENTBUILDER_CONFIG_REPO_LABEL="Repo" COM_COMPONENTBUILDER_CONFIG_RETURN_OPTIONS_BUILD_DESCRIPTION="Should the system return the build info/messages, or simply 1 for success and 0 for failure." COM_COMPONENTBUILDER_CONFIG_RETURN_OPTIONS_BUILD_LABEL="Return Options for Build" COM_COMPONENTBUILDER_CONFIG_SENDMAIL="Sendmail" @@ -3623,6 +3484,7 @@ COM_COMPONENTBUILDER_CONFIG_SENDMAIL_HINT="/usr/sbin/sendmail" COM_COMPONENTBUILDER_CONFIG_SENDMAIL_LABEL="Sendmail Path" COM_COMPONENTBUILDER_CONFIG_SET_BROWSER_STORAGE_DESCRIPTION="Select if browser storage should be used to save on Ajax calls and speed up this components site pages." COM_COMPONENTBUILDER_CONFIG_SET_BROWSER_STORAGE_LABEL="Browser Storage" +COM_COMPONENTBUILDER_CONFIG_SHOW="Show" COM_COMPONENTBUILDER_CONFIG_SHOW_ALL="Show All" COM_COMPONENTBUILDER_CONFIG_SIMPLEXMLELEMENT_CLASS="SimpleXMLElement Class" COM_COMPONENTBUILDER_CONFIG_SMTP="SMTP" @@ -3648,13 +3510,24 @@ COM_COMPONENTBUILDER_CONFIG_STORAGE_TIME_TO_LIVE_LABEL="Update Cycle" COM_COMPONENTBUILDER_CONFIG_STRING_MANIPULATION="String Manipulation" COM_COMPONENTBUILDER_CONFIG_SUBFORM_LAYOUTS_DESCRIPTION="Select the sub-form layouts you would like to use." COM_COMPONENTBUILDER_CONFIG_SUBFORM_LAYOUTS_LABEL="Sub-form Layouts" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWER="Super Power" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_HINT="joomla/super-powers" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_LABEL="Super Powers Core" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_ORGANISATION_DESCRIPTION="Set the organisation on your Gitea system where all the JCB core super powers repositories can be found." +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_ORGANISATION_HINT="joomla" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_ORGANISATION_LABEL="Gitea Core Organisation" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_ORGANISATION_NOTE_DESCRIPTION="

The organisation on your Gitea system where all the core super powers repositories can be found.
Example: https://your.gitea.system.com/[core-org]/super-powers

These are the core super powers:
  • https://git.vdm.dev/joomla/super-powers (required)
  • https://git.vdm.dev/joomla/phpseclib (encryption)
  • https://git.vdm.dev/joomla/fof (legacy encryption)
  • https://git.vdm.dev/joomla/gitea (Easy Gitea classes)
  • https://git.vdm.dev/joomla/openai (Easy Openai classes)
  • https://git.vdm.dev/joomla/minify (not usually required)
  • https://git.vdm.dev/joomla/psr (not usually required)
  • https://git.vdm.dev/joomla/jcb-compiler (not usually required)
  • https://git.vdm.dev/joomla/jcb-packager (not usually required)
  • https://git.vdm.dev/joomla/search (not usually required)

You should mirror theses repositories to your Gitea system. Depending on your extension setup JCB may need these repositories to effectively build your extension.

" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_CORE_ORGANISATION_NOTE_LABEL="Gitea Core Organisation" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_DOCUMENTATION_DESCRIPTION="Switch to show or hide the documentation of super powers." +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_DOCUMENTATION_LABEL="Documentation" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_REPOSITORIES_DESCRIPTION="Do you have your own repositories on https://git.vdm.dev/ with super powers?" +COM_COMPONENTBUILDER_CONFIG_SUPER_POWERS_REPOSITORIES_LABEL="Own Super Powers?" COM_COMPONENTBUILDER_CONFIG_THREED_PARTICLE_EXPLORATIONS="3D Particle Explorations" COM_COMPONENTBUILDER_CONFIG_TLS="TLS" COM_COMPONENTBUILDER_CONFIG_TRUE="True" COM_COMPONENTBUILDER_CONFIG_TYPE_NAME_BUILDER_DESCRIPTION="The default option only uses alphabetical characters and converts all numbers in field names to the English equivalent like 1 becomes one.
Alphanumeric+dot keeps the numbers unconverted unless it is at the beginning of the field name, and allows for a dot (.) to be used in the type name for namespacing." COM_COMPONENTBUILDER_CONFIG_TYPE_NAME_BUILDER_LABEL="Field Type Name Builder
(in compiler)" -COM_COMPONENTBUILDER_CONFIG_UIKIT_DESC="The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end framework -for developing fast and powerful web interfaces. For more info visit https://getuikit.com/v2/" +COM_COMPONENTBUILDER_CONFIG_UIKIT_DESC="The Parameters for the uikit are set here.
Uikit is a lightweight and modular front-end frameworkfor developing fast and powerful web interfaces. For more info visit https://getuikit.com/v2/" COM_COMPONENTBUILDER_CONFIG_UIKIT_LABEL="Uikit2 Settings" COM_COMPONENTBUILDER_CONFIG_UIKIT_LOAD_DESC="Set the uikit loading option." COM_COMPONENTBUILDER_CONFIG_UIKIT_LOAD_LABEL="Loading Options" @@ -3667,6 +3540,7 @@ COM_COMPONENTBUILDER_CONFIG_VIEW_FIELD_LABEL="View & Field" COM_COMPONENTBUILDER_CONFIG_YES="Yes" COM_COMPONENTBUILDER_CONFIRMATION_STEP_BEFORE_IMPORTING="Confirmation Step Before Importing!" COM_COMPONENTBUILDER_CONTEXT="Context" +COM_COMPONENTBUILDER_CONTRIBUTE_TO_JCB="Contribute to JCB" COM_COMPONENTBUILDER_CONTRIBUTOR="Contributor" COM_COMPONENTBUILDER_CONTRIBUTORS="Contributors" COM_COMPONENTBUILDER_COPYRIGHT="Copyright" @@ -3687,11 +3561,9 @@ COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_ACCESS_DESC="Allows the users in this gr COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_OPTIONS="Batch process the selected Custom Admin Views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_TIP="All changes will be applied to all selected Custom Admin Views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_USE="Custom Admin Views Batch Use" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch custom admin views" +COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_CREATE="Custom Admin Views Create" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create custom admin views" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_ADD="Custom Admin Views Dashboard Add" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of custom admin view" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_LIST="Custom Admin Views Dashboard List" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of custom admin view" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DELETE="Custom Admin Views Delete" @@ -3704,7 +3576,7 @@ COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_STATE="Custom Admin Views Edit State" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the custom admin view" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_VERSION="Custom Admin Views Edit Version" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version custom admin views" +COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EXPORT="Custom Admin Views Export" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EXPORT_DESC="Allows the users in this group to export export custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_IMPORT="Custom Admin Views Import" @@ -3801,8 +3673,7 @@ COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CLOCK="Clock" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CMD="CMD" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CODENAME_DESCRIPTION="Add Name in Code Here" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CODENAME_HINT="codename" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CODENAME_LABEL="Name in Code
-Naming Conventions" +COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CODENAME_LABEL="Name in Code
Naming Conventions" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CODENAME_MESSAGE="Error! Please add name in code here." COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_COG="Cog" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_COGS="Cogs" @@ -3960,10 +3831,7 @@ COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NEW_TAB="New Tab" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NEW_TAB_2="New Tab 2" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NEXT="Next" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NO="No" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NOTE_LIBRARIES_SELECTION_LABEL="Select libraries you would like to use in your code" @@ -4116,7 +3984,7 @@ COM_COMPONENTBUILDER_CUSTOM_CODES_ACCESS_DESC="Allows the users in this group to COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_OPTIONS="Batch process the selected Custom Codes" COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_TIP="All changes will be applied to all selected Custom Codes" COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_USE="Custom Codes Batch Use" -COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch custom codes" +COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_CREATE="Custom Codes Create" COM_COMPONENTBUILDER_CUSTOM_CODES_CREATE_DESC="Allows the users in this group to create create custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_DASHBOARD_LIST="Custom Codes Dashboard List" @@ -4134,7 +4002,7 @@ COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_STATE="Custom Codes Edit State" COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_STATE_DESC="Allows the users in this group to update the state of the custom code" COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_VERSION="Custom Codes Edit Version" -COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version custom codes" +COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_EXPORT="Custom Codes Export" COM_COMPONENTBUILDER_CUSTOM_CODES_EXPORT_DESC="Allows the users in this group to export export custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_IMPORT="Custom Codes Import" @@ -4196,130 +4064,9 @@ COM_COMPONENTBUILDER_CUSTOM_CODE_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_CUSTOM_CODE_MODIFIED_DATE_DESC="The date this Custom Code was modified." COM_COMPONENTBUILDER_CUSTOM_CODE_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_CUSTOM_CODE_NEW="A New Custom Code" -COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_JCB_PLACEHOLDER_DESCRIPTION="

[save to see placeholder]
You can also pass values to this code like this: [save to see placeholder trick]

-

Those values will be replace placeholders called args. These placeholders are zero based and should look like this: [[[arg0]]], [[[arg1]]] ... as many as you like. If you use 5 args in your code, you must always pass 5 values, since they are zero based your fifth arg will look like this [[[arg4]]]

-

To use the following [ ] , + = in your string being passed, use the following: [ &#91;; ] &#93;; , &#44;; + &#43;; = &#61;

-

Please note THAT YOU CAN NOW use this placeholder in other custom code views, just not in Hash (automation) custom code from the IDE, and not in it self, enjoy!
Another important note, all code with args will not be reversed updated from the changes in the editor out side of JCB at this time, since that will remove all the arg placeholders this means you will only be able to update the code here in the JCB UI.

This note will change once we have resolved these limitations." +COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_JCB_PLACEHOLDER_DESCRIPTION="

[save to see placeholder]
You can also pass values to this code like this: [save to see placeholder trick]

Those values will be replace placeholders called args. These placeholders are zero based and should look like this: [[[arg0]]], [[[arg1]]] ... as many as you like. If you use 5 args in your code, you must always pass 5 values, since they are zero based your fifth arg will look like this [[[arg4]]]

To use the following [ ] , + = in your string being passed, use the following: [ &#91;; ] &#93;; , &#44;; + &#43;; = &#61;

Please note THAT YOU CAN NOW use this placeholder in other custom code views, just not in Hash (automation) custom code from the IDE, and not in it self, enjoy!
Another important note, all code with args will not be reversed updated from the changes in the editor out side of JCB at this time, since that will remove all the arg placeholders this means you will only be able to update the code here in the JCB UI.

This note will change once we have resolved these limitations." COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_JCB_PLACEHOLDER_LABEL="You can use this code in any JCB code area, simply add this PlaceHolder." -COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_PLACEHOLDERS_EXPLAINED_DESCRIPTION="
-

Understand how the placeholders work in (IDE)

-
-

Comment Type PHP/JS

-

How You Can Add New Code in the IDE

-
'; - $head .= PHP_EOL . $this->_t(3) . ""; - $head .= PHP_EOL . $this->_t(2) . "'; - $head .= PHP_EOL . $this->_t(3) . ""; - $head .= PHP_EOL . $this->_t(2) . "
' . JText::_('COM_COMPONENTBUILDER_PROPERTY') . '' . JText::_('COM_COMPONENTBUILDER_EXAMPLE') . '' . JText::_('COM_COMPONENTBUILDER_DESCRIPTION') . '
' . $property['name'] . '' . $example . '' . $property['description'] . '
- Add New Insert Code - - - -
/***[INSERT<>$$$$]***/ 
 <YOUR CODE HERE>
/***[/INSERT<>$$$$]***/ 
- - Add New Replace Code - - - -
/***[REPLACE<>$$$$]***/ 
 <YOUR CODE HERE>
/***[/REPLACE<>$$$$]***/ 
-

When JCB Adds it Back

- - JCB Add Inserted Code - - - -
/***[INSERTED$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/INSERTED$$$$]***/ 
- - JCB Add Replaced Code - - - -
/***[REPLACED$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/REPLACED$$$$]***/ 
-

When You Want to Changing Existing Custom Code in the IDE

- - Update Inserted Code - - - -
/***[INSERTED<>$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/INSERTED<>$$$$]***/ 
- - Update Replaced Code - - - -
/***[REPLACED<>$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/REPLACED<>$$$$]***/ 
-
-
-

Comment Type HTML

-

How You Can Add New Code in the IDE

- - Add New Insert Code - - - -
<!--[INSERT<>$$$$]--> 
 <YOUR CODE HERE>
<!--[/INSERT<>$$$$]--> 
- - Add New Replace Code - - - -
<!--[REPLACE<>$$$$]--> 
 <YOUR CODE HERE>
<!--[/REPLACE<>$$$$]--> 
-

When JCB Adds it Back

- - JCB Add Inserted Code - - - -
<!--[INSERTED$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/INSERTED$$$$]--> 
- - JCB Add Replaced Code - - - -
<!--[REPLACED$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/REPLACED$$$$]--> 
-

When You Want to Changing Existing Custom Code in the IDE

- - Update Inserted Code - - - -
<!--[INSERTED<>$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/INSERTED<>$$$$]--> 
- - Update Replaced Code - - - -
<!--[REPLACED<>$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/REPLACED<>$$$$]--> 
-
-

x is the ID of the code in the system don't change it when you edit the code in your IDE outside of JCB!

-
- -
" +COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_PLACEHOLDERS_EXPLAINED_DESCRIPTION="

Understand how the placeholders work in (IDE)

Comment Type PHP/JS

How You Can Add New Code in the IDE

Add New Insert Code
/***[INSERT<>$$$$]***/ 
 <YOUR CODE HERE>
/***[/INSERT<>$$$$]***/ 
Add New Replace Code
/***[REPLACE<>$$$$]***/ 
 <YOUR CODE HERE>
/***[/REPLACE<>$$$$]***/ 

When JCB Adds it Back

JCB Add Inserted Code
/***[INSERTED$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/INSERTED$$$$]***/ 
JCB Add Replaced Code
/***[REPLACED$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/REPLACED$$$$]***/ 

When You Want to Changing Existing Custom Code in the IDE

Update Inserted Code
/***[INSERTED<>$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/INSERTED<>$$$$]***/ 
Update Replaced Code
/***[REPLACED<>$$$$]***//*x*/ 
 <YOUR CODE HERE>
/***[/REPLACED<>$$$$]***/ 

Comment Type HTML

How You Can Add New Code in the IDE

Add New Insert Code
<!--[INSERT<>$$$$]--> 
 <YOUR CODE HERE>
<!--[/INSERT<>$$$$]--> 
Add New Replace Code
<!--[REPLACE<>$$$$]--> 
 <YOUR CODE HERE>
<!--[/REPLACE<>$$$$]--> 

When JCB Adds it Back

JCB Add Inserted Code
<!--[INSERTED$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/INSERTED$$$$]--> 
JCB Add Replaced Code
<!--[REPLACED$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/REPLACED$$$$]--> 

When You Want to Changing Existing Custom Code in the IDE

Update Inserted Code
<!--[INSERTED<>$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/INSERTED<>$$$$]--> 
Update Replaced Code
<!--[REPLACED<>$$$$]--><!--x--> 
 <YOUR CODE HERE>
<!--[/REPLACED<>$$$$]--> 

x is the ID of the code in the system don't change it when you edit the code in your IDE outside of JCB!

" COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_PLACEHOLDERS_EXPLAINED_LABEL="Information Area." COM_COMPONENTBUILDER_CUSTOM_CODE_NOT_REQUIRED="Not Required" COM_COMPONENTBUILDER_CUSTOM_CODE_ORDERING_LABEL="Ordering" @@ -4356,10 +4103,8 @@ COM_COMPONENTBUILDER_DASH="Dashboard" COM_COMPONENTBUILDER_DASHBOARD="Component Builder Dashboard" COM_COMPONENTBUILDER_DASHBOARD_ADD_RECORD="Dashboard (add record)" COM_COMPONENTBUILDER_DASHBOARD_ADMIN_VIEWS="Admin Views

" -COM_COMPONENTBUILDER_DASHBOARD_ADMIN_VIEW_ADD="Add Admin View

" COM_COMPONENTBUILDER_DASHBOARD_COMPILER="Compiler

" COM_COMPONENTBUILDER_DASHBOARD_CUSTOM_ADMIN_VIEWS="Custom Admin Views

" -COM_COMPONENTBUILDER_DASHBOARD_CUSTOM_ADMIN_VIEW_ADD="Add Custom Admin View

" COM_COMPONENTBUILDER_DASHBOARD_CUSTOM_CODES="Custom Codes

" COM_COMPONENTBUILDER_DASHBOARD_DYNAMIC_GETS="Dynamic Gets

" COM_COMPONENTBUILDER_DASHBOARD_DYNAMIC_GET_ADD="Add Dynamic Get

" @@ -4380,9 +4125,9 @@ COM_COMPONENTBUILDER_DASHBOARD_LIBRARIES="Libraries

" COM_COMPONENTBUILDER_DASHBOARD_LIST_OF_RECORDS="Dashboard (list of records)" COM_COMPONENTBUILDER_DASHBOARD_PLACEHOLDERS="Placeholders

" COM_COMPONENTBUILDER_DASHBOARD_POWERS="Powers

" +COM_COMPONENTBUILDER_DASHBOARD_SEARCH="Search

" COM_COMPONENTBUILDER_DASHBOARD_SERVERS="Servers

" COM_COMPONENTBUILDER_DASHBOARD_SITE_VIEWS="Site Views

" -COM_COMPONENTBUILDER_DASHBOARD_SITE_VIEW_ADD="Add Site View

" COM_COMPONENTBUILDER_DASHBOARD_SNIPPETS="Snippets

" COM_COMPONENTBUILDER_DASHBOARD_TEMPLATES="Templates

" COM_COMPONENTBUILDER_DASHBOARD_TEMPLATE_ADD="Add Template

" @@ -4398,6 +4143,8 @@ COM_COMPONENTBUILDER_DISPLAY_SWITCH_FOR_DYNAMIC_PLACEMENT_IN_RELATION_TO_THE_USE COM_COMPONENTBUILDER_DIVERGED="Diverged" COM_COMPONENTBUILDER_DIVERGED_MEANS_YOUR_BLOCAL_SNIPPETB_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_A_BDIVERGEDB_FROM_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_IN_THAT_IT_DOES_NOT_HAVE_THE_SAME_BCREATIONB_OR_BMODIFIED_DATEB="Diverged means your local snippet (with the same name, library and type) has a diverged from the community snippet (with the same name, library and type) in that it does not have the same creation or modified date." COM_COMPONENTBUILDER_DOES_THIS_PACKAGE_REQUIRE_A_KEY_TO_INSTALL="Does this package require a key to install." +COM_COMPONENTBUILDER_DONATE_TO_JCB="Donate to JCB" +COM_COMPONENTBUILDER_DONATIONS="Donations!" COM_COMPONENTBUILDER_DOWNLOAD_UPDATE="Download Update" COM_COMPONENTBUILDER_DO_NOT_ADD="Do not add" COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD="
Company
%s
" @@ -4413,7 +4160,7 @@ COM_COMPONENTBUILDER_DYNAMIC_GETS_ACCESS_DESC="Allows the users in this group to COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_OPTIONS="Batch process the selected Dynamic Gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_TIP="All changes will be applied to all selected Dynamic Gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_USE="Dynamic Gets Batch Use" -COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch dynamic gets" +COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_CREATE="Dynamic Gets Create" COM_COMPONENTBUILDER_DYNAMIC_GETS_CREATE_DESC="Allows the users in this group to create create dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_DASHBOARD_ADD="Dynamic Gets Dashboard Add" @@ -4429,7 +4176,7 @@ COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_STATE="Dynamic Gets Edit State" COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_STATE_DESC="Allows the users in this group to update the state of the dynamic get" COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_VERSION="Dynamic Gets Edit Version" -COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version dynamic gets" +COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_EXPORT="Dynamic Gets Export" COM_COMPONENTBUILDER_DYNAMIC_GETS_EXPORT_DESC="Allows the users in this group to export export dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_IMPORT="Dynamic Gets Import" @@ -4708,9 +4455,11 @@ COM_COMPONENTBUILDER_EDIT_CREATED_DATE="Edit Created Date" COM_COMPONENTBUILDER_EDIT_CREATED_DATE_DESC="Allows users in this group to edit created date." COM_COMPONENTBUILDER_EDIT_S="Edit %s" COM_COMPONENTBUILDER_EDIT_S_FOR_THIS_S="Edit %s for this %s" +COM_COMPONENTBUILDER_EDIT_S_S_DIRECTLY="Edit %s (%s) directly" COM_COMPONENTBUILDER_EDIT_VERSIONS="Edit Version" COM_COMPONENTBUILDER_EDIT_VERSIONS_DESC="Allows users in this group to edit versions." COM_COMPONENTBUILDER_EDIT_VIEW="Edit View" +COM_COMPONENTBUILDER_ELEVATE_JCB_TODAY="Elevate JCB Today" COM_COMPONENTBUILDER_EMAIL="Email" COM_COMPONENTBUILDER_EMAIL_S="Email %s" COM_COMPONENTBUILDER_EMAIL_WITH_THE_NEW_KEY_WAS_SENT="Email with the new key was sent" @@ -4719,8 +4468,12 @@ COM_COMPONENTBUILDER_EMCOPYRIGHTEM_BSB="Copyright: %s" COM_COMPONENTBUILDER_EMEMAILEM_BSB="Email: %s" COM_COMPONENTBUILDER_EMLICENSEEM_BSB="License: %s" COM_COMPONENTBUILDER_EMOWNEREM_BSB="Owner: %s" +COM_COMPONENTBUILDER_EMPOWER_JCB="Empower JCB" +COM_COMPONENTBUILDER_EMPOWER_THE_FUTURE_WITH_JCB="Empower the Future with JCB" COM_COMPONENTBUILDER_EMPTY_TRASH="Empty trash" COM_COMPONENTBUILDER_EMWEBSITEEM_BSB="Website: %s" +COM_COMPONENTBUILDER_ENTER_YOUR_REPLACE_TEXT="Enter your replace text" +COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT="Enter your search text" COM_COMPONENTBUILDER_EQUAL="Equal" COM_COMPONENTBUILDER_EQUAL_MEANS_THAT_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_AND_YOUR_LOCAL_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_THE_SAME_BCREATIONB_AND_BMODIFIED_DATEB="Equal means that the community snippet (with the same name, library and type) and your local snippet (with the same name, library and type) has the same creation and modified date." COM_COMPONENTBUILDER_ERROR="Error" @@ -4751,7 +4504,7 @@ COM_COMPONENTBUILDER_FIELDS_ACCESS_DESC="Allows the users in this group to acces COM_COMPONENTBUILDER_FIELDS_BATCH_OPTIONS="Batch process the selected Fields" COM_COMPONENTBUILDER_FIELDS_BATCH_TIP="All changes will be applied to all selected Fields" COM_COMPONENTBUILDER_FIELDS_BATCH_USE="Fields Batch Use" -COM_COMPONENTBUILDER_FIELDS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch fields" +COM_COMPONENTBUILDER_FIELDS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch fields" COM_COMPONENTBUILDER_FIELDS_CREATE="Fields Create" COM_COMPONENTBUILDER_FIELDS_CREATE_DESC="Allows the users in this group to create create fields" COM_COMPONENTBUILDER_FIELDS_DASHBOARD_ADD="Fields Dashboard Add" @@ -4767,7 +4520,7 @@ COM_COMPONENTBUILDER_FIELDS_EDIT_OWN_DESC="Allows the users in this group to edi COM_COMPONENTBUILDER_FIELDS_EDIT_STATE="Fields Edit State" COM_COMPONENTBUILDER_FIELDS_EDIT_STATE_DESC="Allows the users in this group to update the state of the field" COM_COMPONENTBUILDER_FIELDS_EDIT_VERSION="Fields Edit Version" -COM_COMPONENTBUILDER_FIELDS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version fields" +COM_COMPONENTBUILDER_FIELDS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version fields" COM_COMPONENTBUILDER_FIELDS_EXPORT="Fields Export" COM_COMPONENTBUILDER_FIELDS_EXPORT_DESC="Allows the users in this group to export export fields" COM_COMPONENTBUILDER_FIELDS_IMPORT="Fields Import" @@ -4793,6 +4546,7 @@ COM_COMPONENTBUILDER_FIELDS_N_ITEMS_UNPUBLISHED="%s Fields unpublished." COM_COMPONENTBUILDER_FIELDS_N_ITEMS_UNPUBLISHED_1="%s Field unpublished." COM_COMPONENTBUILDER_FIELDS_SUBMENU="Fields Submenu" COM_COMPONENTBUILDER_FIELDS_SUBMENU_DESC="Allows the users in this group to submenu of field" +COM_COMPONENTBUILDER_FIELDS_THAT_HAD="fields that had" COM_COMPONENTBUILDER_FIELDTYPE="Fieldtype" COM_COMPONENTBUILDER_FIELDTYPES="Fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_ACCESS="Fieldtypes Access" @@ -4800,7 +4554,7 @@ COM_COMPONENTBUILDER_FIELDTYPES_ACCESS_DESC="Allows the users in this group to a COM_COMPONENTBUILDER_FIELDTYPES_BATCH_OPTIONS="Batch process the selected Fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_BATCH_TIP="All changes will be applied to all selected Fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE="Fieldtypes Batch Use" -COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch fieldtypes" +COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_CREATE="Fieldtypes Create" COM_COMPONENTBUILDER_FIELDTYPES_CREATE_DESC="Allows the users in this group to create create fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_LIST="Fieldtypes Dashboard List" @@ -4814,7 +4568,7 @@ COM_COMPONENTBUILDER_FIELDTYPES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_FIELDTYPES_EDIT_STATE="Fieldtypes Edit State" COM_COMPONENTBUILDER_FIELDTYPES_EDIT_STATE_DESC="Allows the users in this group to update the state of the fieldtype" COM_COMPONENTBUILDER_FIELDTYPES_EDIT_VERSION="Fieldtypes Edit Version" -COM_COMPONENTBUILDER_FIELDTYPES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version fieldtypes" +COM_COMPONENTBUILDER_FIELDTYPES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_EXPORT="Fieldtypes Export" COM_COMPONENTBUILDER_FIELDTYPES_EXPORT_DESC="Allows the users in this group to export export fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_IMPORT="Fieldtypes Import" @@ -4844,6 +4598,8 @@ COM_COMPONENTBUILDER_FIELDTYPE_ADJUSTABLE_DESCRIPTION="Select if the value is ad COM_COMPONENTBUILDER_FIELDTYPE_ADJUSTABLE_LABEL="Adjustable" COM_COMPONENTBUILDER_FIELDTYPE_BASE64="base64" COM_COMPONENTBUILDER_FIELDTYPE_BASIC_ENCRYPTION_LOCALDBKEY="Basic Encryption (local-DB-key)" +COM_COMPONENTBUILDER_FIELDTYPE_BASIC_ENCRYPTION_NOTE_DESCRIPTION="

Since basic encryption makes use of the FOF encryption suite, we need to deprecate this method.
Hence, please refrain from using this method in new projects!

Removing this basic encryption method from an existing project is challenging, and incorrect removal may result in data loss, or breach. For this reason, we've ported the FOF encryption suite into JCB powers, enabling its use in PHP 8+ and Joomla 4.

As a result, you should be able to continue using it in existing projects.

We plan to establish a migration path to another encryption option, like PHPSecLib, in the future. We will announce the removal date of the Basic Encryption feature only after this migration path is in place.

" +COM_COMPONENTBUILDER_FIELDTYPE_BASIC_ENCRYPTION_NOTE_LABEL="Basic Encryption" COM_COMPONENTBUILDER_FIELDTYPE_BIGINT="BIGINT" COM_COMPONENTBUILDER_FIELDTYPE_BLOB="BLOB" COM_COMPONENTBUILDER_FIELDTYPE_CATID_DESCRIPTION="select one of the following categories" @@ -4907,6 +4663,8 @@ COM_COMPONENTBUILDER_FIELDTYPE_MANDATORY_LABEL="Mandatory" COM_COMPONENTBUILDER_FIELDTYPE_MEDIUMBLOB="MEDIUMBLOB" COM_COMPONENTBUILDER_FIELDTYPE_MEDIUMTEXT="MEDIUMTEXT" COM_COMPONENTBUILDER_FIELDTYPE_MEDIUM_ENCRYPTION_LOCALFILEKEY="Medium Encryption (local-file-key)" +COM_COMPONENTBUILDER_FIELDTYPE_MEDIUM_ENCRYPTION_NOTE_DESCRIPTION="

Since medium encryption makes use of the FOF encryption suite, we need to deprecate this method.
Hence, please refrain from using this method in new projects!

Removing this medium encryption method from an existing project is challenging, and incorrect removal may result in data loss, or breach. For this reason, we've ported the FOF encryption suite into JCB powers, enabling its use in PHP 8+ and Joomla 4.

As a result, you should be able to continue using it in existing projects.

We plan to establish a migration path to another encryption option, like PHPSecLib, in the future. We will announce the removal date of the Medium Encryption feature only after this migration path is in place.

" +COM_COMPONENTBUILDER_FIELDTYPE_MEDIUM_ENCRYPTION_NOTE_LABEL="Medium Encryption" COM_COMPONENTBUILDER_FIELDTYPE_MODIFIED_BY_DESC="The last user that modified this Fieldtype." COM_COMPONENTBUILDER_FIELDTYPE_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_FIELDTYPE_MODIFIED_DATE_DESC="The date this Fieldtype was modified." @@ -4921,9 +4679,7 @@ COM_COMPONENTBUILDER_FIELDTYPE_NONE="None" COM_COMPONENTBUILDER_FIELDTYPE_NONE_SET="None Set" COM_COMPONENTBUILDER_FIELDTYPE_NOTE_ON_FIELDS_DESCRIPTION="To get more form field settings go to https://docs.joomla.org/Form_field" COM_COMPONENTBUILDER_FIELDTYPE_NOTE_ON_FIELDS_LABEL="More Standard form field types" -COM_COMPONENTBUILDER_FIELDTYPE_NOTE_WHMCS_ENCRYPTION_DESCRIPTION="

When using the WHMCS encryption you need to get a WHMCS key from:
https://www.vdm.io, or your own WHMCS install.

Please note that you will need to enable the add-on in the Joomla Component area (Add WHMCS)->Yes.

You can get more info about the WHMCS licensing add-on at the following links.

Helpful Links:
-https://www.whmcs.com/software-licensing/
-http://docs.whmcs.com/Licensing_Addon/

Support JCB and use our affiliate link (https://www.whmcs.com/members/aff.php?aff=37513) to sign-up with WHMCS.

" +COM_COMPONENTBUILDER_FIELDTYPE_NOTE_WHMCS_ENCRYPTION_DESCRIPTION="

When using the WHMCS encryption you need to get a WHMCS key from:
https://www.vdm.io, or your own WHMCS install.

Please note that you will need to enable the add-on in the Joomla Component area (Add WHMCS)->Yes.

You can get more info about the WHMCS licensing add-on at the following links.

Helpful Links:
https://www.whmcs.com/software-licensing/
http://docs.whmcs.com/Licensing_Addon/

Support JCB and use our affiliate link (https://www.whmcs.com/members/aff.php?aff=37513) to sign-up with WHMCS.

" COM_COMPONENTBUILDER_FIELDTYPE_NOTE_WHMCS_ENCRYPTION_LABEL="The WHMCS Encryption" COM_COMPONENTBUILDER_FIELDTYPE_NOT_NULL="NOT NULL" COM_COMPONENTBUILDER_FIELDTYPE_NOT_REQUIRED="Not Required" @@ -4948,7 +4704,7 @@ COM_COMPONENTBUILDER_FIELDTYPE_SHORT_DESCRIPTION_MESSAGE="Error! Please add some COM_COMPONENTBUILDER_FIELDTYPE_SIXTY_FOUR="64" COM_COMPONENTBUILDER_FIELDTYPE_STATUS="Status" COM_COMPONENTBUILDER_FIELDTYPE_STORE_DESCRIPTION="How should the field value be modeled during saving and getting of the value. Default is the Joomla basic normal storing way of dealing with this field type." -COM_COMPONENTBUILDER_FIELDTYPE_STORE_LABEL="Modeling Method" +COM_COMPONENTBUILDER_FIELDTYPE_STORE_LABEL="Modelling Method" COM_COMPONENTBUILDER_FIELDTYPE_TEN="10" COM_COMPONENTBUILDER_FIELDTYPE_TEXT="TEXT" COM_COMPONENTBUILDER_FIELDTYPE_TIME="TIME" @@ -4971,6 +4727,8 @@ COM_COMPONENTBUILDER_FIELD_ADD_JAVASCRIPT_VIEWS_FOOTER_LABEL="Add JavaScript (vi COM_COMPONENTBUILDER_FIELD_ADD_JAVASCRIPT_VIEW_FOOTER_LABEL="Add JavaScript (view-footer)" COM_COMPONENTBUILDER_FIELD_BASE64="base64" COM_COMPONENTBUILDER_FIELD_BASIC_ENCRYPTION_LOCALDBKEY="Basic Encryption (local-DB-key)" +COM_COMPONENTBUILDER_FIELD_BASIC_ENCRYPTION_NOTE_DESCRIPTION="

Since basic encryption makes use of the FOF encryption suite, we need to deprecate this method.
Hence, please refrain from using this method in new projects!

Removing this basic encryption method from an existing project is challenging, and incorrect removal may result in data loss, or breach. For this reason, we've ported the FOF encryption suite into JCB powers, enabling its use in PHP 8+ and Joomla 4.

As a result, you should be able to continue using it in existing projects.

We plan to establish a migration path to another encryption option, like PHPSecLib, in the future. We will announce the removal date of the Basic Encryption feature only after this migration path is in place.

" +COM_COMPONENTBUILDER_FIELD_BASIC_ENCRYPTION_NOTE_LABEL="Basic Encryption" COM_COMPONENTBUILDER_FIELD_BIGINT="BIGINT" COM_COMPONENTBUILDER_FIELD_BLOB="BLOB" COM_COMPONENTBUILDER_FIELD_BSB_NOT_FOUND_IN_LOCAL_DATABASE_TABLE_S_SO_IMPORTED_OF_ITS_VALUES_FAILED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN="Field %s not found in local database table (%s) so imported of its values failed, please update your JCB install and try again." @@ -5022,18 +4780,13 @@ COM_COMPONENTBUILDER_FIELD_HELPNOTE_LABEL="Field Information" COM_COMPONENTBUILDER_FIELD_ID="Id" COM_COMPONENTBUILDER_FIELD_INDEXES_LABEL="Indexes Type" COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_GET_MODEL_DESCRIPTION="The initiator to on get model this field. If JCB finds that there is more then one field with the same initiator code in one view it will only load it once. You could also leave this blank if you already have the on get model initiator set in another field of the same admin_view." -COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_GET_MODEL_HINT="// Get the medium decryption. -$mediumkey = ComponentbuilderHelper::getCryptKey('medium'); -// Get the encryption object. -$medium = new FOFEncryptAes($mediumkey);" +COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_GET_MODEL_HINT="// Get the medium decryption.$mediumkey = ComponentbuilderHelper::getCryptKey('medium');// Get the encryption object.$medium = new FOFEncryptAes($mediumkey);" COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_GET_MODEL_LABEL="Initiator
on get model" COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_SAVE_MODEL_DESCRIPTION="The initiator to on save model this field. If JCB finds that there is more then one field with the same initiator code in one view it will only load it once. You could also leave this blank if you already have the on save model initiator set in another field of the same admin_view." -COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_SAVE_MODEL_HINT="// Get the medium encryption. -$mediumkey = ComponentbuilderHelper::getCryptKey('medium'); -// Get the encryption object. -$medium = new FOFEncryptAes($mediumkey);" +COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_SAVE_MODEL_HINT="// Get the medium encryption.$mediumkey = ComponentbuilderHelper::getCryptKey('medium');// Get the encryption object.$medium = new FOFEncryptAes($mediumkey);" COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_SAVE_MODEL_LABEL="Initiator
on save model" COM_COMPONENTBUILDER_FIELD_INT="INT" +COM_COMPONENTBUILDER_FIELD_IN_THE="field in the" COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEWS_FOOTER_DESCRIPTION="Add JavaScript for the list view that is loaded in the footer inside script tags. Do not add the script tags." COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEWS_FOOTER_LABEL="Javascript (list view footer)" COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEW_FOOTER_DESCRIPTION="Add JavaScript for the edit view that is loaded in the footer inside script tags. Do not add the script tags." @@ -5045,6 +4798,8 @@ COM_COMPONENTBUILDER_FIELD_LONGTEXT="LONGTEXT" COM_COMPONENTBUILDER_FIELD_MEDIUMBLOB="MEDIUMBLOB" COM_COMPONENTBUILDER_FIELD_MEDIUMTEXT="MEDIUMTEXT" COM_COMPONENTBUILDER_FIELD_MEDIUM_ENCRYPTION_LOCALFILEKEY="Medium Encryption (local-file-key)" +COM_COMPONENTBUILDER_FIELD_MEDIUM_ENCRYPTION_NOTE_DESCRIPTION="

Since medium encryption makes use of the FOF encryption suite, we need to deprecate this method.
Hence, please refrain from using this method in new projects!

Removing this medium encryption method from an existing project is challenging, and incorrect removal may result in data loss, or breach. For this reason, we've ported the FOF encryption suite into JCB powers, enabling its use in PHP 8+ and Joomla 4.

As a result, you should be able to continue using it in existing projects.

We plan to establish a migration path to another encryption option, like PHPSecLib, in the future. We will announce the removal date of the Medium Encryption feature only after this migration path is in place.

" +COM_COMPONENTBUILDER_FIELD_MEDIUM_ENCRYPTION_NOTE_LABEL="Medium Encryption" COM_COMPONENTBUILDER_FIELD_MODIFIED_BY_DESC="The last user that modified this Field." COM_COMPONENTBUILDER_FIELD_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_FIELD_MODIFIED_DATE_DESC="The date this Field was modified." @@ -5059,103 +4814,14 @@ COM_COMPONENTBUILDER_FIELD_NONE="None" COM_COMPONENTBUILDER_FIELD_NONE_SET="None Set" COM_COMPONENTBUILDER_FIELD_NOTE_DATABASE_SETTINGS_NEEDED_DESCRIPTION="

Set the database column for this field here. The column will have the same name as the field. Please take care to select these settings in the correct relationship. The nature of this area is to give you as much freedom/power as you would like, but with that comes responsibility.

You therefore need to insure that you know what the correct values should be. A great way to learn, is to look at the Joomla core components fields and the corresponding mySql columns.

" COM_COMPONENTBUILDER_FIELD_NOTE_DATABASE_SETTINGS_NEEDED_LABEL="Database Settings" -COM_COMPONENTBUILDER_FIELD_NOTE_EXPERT_FIELD_SAVE_MODE_DESCRIPTION="

When using the EXPERT mode you need to be that expert.

-

Bellow you must add the required code to on save model and on get model the set value. Usually if we start modeling values, we first load the needed classes, so for that purpose you have the initiator input areas.

" +COM_COMPONENTBUILDER_FIELD_NOTE_EXPERT_FIELD_SAVE_MODE_DESCRIPTION="

When using the EXPERT mode you need to be that expert.

Bellow you must add the required code to on save model and on get model the set value. Usually if we start modeling values, we first load the needed classes, so for that purpose you have the initiator input areas.

" COM_COMPONENTBUILDER_FIELD_NOTE_EXPERT_FIELD_SAVE_MODE_LABEL="The Expert Mode" -COM_COMPONENTBUILDER_FIELD_NOTE_FILTER_INFORMATION_DESCRIPTION="
-
-

Filter Information

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The available values for the filter attribute are:
FilterDescription
INTAn integer
UINTAn unsigned integer
FLOATA floating point number
BOOLEANA boolean value
WORDA string containing A-Z or underscores only (not case sensitive)
ALNUMA string containing A-Z or 0-9 only (not case sensitive)
CMDA string containing A-Z, 0-9, underscores, periods or hyphens (not case sensitive)
BASE64A string containing A-Z, 0-9, forward slashes, plus or equals (not case sensitive)
STRINGA fully decoded and sanitized string (default)
HTMLA sanitized string
ARRAYAn array
PATHA sanitized file path
USERNAMEDo not use (use an application specific filter)
RAWThe raw string is returned with no filtering
unknownAn unknown filter will act like STRING. If the input is an array it will return an array of fully decoded and sanitized strings.
-
-
-

Validation Rules

- -
Searching the system.
-
-
-

Linked To

- -
Searching the database.
-
-
" +COM_COMPONENTBUILDER_FIELD_NOTE_FILTER_INFORMATION_DESCRIPTION="

Filter Information

The available values for the filter attribute are:
Filter Description
INT An integer
UINT An unsigned integer
FLOAT A floating point number
BOOLEAN A boolean value
WORD A string containing A-Z or underscores only (not case sensitive)
ALNUM A string containing A-Z or 0-9 only (not case sensitive)
CMD A string containing A-Z, 0-9, underscores, periods or hyphens (not case sensitive)
BASE64 A string containing A-Z, 0-9, forward slashes, plus or equals (not case sensitive)
STRING A fully decoded and sanitized string (default)
HTML A sanitized string
ARRAY An array
PATH A sanitized file path
USERNAME Do not use (use an application specific filter)
RAW The raw string is returned with no filtering
unknown An unknown filter will act like STRING. If the input is an array it will return an array of fully decoded and sanitized strings.

Validation Rules

Searching the system.

Linked To

Searching the database.
" COM_COMPONENTBUILDER_FIELD_NOTE_NO_DATABASE_SETTINGS_NEEDED_DESCRIPTION="This field does not require any database settings to function correctly." COM_COMPONENTBUILDER_FIELD_NOTE_NO_DATABASE_SETTINGS_NEEDED_LABEL="No Database Require" COM_COMPONENTBUILDER_FIELD_NOTE_SELECT_FIELD_TYPE_DESCRIPTION="Please select a field type that you would like to build." COM_COMPONENTBUILDER_FIELD_NOTE_SELECT_FIELD_TYPE_LABEL="Building a field" -COM_COMPONENTBUILDER_FIELD_NOTE_WHMCS_ENCRYPTION_DESCRIPTION="

When using the WHMCS encryption you need to get a WHMCS key from:
https://www.vdm.io, or your own WHMCS install.

Please note that you will need to enable the add-on in the Joomla Component area (Add WHMCS)->Yes.

You can get more info about the WHMCS licensing add-on at the following links.

Helpful Links:
-https://www.whmcs.com/software-licensing/
-http://docs.whmcs.com/Licensing_Addon/

Support JCB and use our affiliate link (https://www.whmcs.com/members/aff.php?aff=37513) to sign-up with WHMCS.

" +COM_COMPONENTBUILDER_FIELD_NOTE_WHMCS_ENCRYPTION_DESCRIPTION="

When using the WHMCS encryption you need to get a WHMCS key from:
https://www.vdm.io, or your own WHMCS install.

Please note that you will need to enable the add-on in the Joomla Component area (Add WHMCS)->Yes.

You can get more info about the WHMCS licensing add-on at the following links.

Helpful Links:
https://www.whmcs.com/software-licensing/
http://docs.whmcs.com/Licensing_Addon/

Support JCB and use our affiliate link (https://www.whmcs.com/members/aff.php?aff=37513) to sign-up with WHMCS.

" COM_COMPONENTBUILDER_FIELD_NOTE_WHMCS_ENCRYPTION_LABEL="The WHMCS Encryption" COM_COMPONENTBUILDER_FIELD_NOT_NULL="NOT NULL" COM_COMPONENTBUILDER_FIELD_NOT_REQUIRED="Not Required" @@ -5165,11 +4831,7 @@ COM_COMPONENTBUILDER_FIELD_ONE="1" COM_COMPONENTBUILDER_FIELD_ONE_HUNDRED="100" COM_COMPONENTBUILDER_FIELD_ONE_THOUSAND_AND_TWENTY_FOUR="1024" COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_DESCRIPTION="To on get model the field value" -COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_HINT="if (!empty([[[field]]]) && $mediumkey && !is_numeric([[[field]]]) && [[[field]]] === base64_encode(base64_decode([[[field]]], true))) -{ - // medium decrypt field - [[[field]]] = rtrim($medium->decryptString([[[field]]]), "\0"); -}" +COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_HINT="if (!empty([[[field]]]) && $mediumkey && !is_numeric([[[field]]]) && [[[field]]] === base64_encode(base64_decode([[[field]]], true))){ // medium decrypt field [[[field]]] = rtrim($medium->decryptString([[[field]]]), "\0");}" COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_LABEL="On Get Model" COM_COMPONENTBUILDER_FIELD_ON_SAVE_MODEL_FIELD_DESCRIPTION="To on save model the field value" COM_COMPONENTBUILDER_FIELD_ON_SAVE_MODEL_FIELD_HINT="[[[field]]] = $medium->encryptString([[[field]]]);" @@ -5188,7 +4850,7 @@ COM_COMPONENTBUILDER_FIELD_SEVEN="7" COM_COMPONENTBUILDER_FIELD_SIXTY_FOUR="64" COM_COMPONENTBUILDER_FIELD_STATUS="Status" COM_COMPONENTBUILDER_FIELD_STORE_DESCRIPTION="How should the field value be modeled during saving and getting of the value. Default is the Joomla basic normal storing way of dealing with this field type." -COM_COMPONENTBUILDER_FIELD_STORE_LABEL="Modeling Method" +COM_COMPONENTBUILDER_FIELD_STORE_LABEL="Modelling Method" COM_COMPONENTBUILDER_FIELD_TEN="10" COM_COMPONENTBUILDER_FIELD_TEXT="TEXT" COM_COMPONENTBUILDER_FIELD_TIME="TIME" @@ -5257,22 +4919,18 @@ COM_COMPONENTBUILDER_FILTER_MAIN_GET_ASCENDING="Main Get ascending" COM_COMPONENTBUILDER_FILTER_MAIN_GET_DESCENDING="Main Get descending" COM_COMPONENTBUILDER_FILTER_MAIN_SOURCE_ASCENDING="Main Source ascending" COM_COMPONENTBUILDER_FILTER_MAIN_SOURCE_DESCENDING="Main Source descending" -COM_COMPONENTBUILDER_FILTER_MODELING_METHOD_ASCENDING="Modeling Method ascending" -COM_COMPONENTBUILDER_FILTER_MODELING_METHOD_DESCENDING="Modeling Method descending" +COM_COMPONENTBUILDER_FILTER_MODELLING_METHOD_ASCENDING="Modelling Method ascending" +COM_COMPONENTBUILDER_FILTER_MODELLING_METHOD_DESCENDING="Modelling Method descending" COM_COMPONENTBUILDER_FILTER_MODIFIED_DATE_ASCENDING="Modified Date ascending" COM_COMPONENTBUILDER_FILTER_MODIFIED_DATE_DESCENDING="Modified Date descending" COM_COMPONENTBUILDER_FILTER_NAMESPACE_ASCENDING="Namespace ascending" COM_COMPONENTBUILDER_FILTER_NAMESPACE_DESCENDING="Namespace descending" COM_COMPONENTBUILDER_FILTER_NAME_ASCENDING="Name ascending" COM_COMPONENTBUILDER_FILTER_NAME_DESCENDING="Name descending" -COM_COMPONENTBUILDER_FILTER_NAME_IN_CODE_NAMING_CONVENTIONS_ASCENDING="Name in Code -Naming Conventions ascending" -COM_COMPONENTBUILDER_FILTER_NAME_IN_CODE_NAMING_CONVENTIONS_DESCENDING="Name in Code -Naming Conventions descending" -COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORD_NAMING_CONVENTIONS_ASCENDING="Name (single record) -Naming Conventions ascending" -COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORD_NAMING_CONVENTIONS_DESCENDING="Name (single record) -Naming Conventions descending" +COM_COMPONENTBUILDER_FILTER_NAME_IN_CODENAMING_CONVENTIONS_ASCENDING="Name in CodeNaming Conventions ascending" +COM_COMPONENTBUILDER_FILTER_NAME_IN_CODENAMING_CONVENTIONS_DESCENDING="Name in CodeNaming Conventions descending" +COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORDNAMING_CONVENTIONS_ASCENDING="Name (single record)Naming Conventions ascending" +COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORDNAMING_CONVENTIONS_DESCENDING="Name (single record)Naming Conventions descending" COM_COMPONENTBUILDER_FILTER_NULL_SWITCH_ASCENDING="Null Switch ascending" COM_COMPONENTBUILDER_FILTER_NULL_SWITCH_DESCENDING="Null Switch descending" COM_COMPONENTBUILDER_FILTER_PROTOCOL_ASCENDING="Protocol ascending" @@ -5400,18 +5058,18 @@ COM_COMPONENTBUILDER_FILTER_SELECT_LIBRARY="Select Library" COM_COMPONENTBUILDER_FILTER_SELECT_LOCATION="Select Location" COM_COMPONENTBUILDER_FILTER_SELECT_MAIN_GET="Select Main Get" COM_COMPONENTBUILDER_FILTER_SELECT_MAIN_SOURCE="Select Main Source" -COM_COMPONENTBUILDER_FILTER_SELECT_MODELING_METHOD="Select Modeling Method" +COM_COMPONENTBUILDER_FILTER_SELECT_MODELLING_METHOD="Select Modelling Method" COM_COMPONENTBUILDER_FILTER_SELECT_NAME="Select Name" COM_COMPONENTBUILDER_FILTER_SELECT_NULL_SWITCH="Select Null Switch" COM_COMPONENTBUILDER_FILTER_SELECT_PROTOCOL="Select Protocol" COM_COMPONENTBUILDER_FILTER_SELECT_SITE_VIEWS="Select Site Views" +COM_COMPONENTBUILDER_FILTER_SELECT_SUPER_POWER="Select Super Power" COM_COMPONENTBUILDER_FILTER_SELECT_TARGET="Select Target" COM_COMPONENTBUILDER_FILTER_SELECT_TARGET_AREA="Select Target Area" COM_COMPONENTBUILDER_FILTER_SELECT_TARGET_FOLDER="Select Target Folder" COM_COMPONENTBUILDER_FILTER_SELECT_TYPE="Select Type" COM_COMPONENTBUILDER_FILTER_SELECT_TYPE_BEHAVIOR="Select Type Behavior" COM_COMPONENTBUILDER_FILTER_SELECT_TYPE_OF_POWER="Select Type of Power" -COM_COMPONENTBUILDER_FILTER_SELECT_VERSION="Select Version" COM_COMPONENTBUILDER_FILTER_SELECT_VISIBILITY="Select Visibility" COM_COMPONENTBUILDER_FILTER_SET_STRING_VALUE_ASCENDING="Set String Value ascending" COM_COMPONENTBUILDER_FILTER_SET_STRING_VALUE_DESCENDING="Set String Value descending" @@ -5448,6 +5106,9 @@ COM_COMPONENTBUILDER_FOLDER_BSB_WAS_MOVED_TO_BSB="Folder %s was moved to COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVED_TO_BSB="Folder %s was not moved to %s" COM_COMPONENTBUILDER_FORCE_LOCAL_UPDATE="Force Local Update" COM_COMPONENTBUILDER_FORCE_THAT_THIS_JCB_PACKAGE_IMPORT_SEARCH_FOR_LOCAL_ITEMS_TO_BE_DONE_WITH_GUID_VALUE_ONLY_IF_BMERGEB_IS_SET_TO_YES_ABOVE="Force that this JCB package import (search for local items) to be done with GUID value only, if Merge is set to yes above." +COM_COMPONENTBUILDER_FOUND="Found" +COM_COMPONENTBUILDER_FOUND_TEXT="Found Text" +COM_COMPONENTBUILDER_FOUR_SPACES="4 Spaces" COM_COMPONENTBUILDER_FREEOPEN="Free/Open" COM_COMPONENTBUILDER_FULL_WIDTH_IN_TAB="Full Width in Tab" COM_COMPONENTBUILDER_FUNCTION_NAME_ALREADY_TAKEN_PLEASE_TRY_AGAIN="Function name already taken, please try again." @@ -5484,6 +5145,7 @@ COM_COMPONENTBUILDER_GET_THE_SNIPPET_FROM_GITHUB_AND_INSTALL_IT_LOCALLY="Get the COM_COMPONENTBUILDER_GET_THE_SNIPPET_FROM_GITHUB_AND_UPDATE_THE_LOCAL_VERSION="Get the snippet from gitHub and update the local version" COM_COMPONENTBUILDER_GET_TOKEN="Get Token" COM_COMPONENTBUILDER_GET_TOKEN_FROM_VDM_TO_GET_UPDATE_NOTICE_AND_ADD_IT_TO_YOUR_GLOBAL_OPTIONS="Get token from VDM to get update notice, and add it to your global options." +COM_COMPONENTBUILDER_GIVE_TO_JCB="Give to JCB" COM_COMPONENTBUILDER_GLOBAL="Global" COM_COMPONENTBUILDER_GLUECODE="Glue/Code" COM_COMPONENTBUILDER_GREAT_THIS_FUNCTION_NAME_WILL_WORK="Great, this function name will work!" @@ -5491,6 +5153,7 @@ COM_COMPONENTBUILDER_GREAT_THIS_PLACEHOLDER_WILL_WORK="Great, this placeholder w COM_COMPONENTBUILDER_GREAT_THIS_VALIDATION_RULE_NAME_S_WILL_WORK="Great, this validation rule name (%s) will work!" COM_COMPONENTBUILDER_GROUP="group" COM_COMPONENTBUILDER_HAS_METADATA="Has Metadata" +COM_COMPONENTBUILDER_HEADERS="Headers" COM_COMPONENTBUILDER_HELP_DOCUMENT="Help Document" COM_COMPONENTBUILDER_HELP_DOCUMENTS="Help Documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_ACCESS="Help Documents Access" @@ -5498,7 +5161,7 @@ COM_COMPONENTBUILDER_HELP_DOCUMENTS_ACCESS_DESC="Allows the users in this group COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_OPTIONS="Batch process the selected Help Documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_TIP="All changes will be applied to all selected Help Documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_USE="Help Documents Batch Use" -COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch help documents" +COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_CREATE="Help Documents Create" COM_COMPONENTBUILDER_HELP_DOCUMENTS_CREATE_DESC="Allows the users in this group to create create help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_DASHBOARD_LIST="Help Documents Dashboard List" @@ -5512,7 +5175,7 @@ COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_OWN_DESC="Allows the users in this grou COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_STATE="Help Documents Edit State" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_STATE_DESC="Allows the users in this group to update the state of the help document" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_VERSION="Help Documents Edit Version" -COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version help documents" +COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EXPORT="Help Documents Export" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EXPORT_DESC="Allows the users in this group to export export help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_IMPORT="Help Documents Import" @@ -5590,23 +5253,43 @@ COM_COMPONENTBUILDER_HELP_DOCUMENT_URL_LABEL="URL" COM_COMPONENTBUILDER_HELP_DOCUMENT_URL_MESSAGE="Error! Please add url here." COM_COMPONENTBUILDER_HELP_DOCUMENT_VERSION_DESC="A count of the number of times this Help Document has been revised." COM_COMPONENTBUILDER_HELP_DOCUMENT_VERSION_LABEL="Version" +COM_COMPONENTBUILDER_HELP_JCB_GROW="Help JCB Grow" COM_COMPONENTBUILDER_HELP_MANAGER="Help" +COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_THE_REPLACE_TEXT_THAT_YOU_WOULD_LIKE_TO_USE_AS_REPLACEMENT_FOR_THE_SEARCH_TEXT_FOUND="Here you can enter the replace text that you would like to use as replacement for the search text found." +COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_YOUR_SEARCH_TEXT="Here you can enter your search text." +COM_COMPONENTBUILDER_HERE_YOU_CAN_SET_THE_PATH_TO_THE_SUPER_POWERS_LOCAL_REPOSITORY_FOLDER_WHERE_BLAYERCOREB_AND_ALL_TARGETED_BLAYEROWNB_SUB_PATHS_WILL_BE_PLACED_WITH_THEIR_SELECTIVE_BSWITCHAPPROVEDB_POWERS="Here you can set the path to the super powers local repository folder, where [layer:core] and all targeted [layer:own] sub paths will be placed with their selective [switch:approved] powers." COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP="

%s

" COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP="

%s

" COM_COMPONENTBUILDER_HI="Hi" COM_COMPONENTBUILDER_HIDE_ONLY="Hide Only" COM_COMPONENTBUILDER_HIDE_TOGGLE="Hide Toggle" COM_COMPONENTBUILDER_HOW_TO_GET_A_S_FREE_KEYSA_FROM_VDM="How to get free keys from VDM." +COM_COMPONENTBUILDER_HR_HTHREECUSTOM_CODES_WARNINGHTHREE="

Custom Codes Warning

" +COM_COMPONENTBUILDER_HR_HTHREECZEROMPZERONTHREENT_ISSUE_FOUNDHTHREEPTHE_PATH_S_COULD_NOT_BE_USEDP="

c0mp0n3nt issue found

The path (%s) could not be used.

" +COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE="

Dashboard Error

" +COM_COMPONENTBUILDER_HR_HTHREEDYNAMIC_BUTTON_ERRORHTHREE="

Dynamic Button Error

" +COM_COMPONENTBUILDER_HR_HTHREEDYNAMIC_FOLDERS_WERE_DETECTEDHTHREE="

Dynamic folder(s) were detected.

" +COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_ERRORHTHREE="

External Code Error

" +COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_NOTICEHTHREE="

External Code Notice

" +COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_WARNINGHTHREE="

External Code Warning

" +COM_COMPONENTBUILDER_HR_HTHREEFIELD_NOTICEHTHREE="

Field Notice

" +COM_COMPONENTBUILDER_HR_HTHREEFILE_PATH_ERRORHTHREE="

File Path Error

" +COM_COMPONENTBUILDER_HR_HTHREEFOLDER_PATH_ERRORHTHREE="

Folder Path Error

" +COM_COMPONENTBUILDER_HR_HTHREETIDY_ERRORHTHREE="

Tidy Error

" COM_COMPONENTBUILDER_HTHREEPLACEHOLDER_REMOVEDHTHREEPBTHISB_CUSTOM_CODE_CAN_ONLY_BE_USED_IN_BOTHERB_CUSTOM_CODE_NOT_IN_IT_SELF_SINCE_THAT_WILL_CAUSE_A_INFINITE_LOOP_IN_THE_COMPILERP="

Placeholder Removed!

This custom code can only be used in other custom code, not in it self! Since that will cause a infinite loop in the compiler.

" COM_COMPONENTBUILDER_HTHREESHTHREEPCUSTOM_CODE_CAN_ONLY_BE_USED_IN_OTHER_CUSTOM_CODE_IF_SET_AS_BJCB_MANUALB_YOU_CAN_NOT_ADD_THEM_TO_EMHASH_AUTOMATIONEM_CODE_AT_THIS_POINTP="

%s

Custom code can only be used in other custom code if set as JCB (manual), you can not add them to Hash (Automation) code at this point.

" +COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_S_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP="

%s namespace error (%s)

You must at-least have two sections in your namespace, you just have one (%s). This is an unacceptable action, please see psr-4 for more info.

This %s was therefore removed, click here to fix this issue.

" +COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP="

%s namespace error (%s)

You must at-least have two sections in your namespace, you just have one. This is an unacceptable action, please see psr-4 for more info.

This %s was therefore removed, click here to fix this issue.

" COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_BCOMPONENTBUILDERB_WILL_NOT_FUNCTION_CORRECTLYP="

Curl Not Found!

Please setup curl on your system, or componentbuilder will not function correctly!

" COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BKEY_ERRORB_OR_BROKEN_PACKAGE="

Data is corrupt!

This could be due to key error, or broken package!" COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BROKEN_PACKAGE="

Data is corrupt!

This could be due to broken package!" -COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEZEROELEVENPRO_OR_VTWOONETWOSEVENTEENPUBLIC_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB="

We could not open the encrypt data!

This could be due to the FOFEncryption that is no longer supported in Joomla.
Please export your packages with JCB v3.0.11(pro) or v2.12.17(public) or higher to be able to import it into this version of JCB." +COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEONEONEEIGHT_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB="

We could not open the encrypt data!

This could be due to the FOFEncryption that is no longer supported in Joomla.
Please export your packages with JCB v3.1.18 or higher to be able to import it into this version of JCB." COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_PACKAGEHTWOTHIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLA_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEZEROELEVENPRO_OR_VTWOONETWOSEVENTEENPUBLIC_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB="

We could not open the package!

This could be due to the FOFEncryption that is no longer supported in Joomla. Please export your packages with JCB v3.0.11(pro) or v2.12.17(public) or higher to be able to import it into this version of JCB." COM_COMPONENTBUILDER_IAUTHORI_BSB="Author: %s" COM_COMPONENTBUILDER_ICOMPANYI_BSB="Company: %s" COM_COMPONENTBUILDER_ICON="Icon" +COM_COMPONENTBUILDER_ID="id" +COM_COMPONENTBUILDER_ID_MISMATCH_WAS_DETECTED_WITH_THE_SSSS_GUI_CODE_FIELD_SO_THE_PLACEHOLDER_WAS_NOT_SET="ID mismatch was detected with the %s.%s.%s.%s GUI code field. So the placeholder was not set." COM_COMPONENTBUILDER_IEMAILI_BSB="Email: %s" COM_COMPONENTBUILDER_IMPORT_BY_GUID_ONLY="Import by GUID only!" COM_COMPONENTBUILDER_IMPORT_CONTINUE="Continue" @@ -5667,20 +5350,79 @@ COM_COMPONENTBUILDER_IMPORT_UNABLE_TO_FIND_IMPORT_PACKAGE="Package to import not COM_COMPONENTBUILDER_IMPORT_UPDATE_DATA="Import Data" COM_COMPONENTBUILDER_IMPORT_UPLOAD_BOTTON="Upload File" COM_COMPONENTBUILDER_INACTIVE="Inactive" +COM_COMPONENTBUILDER_INDENTATION_OPTIONS="Indentation Options" +COM_COMPONENTBUILDER_INIT="Init" +COM_COMPONENTBUILDER_INITIALIZATION_FAILED="Initialization Failed!" +COM_COMPONENTBUILDER_INVEST_IN_JCB="Invest in JCB" +COM_COMPONENTBUILDER_INVEST_IN_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_BY_MAKING_A_BFINANCIAL_CONTRIBUTIONB_NO_MATTER_HOW_SMALL_THE_CONTINUAL_SUPPORT_OF_ALL_THOSE_USING_THE_TOOL_WILL_BE_MORE_THAN_ENOUGH_TO_ENSURE_ITS_CONTINUED_GROWTH_AND_RELEVANCE_BY_INVESTING_IN_THIS_OPENSOURCE_PROJECT_YOU_ARE_SECURING_ITS_FUTURE_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS="Invest in the future of Joomla Component Builder (JCB) by making a financial contribution, no matter how small. The continual support of all those using the tool will be more than enough to ensure its continued growth and relevance. By investing in this open-source project, you are securing its future as a vital tool for PHP programmers." +COM_COMPONENTBUILDER_INVEST_IN_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_BY_MAKING_A_BFINANCIAL_DONATIONB_SUPPORT_THE_NECESSARY_DEVELOPMENT_AND_MAINTENANCE_OF_THIS_OPENSOURCE_PROJECT_ENSURING_ITS_CONTINUED_GROWTH_AND_RELEVANCE_FOR_THE_COMMUNITY_YOUR_CONTRIBUTION_WILL_HELP_SECURE_THE_FUTURE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS="Invest in the future of Joomla Component Builder (JCB) by making a financial donation. Support the necessary development and maintenance of this open-source project, ensuring its continued growth and relevance for the community. Your contribution will help secure the future of this vital tool for PHP programmers." COM_COMPONENTBUILDER_IN_SYNC="In Sync" COM_COMPONENTBUILDER_ISOLATE="Isolate" COM_COMPONENTBUILDER_IS_BEING_COMPILED="is being compiled" COM_COMPONENTBUILDER_IS_NOT_ONLY_FOUR_LISTRADIOCHECKBOXES="Is Not (only 4 list/radio/checkboxes)" COM_COMPONENTBUILDER_IS_ONLY_FOUR_LISTRADIOCHECKBOXES="Is (only 4 list/radio/checkboxes)" +COM_COMPONENTBUILDER_ITEM_CODE="Item Code" COM_COMPONENTBUILDER_IWEBSITEI_BSB="Website: %s" +COM_COMPONENTBUILDER_JCB_BE_THE_CHANGE="JCB: Be the Change" +COM_COMPONENTBUILDER_JCB_BUILDS_A_BETTER_FUTURE="JCB Builds a Better Future" COM_COMPONENTBUILDER_JCB_COMMUNITY="JCB Community" COM_COMPONENTBUILDER_JCB_COMMUNITY_PACKAGES="JCB Community Packages" COM_COMPONENTBUILDER_JCB_COMMUNITY_SNIPPETS="JCB Community Snippets" +COM_COMPONENTBUILDER_JCB_CONTRIBUTES_TO_OPENSOURCE="JCB Contributes to Open-Source" +COM_COMPONENTBUILDER_JCB_EMPOWERS_PHP_DEVELOPERS="JCB Empowers PHP Developers" +COM_COMPONENTBUILDER_JCB_ENABLES_PHP_DEVELOPMENT="JCB Enables PHP Development" +COM_COMPONENTBUILDER_JCB_ENHANCES_PRODUCTIVITY="JCB Enhances Productivity" +COM_COMPONENTBUILDER_JCB_FOSTERS_A_STRONG_COMMUNITY="JCB Fosters a Strong Community" +COM_COMPONENTBUILDER_JCB_HELPS_GROW_BUSINESSES="JCB Helps Grow Businesses" +COM_COMPONENTBUILDER_JCB_HELPS_PHP_THRIVE="JCB Helps PHP Thrive" +COM_COMPONENTBUILDER_JCB_IMPROVES_PHPS_REPUTATION="JCB Improves PHP's Reputation" +COM_COMPONENTBUILDER_JCB_IMPROVES_PHP_DEVELOPMENT="JCB Improves PHP Development" +COM_COMPONENTBUILDER_JCB_IMPROVES_USER_EXPERIENCE="JCB Improves User Experience" +COM_COMPONENTBUILDER_JCB_IMPROVES_WORKFLOW="JCB Improves Workflow" +COM_COMPONENTBUILDER_JCB_INCREASES_DEVELOPMENT_SPEED="JCB Increases Development Speed" +COM_COMPONENTBUILDER_JCB_INCREASES_REVENUE="JCB Increases Revenue" +COM_COMPONENTBUILDER_JCB_INCREASES_USER_SATISFACTION="JCB Increases User Satisfaction" +COM_COMPONENTBUILDER_JCB_INVESTS_IN_PHPS_SUCCESS="JCB Invests in PHP's Success" +COM_COMPONENTBUILDER_JCB_INVEST_IN_CHANGE="JCB: Invest in Change" +COM_COMPONENTBUILDER_JCB_INVEST_IN_IMPACT="JCB: Invest in Impact" +COM_COMPONENTBUILDER_JCB_INVEST_IN_PROGRESS="JCB: Invest in Progress" +COM_COMPONENTBUILDER_JCB_INVEST_IN_PROGRESS_TODAY="JCB: Invest in Progress Today" +COM_COMPONENTBUILDER_JCB_INVEST_IN_SUCCESS="JCB: Invest in Success" +COM_COMPONENTBUILDER_JCB_INVEST_IN_THE_COMMUNITY="JCB: Invest in the Community" +COM_COMPONENTBUILDER_JCB_INVEST_IN_THE_FUTURE="JCB: Invest in the Future" +COM_COMPONENTBUILDER_JCB_INVEST_IN_YOUR_FUTURE="JCB: Invest in Your Future" +COM_COMPONENTBUILDER_JCB_IS_NOT_YET_FULLY_READY_FOR_JOOMLA_FOUR_BUT_WITH_YOUR_HELP_WE_CAN_MAKE_THE_TRANSITION_FASTER_SHOW_YOUR_SUPPORT_BY_MAKING_A_DONATION_TODAY_AND_HELP_US_BRING_JCB_TO_THE_NEXT_LEVELBR_BR_BYOUR_COMPONENT_WILL_STILL_ONLY_BE_COMPILED_FOR_JOOMLA_THREEB="JCB is not yet fully ready for Joomla 4, but with your help, we can make the transition faster. Show your support by making a donation today and help us bring JCB to the next level.

Your component will still only be compiled for Joomla 3" +COM_COMPONENTBUILDER_JCB_LOWERS_DEVELOPMENT_STRESS="JCB Lowers Development Stress" +COM_COMPONENTBUILDER_JCB_NEEDS_YOU="JCB Needs You" +COM_COMPONENTBUILDER_JCB_OFFERS_A_STRONGER_SOLUTION="JCB Offers a Stronger Solution" +COM_COMPONENTBUILDER_JCB_OFFERS_MORE_FEATURES="JCB Offers More Features" COM_COMPONENTBUILDER_JCB_PACKAGE_IMPORT="JCB Package Import" COM_COMPONENTBUILDER_JCB_PACKAGE_INFO_PATH_DOES_NOT_WORK_WE_ADVICE_YOU_BNOT_TO_CONTINUEB_WITH_THE_IMPORT_OF_THE_SELECTED_PACKAGE="JCB Package info path does not work, we advice you not to continue with the import of the selected package!" +COM_COMPONENTBUILDER_JCB_PROMOTES_EFFICIENCY="JCB Promotes Efficiency" +COM_COMPONENTBUILDER_JCB_PROMOTES_GOODWILL="JCB Promotes Goodwill" +COM_COMPONENTBUILDER_JCB_PROVIDES_A_BETTER_EXPERIENCE="JCB Provides a Better Experience" COM_COMPONENTBUILDER_JCB_PRO_BOARD="JCB Pro board" COM_COMPONENTBUILDER_JCB_PRO_NOTICE_BOARD="JCB Pro Notice Board" +COM_COMPONENTBUILDER_JCB_REDUCES_DEVELOPMENT_COSTS="JCB Reduces Development Costs" +COM_COMPONENTBUILDER_JCB_SAVES_TIME="JCB Saves Time" +COM_COMPONENTBUILDER_JCB_STREAMLINES_DEVELOPMENT="JCB Streamlines Development" +COM_COMPONENTBUILDER_JCB_SUPPORTS_A_THRIVING_ECOSYSTEM="JCB Supports a Thriving Ecosystem" +COM_COMPONENTBUILDER_JCB_SUPPORTS_A_WORTHY_CAUSE="JCB Supports a Worthy Cause" +COM_COMPONENTBUILDER_JCB_SUPPORTS_OPENSOURCE="JCB Supports Open-Source" +COM_COMPONENTBUILDER_JCB_SUPPORTS_PHP_INNOVATION="JCB Supports PHP Innovation" +COM_COMPONENTBUILDER_JCB_SUPPORTS_THE_PHP_COMMUNITY="JCB Supports the PHP Community" +COM_COMPONENTBUILDER_JCB_YOUR_CONTRIBUTION_MATTERS="JCB: Your Contribution Matters" +COM_COMPONENTBUILDER_JCB_YOUR_DONATION_MATTERS="JCB: Your Donation Matters" +COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_COUNTS="JCB: Your Support Counts" +COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_IS_KEY="JCB: Your Support is Key" +COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_MATTERS="JCB: Your Support Matters" +COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_MATTERS_MOST="JCB: Your Support Matters Most" COM_COMPONENTBUILDER_JOIN_FIELDS="Join Fields" +COM_COMPONENTBUILDER_JOIN_JCBS_COMMUNITY="Join JCB's Community" +COM_COMPONENTBUILDER_JOIN_JCBS_JOURNEY="Join JCB's Journey" +COM_COMPONENTBUILDER_JOIN_JCBS_MISSION="Join JCB's Mission" +COM_COMPONENTBUILDER_JOIN_JCBS_SUCCESS="Join JCB's Success" +COM_COMPONENTBUILDER_JOIN_JCBS_VISION="Join JCB's Vision" COM_COMPONENTBUILDER_JOIN_TYPE="Join Type" COM_COMPONENTBUILDER_JOOMLA_COMPONENT="Joomla Component" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS="Joomla Components" @@ -5689,7 +5431,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_ACCESS_DESC="Allows the users in this gro COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_OPTIONS="Batch process the selected Joomla Components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_TIP="All changes will be applied to all selected Joomla Components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE="Joomla Components Batch Use" -COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla components" +COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_CODE_NAME="Code Name" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_COMPANY_DETAILS="Company Details" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_CREATE="Joomla Components Create" @@ -5710,7 +5452,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_OWN_DESC="Allows the users in this g COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_STATE="Joomla Components Edit State" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla component" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION="Joomla Components Edit Version" -COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla components" +COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_N_ITEMS_ARCHIVED="%s Joomla Components archived." COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_N_ITEMS_ARCHIVED_1="%s Joomla Component archived." COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_N_ITEMS_CHECKED_IN_0="No Joomla Component successfully checked in." @@ -5739,6 +5481,8 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDREADME_LABEL="Add README" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDUIKIT_DESCRIPTION="Select the version of Uikit you would like to use." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDUIKIT_LABEL="Add Uikit" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_ADMIN_EVENT_LABEL="Add Global Admin Event" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_BACKUP_FOLDER_PATH_DESCRIPTION="Would you like to override the global backup folder path for this component?" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_BACKUP_FOLDER_PATH_LABEL="Backup Folder Path" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_BOTH_V2_AMP_V3="Add Both v2 & v3" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_CSS_ADMIN_LABEL="Add CSS (admin)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_CSS_SITE_LABEL="Add CSS (site)" @@ -5746,6 +5490,8 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_EMAIL_HELPER_DESCRIPTION="Adding the e COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_EMAIL_HELPER_LABEL="Add Email Helper" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_FOOTABLE_V2="Add FooTable V2" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_FOOTABLE_V3="Add FooTable V3" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_GIT_FOLDER_PATH_DESCRIPTION="Would you like to override the global git folder path for this component?" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_GIT_FOLDER_PATH_LABEL="Git Folder Path" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_JAVASCRIPT_LABEL="Add Javascript" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_LICENSE_DESCRIPTION="Add the option to use the whmcs license add-on in the component." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_LICENSE_LABEL="Add WHMCS
(license add-on)" @@ -5771,9 +5517,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UIKIT_V2="Add Uikit v2" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UIKIT_V3="Add Uikit v3" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UPDATE_SERVER_LABEL="Add Update Server" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADMIN_VIEWS="Admin Views" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_DESCRIPTION="How to apply the assets table fix in JCB.
-SQL (add&remove) this is the default which adds the SQL fix and removes it once the component is uninstalled.
-Intelligent (add&remove+if) same as default, but on uninstall will only remove this fix if no other component needs it. Note that this option will only work with other components that also use the intelligent path." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_DESCRIPTION="How to apply the assets table fix in JCB.
SQL (add&remove) this is the default which adds the SQL fix and removes it once the component is uninstalled.
Intelligent (add&remove+if) same as default, but on uninstall will only remove this fix if no other component needs it. Note that this option will only work with other components that also use the intelligent path." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_LABEL="Assets Table Fix" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_AUTHOR_DESCRIPTION="The Author's Name & Surname." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_AUTHOR_HINT="Author Name & Surname Here" @@ -5782,6 +5526,10 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_AUTHOR_MESSAGE="Error! Please add author n COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACK="Back" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS="Joomla Component Backup Button Access" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS_DESC="Allows the users in this group to access the backup button." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_FOLDER_PATH_DESCRIPTION="Here you can set the path to the backup folder." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_FOLDER_PATH_HINT="/home/user/backup" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_FOLDER_PATH_LABEL="Backup Folder Path" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_FOLDER_PATH_MESSAGE="Error! Please add folder path here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BOM_DESCRIPTION="Select the file that should be used for licensing all files (files found in: administrator/components/com_componentbuilder/compiler)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BOM_LABEL="Licensing Template" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BOTH="Both" @@ -5791,6 +5539,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMPSQL_LABEL="MySQL" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMP_DESCRIPTION="To build the component fields and back-end views dynamically using a mySQL table file." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMP_LABEL="Build Backend-views Dynamically" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDER_BACKUP_KEY="Joomla Component Builder - Backup Key" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDER_JCB_IS_A_CRUCIAL_TOOL_FOR_PHP_PROGRAMMERS_WHO_USE_JOOMLA_TO_EARN_A_LIVING_BY_MAKING_A_BFINANCIAL_DONATIONB_YOU_CAN_SUPPORT_THE_GROWTH_AND_CONTINUITY_OF_THIS_VITAL_RESOURCE_AND_ENSURE_ITS_RELEVANCE_FOR_YEARS_TO_COME_YOUR_CONTRIBUTION_NO_MATTER_HOW_BIG_OR_SMALL_WILL_BE_DEEPLY_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY="Joomla Component Builder (JCB) is a crucial tool for PHP programmers who use Joomla to earn a living. By making a financial donation, you can support the growth and continuity of this vital resource and ensure its relevance for years to come. Your contribution, no matter how big or small, will be deeply appreciated by the project's team and the wider community." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLEAR_TMP_BUTTON_ACCESS="Joomla Component Clear tmp Button Access" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLEAR_TMP_BUTTON_ACCESS_DESC="Allows the users in this group to access the clear tmp button." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLONE_BUTTON_ACCESS="Joomla Component Clone Button Access" @@ -5868,6 +5617,11 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY_HINT="Export Key Here" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY_LABEL="Export Key
(encrypted field)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY_MESSAGE="Error! Please add export key here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_FRONT="Front" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GIT_FOLDER_PATH_DESCRIPTION="Here you can set the path to the git folder." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GIT_FOLDER_PATH_HINT="/home/user/git" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GIT_FOLDER_PATH_LABEL="Git Folder Path" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GIT_FOLDER_PATH_MESSAGE="Error! Please add folder path here." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GLOBAL="Global" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GUID_DESCRIPTION="Globally Unique Identifier" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GUID_HINT="Auto Generated" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GUID_LABEL="GUID" @@ -5894,10 +5648,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_LICENSE_TYPE_LABEL="Implementation" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_LOCK_DOWN_USE_USED_TO_VERIFY_OWNERSHIP="Lock Down Use (used to verify ownership)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_DESCRIPTION="Add the prefix you would like to use. Make sure that it is HTML Character Entities since it is being used in XML." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_HINT="»" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_LABEL="Prefix
-Check out these lists:
-Char-ref or -Emoji
" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_LABEL="Prefix
Check out these lists:
Char-ref or Emoji
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_MESSAGE="Error! Please add some text here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MODIFIED_BY_DESC="The last user that modified this Joomla Component." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MODIFIED_BY_LABEL="Modified By" @@ -5910,8 +5661,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MVC_VERSIONDATE_LABEL="Version Options" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MYSQL="MySQL" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_DESCRIPTION="Add Name in Code Here" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_HINT="codename" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_LABEL="Name in Code
-Naming Conventions" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_LABEL="Name in Code
Naming Conventions" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_MESSAGE="Error! Please add name in code here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_DESCRIPTION="Enter Name Here" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_HINT="Name Here" @@ -5924,34 +5674,23 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ADD_CONFIG_DESCRIPTION="You can add c COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ADD_CONFIG_LABEL="Adding Custom Config Fields" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ADD_CUSTOM_MENUS_DESCRIPTION="You can add custom menus to the component here. The normal Menus are already being added so only add custom Menus that you would like to use for custom scripts." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ADD_CUSTOM_MENUS_LABEL="Adding Custom Menus" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BACKUP_FOLDER_PATH_DESCRIPTION="You component, and all other linked extensions will be placed as zip files inside this folder." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BACKUP_FOLDER_PATH_LABEL="Adding a backup folder export option" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BOTTON_COMPONENT_DASHBOARD_DESCRIPTION="

The default dashboard has all the icons of the views you have selected as Dashboard (add record) or Dashboard (list of records), to expand it you can add more tabs.

" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BOTTON_COMPONENT_DASHBOARD_LABEL="Default Dashboard Option" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BUILDCOMP_DYNAMIC_MYSQL_DESCRIPTION="You can dynamically build the components back-end views and fields by adding a mySql table dump, that has all the tables, or some more tables with its columns and data types. A very basic and generic set of fields and tables will be created, and added to the existing fields and tables of this component." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BUILDCOMP_DYNAMIC_MYSQL_LABEL="Dynamic Builder (mySql) Option" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_COMPONENT_FILES_FOLDERS_DESCRIPTION="You can add custom files and folders to the component, simply add the files to the administrator/components/com_componentbuilder/custom folder and then select them here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_COMPONENT_FILES_FOLDERS_LABEL="Adding Custom Files & Folder" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_CROWDIN_DESCRIPTION="
-

Feature not ready?

-

We are still working on this integration, so it is not fully ready.

-
-
-
-

How to use Crowdin with JCB?

-

You will need an account with Crowdin https://crowdin.com/, then setup a project following these steps https://support.crowdin.com/creating-project/
-Once your project is created get the project API key following these steps https://support.crowdin.com/api/api-integration-setup/
-Then add the Project API key and identifier details below, and your done! Next time you compile this component JCB will automatically sync your project with Crowdin.

-
-
-
-
-
-
" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_CROWDIN_DESCRIPTION="

Feature not ready?

We are still working on this integration, so it is not fully ready.

How to use Crowdin with JCB?

You will need an account with Crowdin https://crowdin.com/, then setup a project following these steps https://support.crowdin.com/creating-project/
Once your project is created get the project API key following these steps https://support.crowdin.com/api/api-integration-setup/
Then add the Project API key and identifier details below, and your done! Next time you compile this component JCB will automatically sync your project with Crowdin.

" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_CROWDIN_LABEL="Crowdin" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DISPLAY_COMPONENT_ADMIN_VIEWS_DESCRIPTION="

Linked Admin Views

Display of the admin views will load here!
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DISPLAY_COMPONENT_CUSTOM_ADMIN_VIEWS_DESCRIPTION="

Linked Custom Admin Views

Display of the custom admin views will load here!
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DISPLAY_COMPONENT_SITE_VIEWS_DESCRIPTION="

Linked Site Views

Display of the site views will load here!
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DYNAMIC_DASHBOARD_DESCRIPTION="The dynamic dashboard is basically the option of taking an Admin View or Custom Admin View that is already linked to this component, and making it the dashboard." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DYNAMIC_DASHBOARD_LABEL="Dynamic Dashboard Option" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_GIT_FOLDER_PATH_DESCRIPTION="You must set the folder where the component and all linked extensions should be deployed for git. You will have to still do your git commit and other git commands yourself. Each extension will create their own folder inside this git folder." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_GIT_FOLDER_PATH_LABEL="Adding a git path to your component" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_MOVED_VIEWS_DESCRIPTION="We have moved the views in to their own tabs for your convenience." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_MOVED_VIEWS_LABEL="To add views, please open the corresponding tab." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_MYSQL_TWEAK_OPTIONS_DESCRIPTION="In each admin view you can add data from a MySQL Table (this is done in the admin view MySQL tab). Here you can limit that data in relation to this component. This feature is useful when an admin view with demo data is used in more then one component, and you would like to exclude some demo data without creating a new admin view." @@ -5964,61 +5703,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_CUSTOM_ADMIN_VIEWS_DESCRIPTION="Do COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_CUSTOM_ADMIN_VIEWS_LABEL="Setting Custom Admin Views" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_SITE_VIEWS_DESCRIPTION="Do not add the same view twice it will not work. Please watch this tutorial for more help." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_SITE_VIEWS_LABEL="Setting Site Views" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_README_DESCRIPTION="

Need help, visit Markdown-Cheatsheet

- -# ###Component_name### (###VERSION###)
-
-###DESCRIPTION###
-
-# Build Details
-
-+ *Company*: [###COMPANYNAME###](###AUTHORWEBSITE###)
-+ *Author*: [###AUTHOR###](mailto:###AUTHOREMAIL###)
-+ *Name*: [###Component_name###](###AUTHORWEBSITE###)
-+ *First Build*: ###CREATIONDATE###
-+ *Last Build*: ###BUILDDATE###
-+ *Version*: ###VERSION###
-+ *Copyright*: ###COPYRIGHT###
-+ *License*: ###LICENSE###
-
-## Build Time
-
-**###totalHours### Hours** or **###totalDays### Eight Hour Days** (actual time the author saved -
-due to [Automated Component Builder](http://joomlacomponentbuilder.com))
-
-> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
-> never making one mistake or taking any coffee break.)
-
-+ *Line count*: **###LINE_COUNT###**
-+ *File count*: **###FILE_COUNT###**
-+ *Folder count*: **###FOLDER_COUNT###**
-
-**###actualHoursSpent### Hours** or **###actualDaysSpent### Eight Hour Days** (the actual time the author spent)
-
-> (with the following break down:
-> **debugging @###debuggingHours###hours** = codingtime / 4;
-> **planning @###planningHours###hours** = codingtime / 7;
-> **mapping @###mappingHours###hours** = codingtime / 10;
-> **office @###officeHours###hours** = codingtime / 6;)
-
-**###actualTotalHours### Hours** or **###actualTotalDays### Eight Hour Days**
-(a total of the realistic time frame for this project)
-
-> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
-> with the normal everyday realities at the office, that includes the component planning, mapping & debugging.)
-
-Project duration: **###projectWeekTime### weeks** or **###projectMonthTime### months**
-
-> This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com).
-> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
-
-## Donations
-
- If you want to support this project, please consider donating:
- * PayPal: [paypal.me/donationgeek](https://www.paypal.me/donationgeek)
- * Bitcoin: 18vURxYpPFjvNk8BnUy1ovCAyQmY3MzkSf
- * Ethereum: 0x9548144662b47327c954f3e214edb96662d51218 -
" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_README_DESCRIPTION="

Need help, visit Markdown-Cheatsheet

# ###Component_name### (###VERSION###)

###DESCRIPTION###

# Build Details

+ *Company*: [###COMPANYNAME###](###AUTHORWEBSITE###)
+ *Author*: [###AUTHOR###](mailto:###AUTHOREMAIL###)
+ *Name*: [###Component_name###](###AUTHORWEBSITE###)
+ *First Build*: ###CREATIONDATE###
+ *Last Build*: ###BUILDDATE###
+ *Version*: ###VERSION###
+ *Copyright*: ###COPYRIGHT###
+ *License*: ###LICENSE###

## Build Time

**###totalHours### Hours** or **###totalDays### Eight Hour Days** (actual time the author saved -
due to [Automated Component Builder](https://www.joomlacomponentbuilder.com))

> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
> never making one mistake or taking any coffee break.)

+ *Line count*: **###LINE_COUNT###**
+ *File count*: **###FILE_COUNT###**
+ *Folder count*: **###FOLDER_COUNT###**

**###actualHoursSpent### Hours** or **###actualDaysSpent### Eight Hour Days** (the actual time the author spent)

> (with the following break down:
> **debugging @###debuggingHours###hours** = codingtime / 4;
> **planning @###planningHours###hours** = codingtime / 7;
> **mapping @###mappingHours###hours** = codingtime / 10;
> **office @###officeHours###hours** = codingtime / 6;)

**###actualTotalHours### Hours** or **###actualTotalDays### Eight Hour Days**
(a total of the realistic time frame for this project)

> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
> with the normal everyday realities at the office, that includes the component planning, mapping & debugging.)

Project duration: **###projectWeekTime### weeks** or **###projectMonthTime### months**

> This **component** was build with a Joomla [Automated Component Builder](https://www.joomlacomponentbuilder.com).
> Developed by [Llewellyn van der Merwe](mailto:joomla@vdm.io)

## Donations

If you want to support this project, please consider donating:
* Open Collective: [Joomla-Component-Builder](https://opencollective.com/Joomla-Component-Builder)
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_README_LABEL="Demo README (with all place-holders)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_UPDATE_SERVER_NOTE_FTP_DESCRIPTION="During compilation the file will be moved to the server. You still need to point the above update server url to the xml file location on your server for it to work correctly." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_UPDATE_SERVER_NOTE_FTP_LABEL="Select the server used for your update server." @@ -6035,6 +5720,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOT_REQUIRED="Not Required" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NUMBER_LABEL="Number" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_OTHER="Other" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_OVERRIDE="Override" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PERMISSION="Permissions" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_ADMIN_EVENT_DESCRIPTION="PHP script for the global helper admin event method." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_ADMIN_EVENT_LABEL="Global Helper Admin Event (method)" @@ -6136,6 +5822,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_WHMCS_URL_MESSAGE="Error! Please add websi COM_COMPONENTBUILDER_JOOMLA_COMPONENT_YES="Yes" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ZIP="ZIP" COM_COMPONENTBUILDER_JOOMLA_FIELDS="Joomla fields" +COM_COMPONENTBUILDER_JOOMLA_FOUR="Joomla 4" COM_COMPONENTBUILDER_JOOMLA_MODULE="Joomla Module" COM_COMPONENTBUILDER_JOOMLA_MODULES="Joomla Modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_ACCESS="Joomla Modules Access" @@ -6143,7 +5830,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_ACCESS_DESC="Allows the users in this group COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_OPTIONS="Batch process the selected Joomla Modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_TIP="All changes will be applied to all selected Joomla Modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_USE="Joomla Modules Batch Use" -COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla modules" +COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_CREATE="Joomla Modules Create" COM_COMPONENTBUILDER_JOOMLA_MODULES_CREATE_DESC="Allows the users in this group to create create joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_DASHBOARD_LIST="Joomla Modules Dashboard List" @@ -6161,7 +5848,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_OWN_DESC="Allows the users in this grou COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_STATE="Joomla Modules Edit State" COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla module" COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_VERSION="Joomla Modules Edit Version" -COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla modules" +COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_EXPORT="Joomla Modules Export" COM_COMPONENTBUILDER_JOOMLA_MODULES_EXPORT_DESC="Allows the users in this group to export export joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS="Joomla Modules Files, Folders & URLs" @@ -6170,7 +5857,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_ACCESS_DESC="Allows the u COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_OPTIONS="Batch process the selected Joomla Modules Files, Folders & URLs" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_TIP="All changes will be applied to all selected Joomla Modules Files, Folders & URLs" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_USE="Joomla Modules Files Folders Urls Batch Use" -COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla modules files folders urls" +COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_CREATE="Joomla Modules Files Folders Urls Create" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_CREATE_DESC="Allows the users in this group to create create joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_DELETE="Joomla Modules Files Folders Urls Delete" @@ -6186,7 +5873,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_OWN_DESC="Allows the COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_STATE="Joomla Modules Files Folders Urls Edit State" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla module files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_VERSION="Joomla Modules Files Folders Urls Edit Version" -COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla modules files folders urls" +COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_N_ITEMS_ARCHIVED="%s Joomla Modules Files, Folders & URLs archived." COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_N_ITEMS_ARCHIVED_1="%s Joomla Module Files, Folders & URLs archived." COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_N_ITEMS_CHECKED_IN_0="No Joomla Module Files, Folders & URLs successfully checked in." @@ -6235,7 +5922,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_ACCESS_DESC="Allows the users in thi COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_OPTIONS="Batch process the selected Joomla Modules Updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_TIP="All changes will be applied to all selected Joomla Modules Updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_USE="Joomla Modules Updates Batch Use" -COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla modules updates" +COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_CREATE="Joomla Modules Updates Create" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_CREATE_DESC="Allows the users in this group to create create joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_DELETE="Joomla Modules Updates Delete" @@ -6251,7 +5938,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_OWN_DESC="Allows the users in t COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_STATE="Joomla Modules Updates Edit State" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla module updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_VERSION="Joomla Modules Updates Edit Version" -COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla modules updates" +COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_N_ITEMS_ARCHIVED="%s Joomla Modules Updates archived." COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_N_ITEMS_ARCHIVED_1="%s Joomla Module Updates archived." COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_N_ITEMS_CHECKED_IN_0="No Joomla Module Updates successfully checked in." @@ -6383,42 +6070,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_FULLPATH_ COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_URLS_DESCRIPTION="You can add urls here, and it can be used in three ways. As a direct link (default) or to get the file content and add it to the component (get) or as both local and link (dynamic)" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_URLS_LABEL="Adding Urls" -COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTNEW_DESCRIPTION="Should file be updated." COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTNEW_LABEL="Update" @@ -6478,13 +6130,9 @@ COM_COMPONENTBUILDER_JOOMLA_MODULE_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_JOOMLA_MODULE_NEW="A New Joomla Module" COM_COMPONENTBUILDER_JOOMLA_MODULE_NO="No" COM_COMPONENTBUILDER_JOOMLA_MODULE_NONE="None" -COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" -COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LIBRARIES_OPTIONS_DESCRIPTION="

All libraries added to modules are added to the component media folder for now

-

So over here you are able to manually add HTML code to your model default tmpl.

" +COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LIBRARIES_OPTIONS_DESCRIPTION="

All libraries added to modules are added to the component media folder for now

So over here you are able to manually add HTML code to your model default tmpl.

" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LIBRARIES_OPTIONS_LABEL="Libraries Options" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LINKED_TO_NOTICE_DESCRIPTION="
Searching the database.
" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LINKED_TO_NOTICE_LABEL="Linked To" @@ -6597,7 +6245,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_ACCESS_DESC="Allows the users in this group COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_OPTIONS="Batch process the selected Joomla Plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_TIP="All changes will be applied to all selected Joomla Plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_USE="Joomla Plugins Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugins" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_CREATE="Joomla Plugins Create" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_CREATE_DESC="Allows the users in this group to create create joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_DASHBOARD_LIST="Joomla Plugins Dashboard List" @@ -6615,14 +6263,14 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_OWN_DESC="Allows the users in this grou COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_STATE="Joomla Plugins Edit State" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla plugin" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_VERSION="Joomla Plugins Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugins" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS="Joomla Plugins Files, Folders & URLs" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_ACCESS="Joomla Plugins Files Folders Urls Access" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_ACCESS_DESC="Allows the users in this group to access access joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_OPTIONS="Batch process the selected Joomla Plugins Files, Folders & URLs" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_TIP="All changes will be applied to all selected Joomla Plugins Files, Folders & URLs" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_USE="Joomla Plugins Files Folders Urls Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugins files folders urls" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_CREATE="Joomla Plugins Files Folders Urls Create" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_CREATE_DESC="Allows the users in this group to create create joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_DELETE="Joomla Plugins Files Folders Urls Delete" @@ -6638,7 +6286,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_OWN_DESC="Allows the COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_STATE="Joomla Plugins Files Folders Urls Edit State" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla plugin files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_VERSION="Joomla Plugins Files Folders Urls Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugins files folders urls" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_N_ITEMS_ARCHIVED="%s Joomla Plugins Files, Folders & URLs archived." COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_N_ITEMS_ARCHIVED_1="%s Joomla Plugin Files, Folders & URLs archived." COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_N_ITEMS_CHECKED_IN_0="No Joomla Plugin Files, Folders & URLs successfully checked in." @@ -6685,7 +6333,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_ACCESS_DESC="Allows the users in thi COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_OPTIONS="Batch process the selected Joomla Plugins Updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_TIP="All changes will be applied to all selected Joomla Plugins Updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_USE="Joomla Plugins Updates Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugins updates" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_CREATE="Joomla Plugins Updates Create" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_CREATE_DESC="Allows the users in this group to create create joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_DELETE="Joomla Plugins Updates Delete" @@ -6701,7 +6349,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_OWN_DESC="Allows the users in t COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_STATE="Joomla Plugins Updates Edit State" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla plugin updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_VERSION="Joomla Plugins Updates Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugins updates" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_N_ITEMS_ARCHIVED="%s Joomla Plugins Updates archived." COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_N_ITEMS_ARCHIVED_1="%s Joomla Plugin Updates archived." COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_N_ITEMS_CHECKED_IN_0="No Joomla Plugin Updates successfully checked in." @@ -6821,42 +6469,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_FULLPATH_ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_URLS_DESCRIPTION="You can add urls here, and it can be used in three ways. As a direct link (default) or to get the file content and add it to the component (get) or as both local and link (dynamic)" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_URLS_LABEL="Adding Urls" -COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTNEW_DESCRIPTION="Should file be updated." COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTNEW_LABEL="Update" @@ -6891,9 +6504,9 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_ACCESS_DESC="Allows the users in this COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_OPTIONS="Batch process the selected Joomla Plugin Groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_TIP="All changes will be applied to all selected Joomla Plugin Groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_USE="Joomla Plugin Groups Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugin groups" +COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugin groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_EDIT_VERSION="Joomla Plugin Groups Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugin groups" +COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugin groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_N_ITEMS_ARCHIVED="%s Joomla Plugin Groups archived." COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_N_ITEMS_ARCHIVED_1="%s Joomla Plugin Group archived." COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_N_ITEMS_CHECKED_IN_0="No Joomla Plugin Group successfully checked in." @@ -7077,6 +6690,8 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_VERSION_DESC="A count of the number of times COM_COMPONENTBUILDER_JOOMLA_PLUGIN_VERSION_LABEL="Version" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_YES="Yes" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ZIP="ZIP" +COM_COMPONENTBUILDER_JOOMLA_THREE="Joomla 3" +COM_COMPONENTBUILDER_JOOMLA_VERSION="Joomla Version" COM_COMPONENTBUILDER_JUST_GET_ALL_SNIPPETS="Just Get All Snippets" COM_COMPONENTBUILDER_KEEP_HISTORY="Keep History" COM_COMPONENTBUILDER_KEEP_ORIGINAL_ACCESS="- Keep Original Access -" @@ -7095,7 +6710,7 @@ COM_COMPONENTBUILDER_LANGUAGES_ACCESS_DESC="Allows the users in this group to ac COM_COMPONENTBUILDER_LANGUAGES_BATCH_OPTIONS="Batch process the selected Languages" COM_COMPONENTBUILDER_LANGUAGES_BATCH_TIP="All changes will be applied to all selected Languages" COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE="Languages Batch Use" -COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch languages" +COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch languages" COM_COMPONENTBUILDER_LANGUAGES_CREATE="Languages Create" COM_COMPONENTBUILDER_LANGUAGES_CREATE_DESC="Allows the users in this group to create create languages" COM_COMPONENTBUILDER_LANGUAGES_DELETE="Languages Delete" @@ -7107,7 +6722,7 @@ COM_COMPONENTBUILDER_LANGUAGES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_LANGUAGES_EDIT_STATE="Languages Edit State" COM_COMPONENTBUILDER_LANGUAGES_EDIT_STATE_DESC="Allows the users in this group to update the state of the language" COM_COMPONENTBUILDER_LANGUAGES_EDIT_VERSION="Languages Edit Version" -COM_COMPONENTBUILDER_LANGUAGES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version languages" +COM_COMPONENTBUILDER_LANGUAGES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version languages" COM_COMPONENTBUILDER_LANGUAGES_EXPORT="Languages Export" COM_COMPONENTBUILDER_LANGUAGES_EXPORT_DESC="Allows the users in this group to export export languages" COM_COMPONENTBUILDER_LANGUAGES_IMPORT="Languages Import" @@ -7168,7 +6783,7 @@ COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_ACCESS_DESC="Allows the users in this COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_OPTIONS="Batch process the selected Language Translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_TIP="All changes will be applied to all selected Language Translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE="Language Translations Batch Use" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch language translations" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_CREATE="Language Translations Create" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_CREATE_DESC="Allows the users in this group to create create language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_DASHBOARD_LIST="Language Translations Dashboard List" @@ -7182,7 +6797,7 @@ COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_OWN_DESC="Allows the users in th COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_STATE="Language Translations Edit State" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_STATE_DESC="Allows the users in this group to update the state of the language translation" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_VERSION="Language Translations Edit Version" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version language translations" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EXPORT="Language Translations Export" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EXPORT_DESC="Allows the users in this group to export export language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_IMPORT="Language Translations Import" @@ -7249,7 +6864,7 @@ COM_COMPONENTBUILDER_LAYOUTS_ACCESS_DESC="Allows the users in this group to acce COM_COMPONENTBUILDER_LAYOUTS_BATCH_OPTIONS="Batch process the selected Layouts" COM_COMPONENTBUILDER_LAYOUTS_BATCH_TIP="All changes will be applied to all selected Layouts" COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE="Layouts Batch Use" -COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch layouts" +COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch layouts" COM_COMPONENTBUILDER_LAYOUTS_CREATE="Layouts Create" COM_COMPONENTBUILDER_LAYOUTS_CREATE_DESC="Allows the users in this group to create create layouts" COM_COMPONENTBUILDER_LAYOUTS_DASHBOARD_LIST="Layouts Dashboard List" @@ -7264,7 +6879,7 @@ COM_COMPONENTBUILDER_LAYOUTS_EDIT_OWN_DESC="Allows the users in this group to ed COM_COMPONENTBUILDER_LAYOUTS_EDIT_STATE="Layouts Edit State" COM_COMPONENTBUILDER_LAYOUTS_EDIT_STATE_DESC="Allows the users in this group to update the state of the layout" COM_COMPONENTBUILDER_LAYOUTS_EDIT_VERSION="Layouts Edit Version" -COM_COMPONENTBUILDER_LAYOUTS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version layouts" +COM_COMPONENTBUILDER_LAYOUTS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version layouts" COM_COMPONENTBUILDER_LAYOUTS_EXPORT="Layouts Export" COM_COMPONENTBUILDER_LAYOUTS_EXPORT_DESC="Allows the users in this group to export export layouts" COM_COMPONENTBUILDER_LAYOUTS_IMPORT="Layouts Import" @@ -7330,10 +6945,7 @@ COM_COMPONENTBUILDER_LAYOUT_NAME_LABEL="Name" COM_COMPONENTBUILDER_LAYOUT_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_LAYOUT_NEW="A New Layout" COM_COMPONENTBUILDER_LAYOUT_NO="No" -COM_COMPONENTBUILDER_LAYOUT_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_LAYOUT_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_LAYOUT_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_LAYOUT_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." COM_COMPONENTBUILDER_LAYOUT_NOTE_LIBRARIES_SELECTION_LABEL="Select libraries you would like to use in your code" @@ -7360,14 +6972,14 @@ COM_COMPONENTBUILDER_LIBRARIES_ACCESS_DESC="Allows the users in this group to ac COM_COMPONENTBUILDER_LIBRARIES_BATCH_OPTIONS="Batch process the selected Libraries" COM_COMPONENTBUILDER_LIBRARIES_BATCH_TIP="All changes will be applied to all selected Libraries" COM_COMPONENTBUILDER_LIBRARIES_BATCH_USE="Libraries Batch Use" -COM_COMPONENTBUILDER_LIBRARIES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch libraries" +COM_COMPONENTBUILDER_LIBRARIES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch libraries" COM_COMPONENTBUILDER_LIBRARIES_CONFIG="Libraries Config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_ACCESS="Libraries Config Access" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_ACCESS_DESC="Allows the users in this group to access access libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_OPTIONS="Batch process the selected Libraries Config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_TIP="All changes will be applied to all selected Libraries Config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_USE="Libraries Config Batch Use" -COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch libraries config" +COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_CREATE="Libraries Config Create" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_CREATE_DESC="Allows the users in this group to create create libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_DELETE="Libraries Config Delete" @@ -7383,7 +6995,7 @@ COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_STATE="Libraries Config Edit State" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_STATE_DESC="Allows the users in this group to update the state of the library config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_VERSION="Libraries Config Edit Version" -COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_VERSION_DESC="Allows users in this group to edit versions of version libraries config" +COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_N_ITEMS_ARCHIVED="%s Libraries Config archived." COM_COMPONENTBUILDER_LIBRARIES_CONFIG_N_ITEMS_ARCHIVED_1="%s Library Config archived." COM_COMPONENTBUILDER_LIBRARIES_CONFIG_N_ITEMS_CHECKED_IN_0="No Library Config successfully checked in." @@ -7416,14 +7028,14 @@ COM_COMPONENTBUILDER_LIBRARIES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_LIBRARIES_EDIT_STATE="Libraries Edit State" COM_COMPONENTBUILDER_LIBRARIES_EDIT_STATE_DESC="Allows the users in this group to update the state of the library" COM_COMPONENTBUILDER_LIBRARIES_EDIT_VERSION="Libraries Edit Version" -COM_COMPONENTBUILDER_LIBRARIES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version libraries" +COM_COMPONENTBUILDER_LIBRARIES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version libraries" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS="Libraries Files, Folders & URLs" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_ACCESS="Libraries Files Folders Urls Access" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_ACCESS_DESC="Allows the users in this group to access access libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_OPTIONS="Batch process the selected Libraries Files, Folders & URLs" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_TIP="All changes will be applied to all selected Libraries Files, Folders & URLs" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_USE="Libraries Files Folders Urls Batch Use" -COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch libraries files folders urls" +COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_CREATE="Libraries Files Folders Urls Create" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_CREATE_DESC="Allows the users in this group to create create libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_DELETE="Libraries Files Folders Urls Delete" @@ -7439,7 +7051,7 @@ COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_OWN_DESC="Allows the user COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_STATE="Libraries Files Folders Urls Edit State" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_STATE_DESC="Allows the users in this group to update the state of the library files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_VERSION="Libraries Files Folders Urls Edit Version" -COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version libraries files folders urls" +COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_N_ITEMS_ARCHIVED="%s Libraries Files, Folders & URLs archived." COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_N_ITEMS_ARCHIVED_1="%s Library Files, Folders & URLs archived." COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_N_ITEMS_CHECKED_IN_0="No Library Files, Folders & URLs successfully checked in." @@ -7592,42 +7204,7 @@ COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_FULLPATH_LABEL= COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_URLS_DESCRIPTION="You can add urls here, and it can be used in three ways. As a direct link (default) or to get the file content and add it to the component (get) or as both local and link (dynamic)" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_URLS_LABEL="Adding Urls" -COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTNEW_DESCRIPTION="Should file be updated." COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTNEW_LABEL="Update" @@ -7735,17 +7312,26 @@ COM_COMPONENTBUILDER_LIBRARY_VERSION_DESC="A count of the number of times this L COM_COMPONENTBUILDER_LIBRARY_VERSION_LABEL="Version" COM_COMPONENTBUILDER_LICENSE="License" COM_COMPONENTBUILDER_LICENSE_S="License: %s" +COM_COMPONENTBUILDER_LINE="line" +COM_COMPONENTBUILDER_LINES="lines" COM_COMPONENTBUILDER_LINK="Link" COM_COMPONENTBUILDER_LINK_LOCAL_DYNAMIC="Link & Local (dynamic)" COM_COMPONENTBUILDER_LINK_TO_THE_CONTRIBUTOR="Link to the contributor" COM_COMPONENTBUILDER_LIST_FIELD="List Field" COM_COMPONENTBUILDER_LIST_VIEW="List View" COM_COMPONENTBUILDER_LOADING="loading" +COM_COMPONENTBUILDER_LOADING_THE_PRIVATE_KEY_FILE_FAILED="Loading the private key file failed" +COM_COMPONENTBUILDER_LOADING_THE_PRIVATE_KEY_TEXT_FAILED="Loading the private key text failed" COM_COMPONENTBUILDER_LOCAL="Local" COM_COMPONENTBUILDER_LOCAL_GET="Local (get)" +COM_COMPONENTBUILDER_LOCAL_POWERS_REPOSITORY_PATH="Local Powers Repository Path" COM_COMPONENTBUILDER_LOCAL_SNIPPET="Local snippet" +COM_COMPONENTBUILDER_LOGIN_FAILED="Login failed" COM_COMPONENTBUILDER_MAIN_MENU="Main Menu" +COM_COMPONENTBUILDER_MAKE_A_DIFFERENCE_WITH_JCB="Make a Difference with JCB" +COM_COMPONENTBUILDER_MANUAL="Manual" COM_COMPONENTBUILDER_MATCH_BEHAVIOUR="Match Behaviour" +COM_COMPONENTBUILDER_MATCH_CASE="Match Case" COM_COMPONENTBUILDER_MATCH_FIELD="Match Field" COM_COMPONENTBUILDER_MATCH_OPTIONS="Match Options" COM_COMPONENTBUILDER_MAX_LENGTH_ONLY_FOUR_TEXT_FIELD="Max Length (only 4 text_field)" @@ -7753,11 +7339,13 @@ COM_COMPONENTBUILDER_MERGE="Merge" COM_COMPONENTBUILDER_METHODS="Methods" COM_COMPONENTBUILDER_MINIFY_JAVASCRIPT="Minify JavaScript" COM_COMPONENTBUILDER_MIN_LENGTH_ONLY_FOUR_TEXT_FIELD="Min Length (only 4 text_field)" +COM_COMPONENTBUILDER_MODE="Mode" COM_COMPONENTBUILDER_MODEL_AFTER_MODELLING="Model (after modelling)" COM_COMPONENTBUILDER_MODEL_BEFORE_MODELLING="Model (before modelling)" COM_COMPONENTBUILDER_MODULE="Module" COM_COMPONENTBUILDER_MODULES="Modules" COM_COMPONENTBUILDER_MOVE="Move" +COM_COMPONENTBUILDER_MOVING_OF_THE_S_FAILED="Moving of the %s failed" COM_COMPONENTBUILDER_NAME="Name" COM_COMPONENTBUILDER_NAME_ASC="Name (Asc)" COM_COMPONENTBUILDER_NAME_DESC="Name (Desc)" @@ -7774,6 +7362,7 @@ COM_COMPONENTBUILDER_NONE_SELECTED="None selected" COM_COMPONENTBUILDER_NOTICE_BOARD="Notice Board" COM_COMPONENTBUILDER_NOTRANSLATION="no-translation" COM_COMPONENTBUILDER_NOT_FOUND_OR_ACCESS_DENIED="Not found, or access denied." +COM_COMPONENTBUILDER_NOT_SAVED="Not saved!" COM_COMPONENTBUILDER_NOT_SET="not set" COM_COMPONENTBUILDER_NOT_TRANSLATED_IN="Not translated in" COM_COMPONENTBUILDER_NO_ACCESS_GRANTED="No Access Granted!" @@ -7787,12 +7376,16 @@ COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_SINCE_INCORRECT_TYPE_REQUESTED="No cr COM_COMPONENTBUILDER_NO_DESCRIPTION_FOUND="No description found." COM_COMPONENTBUILDER_NO_FILES_LINKED="No Files Linked" COM_COMPONENTBUILDER_NO_FOUND="No Found" +COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_IN_S="No instances where found in %s" COM_COMPONENTBUILDER_NO_ITEM_FOUND="No Item Found" COM_COMPONENTBUILDER_NO_KEYS_WERE_FOUND_TO_ADD_AN_EXPORT_KEY_SIMPLY_OPEN_THE_COMPONENT_GO_TO_THE_TAB_CALLED_SETTINGS_BOTTOM_RIGHT_THERE_IS_A_FIELD_CALLED_EXPORT_KEY="No keys were found. To add an export key simply open the component, go to the tab called settings, bottom right there is a field called Export Key." COM_COMPONENTBUILDER_NO_LANGUAGES_FOUND="No Languages Found" COM_COMPONENTBUILDER_NO_LANGUAGES_UPDATE_SERVER_FOUND="No Languages Update server found." +COM_COMPONENTBUILDER_NO_NAMESPACE_FOUND="No Namespace Found" COM_COMPONENTBUILDER_NO_NEED_TO_GET_IT_SINCE_IT_IS_ALREADY_IN_SYNC_WITH_YOUR_LOCAL_VERSION="No need to get it since it is already in sync with your local version" +COM_COMPONENTBUILDER_NO_PATHS_FOUND="No Paths Found" COM_COMPONENTBUILDER_NO_RESULTS_MATCH="No results match" +COM_COMPONENTBUILDER_NO_SELECTION_DETECTED="No selection detected" COM_COMPONENTBUILDER_NO_SNIPPETS_WERE_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN="No snippets were selected, please make a selection and try again!" COM_COMPONENTBUILDER_NO_S_FOUND="No %s Found" COM_COMPONENTBUILDER_NO_S_HAVE_BEEN_LINKED_TO_THIS_VIEW_SOON_AS_THIS_IS_DONE_IT_WILL_BE_DISPLAYED_HERE="No %s have been linked to this view. Soon as this is done it will be displayed here." @@ -7823,6 +7416,8 @@ COM_COMPONENTBUILDER_PAIDLOCKED="Paid/Locked" COM_COMPONENTBUILDER_PATH_CODESCODE="Path: %s" COM_COMPONENTBUILDER_PATH_TO_THE_ZIPPED_PACKAGE_IS_CODESCODE_BR_S_S="Path to the zipped package is: %s
%s %s" COM_COMPONENTBUILDER_PERMISSIONS="Permissions" +COM_COMPONENTBUILDER_PERMISSION_DENIED="Permission Denied!" +COM_COMPONENTBUILDER_PFILE_AT_BSSB_GAVE_THE_FOLLOWING_ERRORBR_SP="

File at %s/%s gave the following error!
%s

" COM_COMPONENTBUILDER_PLACEHOLDER="Placeholder" COM_COMPONENTBUILDER_PLACEHOLDERS="Placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS="Placeholders Access" @@ -7830,7 +7425,7 @@ COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_OPTIONS="Batch process the selected Placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_TIP="All changes will be applied to all selected Placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE="Placeholders Batch Use" -COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE="Placeholders Create" COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_DASHBOARD_LIST="Placeholders Dashboard List" @@ -7844,7 +7439,7 @@ COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE="Placeholders Edit State" COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the placeholder" COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION="Placeholders Edit Version" -COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT="Placeholders Export" COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT_DESC="Allows the users in this group to export export placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_IMPORT="Placeholders Import" @@ -7885,36 +7480,7 @@ COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_DATE_DESC="The date this Placeholder was modified." COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_PLACEHOLDER_NEW="A New Placeholder" -COM_COMPONENTBUILDER_PLACEHOLDER_NOTE_PLACEHOLDERS_PLACEDIN_DESCRIPTION="" +COM_COMPONENTBUILDER_PLACEHOLDER_NOTE_PLACEHOLDERS_PLACEDIN_DESCRIPTION="" COM_COMPONENTBUILDER_PLACEHOLDER_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_PLACEHOLDER_PERMISSION="Permissions" COM_COMPONENTBUILDER_PLACEHOLDER_PUBLISHING="Publishing" @@ -7935,6 +7501,8 @@ COM_COMPONENTBUILDER_PLACES_ACROSS_JCB_WHERE_THIS_S_IS_LINKED="Places across JCB COM_COMPONENTBUILDER_PLEASE_ADD_FILES_TO_S="Please add files to (%s)" COM_COMPONENTBUILDER_PLEASE_ADD_FOLDERS_TO_S="Please add folders to (%s)" COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_LATTER="Please check again latter." +COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA="Please check again soon! and/or follow the progress on %sgit.vdm.dev." +COM_COMPONENTBUILDER_PLEASE_FIRST_MAKE_A_SELECTION_FROM_THE_LIST="Please first make a selection from the list." COM_COMPONENTBUILDER_PLEASE_NOTE_THAT_THIS_PACKAGE_BHAS_NOB_CHECKSUM_VALIDATION="Please note that this package has no checksum validation!" COM_COMPONENTBUILDER_PLEASE_SELECT_A_COMPONENT_THAT_YOU_WOULD_LIKE_TO_COMPILE="Please select a component that you would like to compile." COM_COMPONENTBUILDER_PLEASE_TRY_AGAIN_LATER="Please try again later" @@ -7950,7 +7518,7 @@ COM_COMPONENTBUILDER_POWERS_A_HREFS_TARGET_BLANK_TITLEOPEN_POWERSA_WITH_VERSION_ COM_COMPONENTBUILDER_POWERS_BATCH_OPTIONS="Batch process the selected Powers" COM_COMPONENTBUILDER_POWERS_BATCH_TIP="All changes will be applied to all selected Powers" COM_COMPONENTBUILDER_POWERS_BATCH_USE="Powers Batch Use" -COM_COMPONENTBUILDER_POWERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch powers" +COM_COMPONENTBUILDER_POWERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch powers" COM_COMPONENTBUILDER_POWERS_CREATE="Powers Create" COM_COMPONENTBUILDER_POWERS_CREATE_DESC="Allows the users in this group to create create powers" COM_COMPONENTBUILDER_POWERS_DASHBOARD_LIST="Powers Dashboard List" @@ -7969,7 +7537,7 @@ COM_COMPONENTBUILDER_POWERS_EDIT_OWN_DESC="Allows the users in this group to edi COM_COMPONENTBUILDER_POWERS_EDIT_STATE="Powers Edit State" COM_COMPONENTBUILDER_POWERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the power" COM_COMPONENTBUILDER_POWERS_EDIT_VERSION="Powers Edit Version" -COM_COMPONENTBUILDER_POWERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version powers" +COM_COMPONENTBUILDER_POWERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version powers" COM_COMPONENTBUILDER_POWERS_NAME="Name" COM_COMPONENTBUILDER_POWERS_N_ITEMS_ARCHIVED="%s Powers archived." COM_COMPONENTBUILDER_POWERS_N_ITEMS_ARCHIVED_1="%s Power archived." @@ -7993,11 +7561,26 @@ COM_COMPONENTBUILDER_POWERS_N_ITEMS_UNPUBLISHED_1="%s Power unpublished." COM_COMPONENTBUILDER_POWERS_SUBMENU="Powers Submenu" COM_COMPONENTBUILDER_POWERS_SUBMENU_DESC="Allows the users in this group to submenu of power" COM_COMPONENTBUILDER_POWER_ABSTRACT_CLASS="abstract class" +COM_COMPONENTBUILDER_POWER_ACCESS_POINT_DESCRIPTION="Library path to the autoload.php file" +COM_COMPONENTBUILDER_POWER_ACCESS_POINT_HINT="custom_folder/vendor/autoload.php (must be in the .../public_html/library/ folder of Joomla)" +COM_COMPONENTBUILDER_POWER_ACCESS_POINT_LABEL="Access Point" +COM_COMPONENTBUILDER_POWER_ACCESS_POINT_MESSAGE="Error! Please add autoload full path here." COM_COMPONENTBUILDER_POWER_ADD_HEAD_DESCRIPTION="You can add your own custom header script, combined with the default header script that make the extended class work." COM_COMPONENTBUILDER_POWER_ADD_HEAD_LABEL="Add Custom Class Header" +COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_DESCRIPTION="The option to override the licensing template." +COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_LABEL="Add Licensing Template" +COM_COMPONENTBUILDER_POWER_APPROVED="Approved" +COM_COMPONENTBUILDER_POWER_APPROVED_DESCRIPTION="When you approve a power, it will be added to your local powers folder once linked to a component, and this super power feature is activated. There are two ways to activate this feature, one is in the advanced options on the compiler page, and the other is in the global options of JCB." +COM_COMPONENTBUILDER_POWER_APPROVED_LABEL="Super Power" +COM_COMPONENTBUILDER_POWER_APPROVED_PATHS_DESCRIPTION="Select the paths this power should be added to." +COM_COMPONENTBUILDER_POWER_APPROVED_PATHS_LABEL="Approved Paths" COM_COMPONENTBUILDER_POWER_AS_LABEL="as" +COM_COMPONENTBUILDER_POWER_AUTOLOAD_COMPOSER_NOTE_DESCRIPTION="

Once you have manually pulled composer classes into your own custom folder in libraries area (via composer), you can link it here.

So this feature gives you the ability to add your own custom composer set of classes to your project. Yes, you will still have to manually pull them into your own custom and unique folder into the libraries area of Joomla (on this JCB development system). But you can link it here and JCB will take care of adding it to your component.

First and most importantly (due to obvious risk of collusion), avoid pulling classes into your custom set of composer classes that are already included in the Joomla vendor folder. Those classes that Joomla loads are already available to you. To use them, just add the use Namespace; of that class to the header of this power, and the PHP auto linker will take care of the rest.

So all composer projects =>(vendor folders) has an autoload.php file that is located in the root of the vendor folder. We call this the access point to that cluster of classes. This means you will have one access point for multiple namespaces.

Due the continued risk of collusion we allow only one access point per/power. But for even more peace of mind, it is best to have only one access point per/project. Which means you should try to consolidate your custom composer additional classes (outside of the Joomla vendor folder) into one vendor folder. This will result in one access point, that you will use multiple times for various powers.

Should you want JCB to load the composer classes to your component, you will have to manually link it to the Component Files & Folders area. This is the best option for now (and will always work), but we will soon improve the Library area in JCB to also take care of PHP libraries. Once this option becomes available we will give notice of the change here.

" +COM_COMPONENTBUILDER_POWER_AUTOLOAD_COMPOSER_NOTE_LABEL="When to use Autoloader Composer Powers?" COM_COMPONENTBUILDER_POWER_CLASS="class" COM_COMPONENTBUILDER_POWER_CODE="Code" +COM_COMPONENTBUILDER_POWER_COMPOSER="Composer" +COM_COMPONENTBUILDER_POWER_COMPOSER_LABEL="Autoloader Composer Powers" COM_COMPONENTBUILDER_POWER_CREATED_BY_DESC="The user that created this Power." COM_COMPONENTBUILDER_POWER_CREATED_BY_LABEL="Created By" COM_COMPONENTBUILDER_POWER_CREATED_DATE_DESC="The date this Power was created." @@ -8024,11 +7607,16 @@ COM_COMPONENTBUILDER_POWER_IMPLEMENTS_CUSTOM_LABEL="Implements interface(s) - Cu COM_COMPONENTBUILDER_POWER_IMPLEMENTS_CUSTOM_MESSAGE="Error! Please add the custom interface(s) this class must implement." COM_COMPONENTBUILDER_POWER_IMPLEMENTS_DESCRIPTION="The interface(s), this class should implement." COM_COMPONENTBUILDER_POWER_IMPLEMENTS_LABEL="Implements interface(s)" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS="Power Init Button Access" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS_DESC="Allows the users in this group to access the init button." COM_COMPONENTBUILDER_POWER_INTERFACE="interface" +COM_COMPONENTBUILDER_POWER_JOOMLASUPERPOWERS="joomla/super-powers" +COM_COMPONENTBUILDER_POWER_LICENSING="Licensing" +COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_HINT="/** * @package Joomla.Component.Builder * * @created 4th September, 2015 * @author Llewellyn van der Merwe * @git Joomla Component Builder * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */" +COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_LABEL="Licensing Template" COM_COMPONENTBUILDER_POWER_LOAD="Load" COM_COMPONENTBUILDER_POWER_LOAD_LABEL="load" -COM_COMPONENTBUILDER_POWER_LOAD_POWERS_NOTE_DESCRIPTION="

When you would like to load a power to the project, but you do not want that power to be part of the use namespace declarations in the header of this power.

-

You do not need to again select any power that is already selected in the Extends, Implements, or Use Selection fields, since they are already being loaded.

" +COM_COMPONENTBUILDER_POWER_LOAD_POWERS_NOTE_DESCRIPTION="

When you would like to load a power to the project, but you do not want that power to be part of the use namespace declarations in the header of this power.

You do not need to again select any power that is already selected in the Extends, Implements, or Use Selection fields, since they are already being loaded.

" COM_COMPONENTBUILDER_POWER_LOAD_POWERS_NOTE_LABEL="When to Load Powers Here?" COM_COMPONENTBUILDER_POWER_LOAD_SELECTION_DESCRIPTION="Select powers that you want to make sure also load when this power is loaded." COM_COMPONENTBUILDER_POWER_LOAD_SELECTION_LABEL="Load Powers" @@ -8043,29 +7631,7 @@ COM_COMPONENTBUILDER_POWER_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_POWER_MODIFIED_DATE_DESC="The date this Power was modified." COM_COMPONENTBUILDER_POWER_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_POWER_NAMESPACE_DESCRIPTION="Add the namespace of this class." -COM_COMPONENTBUILDER_POWER_NAMESPACE_DETAILS_DESCRIPTION="
-

We will use the namespace value to build the folder structure and filename. This namespace will also directly be used as the use declaration wherever you link this power. Therefore the namespace declared here must end with the filename, and this file name must match the case of the terminating class name.
-Example (namespace): ComponentName\Sub\ClassName
-JCB will build the following file path
-Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/ClassName.php
-With a four section namespace
-Example (namespace): ComponentName\Sub\Type\ClassName
-JCB will build the following file path
-Example (filepath): root/libraries/jcb_powers/ComponentName.Sub.Type/src/ClassName.php
-To add a folder inside the src folder use [.] in class name
-Example (namespace): ComponentName\Sub\Util.ClassName
-Example (JCB builds this namespace): ComponentName\Sub\Util\ClassName
-JCB will build the following file path
-Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/Util/ClassName.php

- -

The component placeholder also works in namespacing, as well as normal placeholders:
-Example: [[[Component]]]\SubNamespaceNames\ClassName

- -

We will also use the namespacing for auto loading in your project wherever you link this power.

-

The jcb_powers can be changed globally and per/component (soon).
Make your powers load system wide with a plugin (soon).

- -

For more info on how all this works: https://www.php-fig.org/psr/psr-4/

-
" +COM_COMPONENTBUILDER_POWER_NAMESPACE_DETAILS_DESCRIPTION="

We will use the namespace value to build the folder structure and filename. This namespace will also directly be used as the use declaration wherever you link this power. Therefore the namespace declared here must end with the filename, and this file name must match the case of the terminating class name.
Example (namespace): ComponentName\Sub\ClassName
JCB will build the following file path
Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/ClassName.php
With a four section namespace
Example (namespace): ComponentName\Sub\Type\ClassName
JCB will build the following file path
Example (filepath): root/libraries/jcb_powers/ComponentName.Sub.Type/src/ClassName.php
To add a folder inside the src folder use [.] in class name
Example (namespace): ComponentName\Sub\Util.ClassName
Example (JCB builds this namespace): ComponentName\Sub\Util\ClassName
JCB will build the following file path
Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/Util/ClassName.php

The component placeholder also works in namespacing, as well as normal placeholders:
Example: [[[Component]]]\SubNamespaceNames\ClassName

We will also use the namespacing for auto loading in your project wherever you link this power.

The jcb_powers can be changed globally and per/component (soon).
Make your powers load system wide with a plugin (soon).

For more info on how all this works: https://www.php-fig.org/psr/psr-4/

" COM_COMPONENTBUILDER_POWER_NAMESPACE_DETAILS_LABEL="Namespacing in JCB" COM_COMPONENTBUILDER_POWER_NAMESPACE_HINT="ComponentName\Powers\ClassName" COM_COMPONENTBUILDER_POWER_NAMESPACE_LABEL="Namespace" @@ -8076,10 +7642,14 @@ COM_COMPONENTBUILDER_POWER_NAME_LABEL="Name" COM_COMPONENTBUILDER_POWER_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_POWER_NEW="A New Power" COM_COMPONENTBUILDER_POWER_NO="No" +COM_COMPONENTBUILDER_POWER_NOTE_APPROVED_PATHS_DESCRIPTION="

Select the sub paths inside the local path where you would like to add this power. The default is the core JCB path which is joomla/super-powers (this can be changed in the global options)

To set the local path, and to add more sub paths, open the JCB global options, and look for the super power tab, there you will find all the instructions needed.

" +COM_COMPONENTBUILDER_POWER_NOTE_APPROVED_PATHS_LABEL="Super Powers Repositories" COM_COMPONENTBUILDER_POWER_NOTE_LINKED_TO_NOTICE_DESCRIPTION="
Searching the database.
" COM_COMPONENTBUILDER_POWER_NOTE_LINKED_TO_NOTICE_LABEL="Linked To" +COM_COMPONENTBUILDER_POWER_NOT_APPROVED="Not Approved" COM_COMPONENTBUILDER_POWER_NOT_REQUIRED="Not Required" COM_COMPONENTBUILDER_POWER_ORDERING_LABEL="Ordering" +COM_COMPONENTBUILDER_POWER_OVERRIDE="Override" COM_COMPONENTBUILDER_POWER_PERMISSION="Permissions" COM_COMPONENTBUILDER_POWER_POWER_VERSION_DESCRIPTION="Add Version Number Here" COM_COMPONENTBUILDER_POWER_POWER_VERSION_HINT="1.0.0" @@ -8090,10 +7660,13 @@ COM_COMPONENTBUILDER_POWER_PROPERTY_LABEL="Properties" COM_COMPONENTBUILDER_POWER_PROPERTY_SELECTION_DESCRIPTION="Select properties you want to use in your power." COM_COMPONENTBUILDER_POWER_PROPERTY_SELECTION_LABEL="Property Selection" COM_COMPONENTBUILDER_POWER_PUBLISHING="Publishing" +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS="Power Reset Button Access" +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS_DESC="Allows the users in this group to access the reset button." COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS="Power Run Expansion Button Access" COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the users in this group to access the run expansion button." COM_COMPONENTBUILDER_POWER_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the Power to customise the alias." COM_COMPONENTBUILDER_POWER_STATUS="Status" +COM_COMPONENTBUILDER_POWER_SUPER_POWER="Super Power" COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_DESCRIPTION="Used only in the system." COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_HINT="The System Name Here" COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_LABEL="System Name" @@ -8102,52 +7675,86 @@ COM_COMPONENTBUILDER_POWER_TRAIT="trait" COM_COMPONENTBUILDER_POWER_TYPE_DESCRIPTION="The type of power being build" COM_COMPONENTBUILDER_POWER_TYPE_LABEL="Type of Power" COM_COMPONENTBUILDER_POWER_USE="Use" -COM_COMPONENTBUILDER_POWER_USE_LABEL="use" +COM_COMPONENTBUILDER_POWER_USE_GLOBAL="Use Global" +COM_COMPONENTBUILDER_POWER_USE_HINT="Name\Project\ClassName" +COM_COMPONENTBUILDER_POWER_USE_LABEL="Use" +COM_COMPONENTBUILDER_POWER_USE_MESSAGE="Error! Please add namespace here." COM_COMPONENTBUILDER_POWER_USE_SELECTION_DESCRIPTION="Select namespace you want to use in your power." COM_COMPONENTBUILDER_POWER_USE_SELECTION_LABEL="Use Selection" COM_COMPONENTBUILDER_POWER_VERSION_DESC="A count of the number of times this Power has been revised." COM_COMPONENTBUILDER_POWER_VERSION_LABEL="Version" COM_COMPONENTBUILDER_POWER_YES="Yes" +COM_COMPONENTBUILDER_PPOWER_BGUIDSB_NOT_FOUNDP="

Power guid:%s not found!

" COM_COMPONENTBUILDER_PROPERTIES="Properties" COM_COMPONENTBUILDER_PROPERTIESBR_SMALLHERE_YOU_CAN_SET_THE_PROPERTIES_FOR_THIS_FIELDSMALL="Properties
Here you can set the properties for this field." COM_COMPONENTBUILDER_PROPERTY="Property" COM_COMPONENTBUILDER_PROPERTY_ALREADY_SELECTED_TRY_ANOTHER="Property already selected, try another." COM_COMPONENTBUILDER_PROPERTY_NAME="Property Name" COM_COMPONENTBUILDER_PROPERTY_VALUE="Property Value" +COM_COMPONENTBUILDER_PSUPER_POWERB_REPOSITORY_AT_BSSB_GAVE_THE_FOLLOWING_ERRORBR_SP="

Super Power repository at %s/%s gave the following error!
%s

" +COM_COMPONENTBUILDER_PS_NAMING_MISMATCH_ERROR_SPPTHE_S_NAME_IS_BSB_AND_THE_ENDING_FILE_NAME_IN_THE_NAMESPACE_IS_BSB_THIS_IS_BAD_CONVENTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPA_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP="

%s naming mismatch error (%s)

The %s name is %s and the ending file name in the namespace is %s. This is bad convention, please see psr-4 for more info.

Click here to fix this issue.

" COM_COMPONENTBUILDER_PUBLIC_ACCESS="Public Access" COM_COMPONENTBUILDER_PUBLISHED="Published" COM_COMPONENTBUILDER_PUBLISHING="Publishing" COM_COMPONENTBUILDER_README="Readme" COM_COMPONENTBUILDER_READY_TO_COMPILE_A_COMPONENT="Ready to compile a component" COM_COMPONENTBUILDER_REFRESH="Refresh" +COM_COMPONENTBUILDER_REGEX_SEARCH="Regex Search" COM_COMPONENTBUILDER_REMOVE="Remove" COM_COMPONENTBUILDER_REMOVING_ALL_ZIP_PACKAGES_FROM_THE_TEMPORARY_FOLDER_OF_THE_JOOMLA_INSTALL="Removing all zip packages from the temporary folder of the Joomla install" COM_COMPONENTBUILDER_RENAME="Rename" +COM_COMPONENTBUILDER_REPLACE="Replace" +COM_COMPONENTBUILDER_REPLACED_WITH="replaced with" +COM_COMPONENTBUILDER_REPLACE_PROCESS_COMPLETE="replace process complete" COM_COMPONENTBUILDER_REPORT_AN_ISSUE_BSB="Report an issue: %s" COM_COMPONENTBUILDER_REQUIRES_THE_VALUE_ENTERED_BE_ONE_OF_THE_OPTIONS_IN_AN_ELEMENT_OF_TYPEQUOTLISTQUOT_THAT_IS_THAT_THE_ELEMENT_IS_A_SELECT_LIST="Requires the value entered be one of the options in an element of type="list": that is, that the element is a select list." COM_COMPONENTBUILDER_REQUIRES_THE_VALUE_TO_BE_A_TELEPHONE_NUMBER_COMPLYING_WITH_THE_STANDARDS_OF_NANPA_ITUT_TRECEONE_HUNDRED_AND_SIXTY_FOUR_OR_IETF_RFCFOUR_THOUSAND_NINE_HUNDRED_AND_THIRTY_THREE="Requires the value to be a Telephone number complying with the standards of nanpa, ITU-T T-REC-E.164 or ietf rfc4933." COM_COMPONENTBUILDER_REQUIRES_THE_VALUE_TO_BE_THE_SAME_AS_THAT_HELD_IN_THE_FIELD_NAMED_QUOTFIELDQUOT_EGS="Requires the value to be the same as that held in the field named "field", eg:%s" +COM_COMPONENTBUILDER_RESET="Reset" +COM_COMPONENTBUILDER_RESET_FAILED="Reset Failed!" COM_COMPONENTBUILDER_REVERT_ALL_AHEAD_SNIPPETS="Revert All Ahead Snippets" COM_COMPONENTBUILDER_RIGHT_IN_TAB="Right in Tab" COM_COMPONENTBUILDER_RIGHT_OF_TABS="Right of Tabs" COM_COMPONENTBUILDER_RUN_EXPANSION="Run Expansion" +COM_COMPONENTBUILDER_SAVE_ALL_CHANGES_MADE_TO_THE_SELECTED_ITEM="Save all changes made to the selected item." +COM_COMPONENTBUILDER_SAVE_ITEM="Save Item" COM_COMPONENTBUILDER_SAVE_SUCCESS="Great! Item successfully saved." COM_COMPONENTBUILDER_SAVE_WARNING="The value already existed so please select another." COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_A_BGITHUB_ACCESS_TOKENB_TO_COMPONENTBUILDER_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_TO_GITHUB_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO_TO_RETRIEVE_S="%s
You can add a gitHub Access Token to Componentbuilder global options to make authenticated requests to gitHub. An access token with only public access will do to retrieve %s." +COM_COMPONENTBUILDER_SEARCH="Search" COM_COMPONENTBUILDER_SEARCHABLE="Searchable" +COM_COMPONENTBUILDER_SEARCHED_FOR="searched for" +COM_COMPONENTBUILDER_SEARCHING="searching" +COM_COMPONENTBUILDER_SEARCH_ACCESS="Search Access" +COM_COMPONENTBUILDER_SEARCH_ACCESS_DESC="Allows the users in this group to access search." +COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS="Search Compiler Button Access" +COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS_DESC="Allows the users in this group to access the compiler button." +COM_COMPONENTBUILDER_SEARCH_DASHBOARD_LIST="Search Dashboard List" +COM_COMPONENTBUILDER_SEARCH_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of Search" +COM_COMPONENTBUILDER_SEARCH_DATABASE_AGAIN="Search Database Again" +COM_COMPONENTBUILDER_SEARCH_DESC="JCB Search" +COM_COMPONENTBUILDER_SEARCH_OR_SEARCH_AND_REPLACE="Search, or Search and Replace" +COM_COMPONENTBUILDER_SEARCH_SUBMENU="Search Submenu" +COM_COMPONENTBUILDER_SEARCH_SUBMENU_DESC="Allows the users in this group to submenu of Search" +COM_COMPONENTBUILDER_SECONDS="seconds" COM_COMPONENTBUILDER_SEE_ALL_IMPORT_INFO="See All Import Info" COM_COMPONENTBUILDER_SELECTION="selection" COM_COMPONENTBUILDER_SELECT_ADMIN_VIEW="Select Admin View" COM_COMPONENTBUILDER_SELECT_AN_ADMIN_VIEW="Select an admin view" COM_COMPONENTBUILDER_SELECT_AN_OPTION="Select an option" +COM_COMPONENTBUILDER_SELECT_APPROVED_PATH="Select Approved Path" +COM_COMPONENTBUILDER_SELECT_A_NAMESPACE="Select a Namespace" COM_COMPONENTBUILDER_SELECT_A_PROPERTY="Select a property" COM_COMPONENTBUILDER_SELECT_A_SITE_VIEW="Select a site view" COM_COMPONENTBUILDER_SELECT_A_SNIPPET="select a snippet" +COM_COMPONENTBUILDER_SELECT_BUILD_DATE="Select Build Date" COM_COMPONENTBUILDER_SELECT_COMPONENT="Select Component" COM_COMPONENTBUILDER_SELECT_EXTENSION="Select Extension" COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_COMPILE="Select the component to compile" +COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_SEARCH="Select the component to search" COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_YOUR_WOULD_LIKE_TO_IMPORT="Select the component your would like to import." COM_COMPONENTBUILDER_SELECT_THE_PACKAGE_TO_IMPORT="Select the package to import" +COM_COMPONENTBUILDER_SELECT_THE_TABLE_TO_SEARCH="Select the table to search" COM_COMPONENTBUILDER_SERVER="Server" COM_COMPONENTBUILDER_SERVERS="Servers" COM_COMPONENTBUILDER_SERVERS_ACCESS="Servers Access" @@ -8155,7 +7762,7 @@ COM_COMPONENTBUILDER_SERVERS_ACCESS_DESC="Allows the users in this group to acce COM_COMPONENTBUILDER_SERVERS_BATCH_OPTIONS="Batch process the selected Servers" COM_COMPONENTBUILDER_SERVERS_BATCH_TIP="All changes will be applied to all selected Servers" COM_COMPONENTBUILDER_SERVERS_BATCH_USE="Servers Batch Use" -COM_COMPONENTBUILDER_SERVERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch servers" +COM_COMPONENTBUILDER_SERVERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch servers" COM_COMPONENTBUILDER_SERVERS_CREATE="Servers Create" COM_COMPONENTBUILDER_SERVERS_CREATE_DESC="Allows the users in this group to create create servers" COM_COMPONENTBUILDER_SERVERS_DASHBOARD_LIST="Servers Dashboard List" @@ -8173,7 +7780,7 @@ COM_COMPONENTBUILDER_SERVERS_EDIT_OWN_DESC="Allows the users in this group to ed COM_COMPONENTBUILDER_SERVERS_EDIT_STATE="Servers Edit State" COM_COMPONENTBUILDER_SERVERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the server" COM_COMPONENTBUILDER_SERVERS_EDIT_VERSION="Servers Edit Version" -COM_COMPONENTBUILDER_SERVERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version servers" +COM_COMPONENTBUILDER_SERVERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version servers" COM_COMPONENTBUILDER_SERVERS_EXPORT="Servers Export" COM_COMPONENTBUILDER_SERVERS_EXPORT_DESC="Allows the users in this group to export export servers" COM_COMPONENTBUILDER_SERVERS_IMPORT="Servers Import" @@ -8248,21 +7855,7 @@ COM_COMPONENTBUILDER_SERVER_PRIVATE_DESCRIPTION="Set the path to the private key COM_COMPONENTBUILDER_SERVER_PRIVATE_HINT="/home/username/.ssh/id_rsa" COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_DESCRIPTION="Add your private key here! Yes this field is encrypted in the DB, but if your DB gets compromised this key must also be considered compromised! The system path option is considered more secure and seen as best practice." COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_FILE_PATH="Private Key - File Path" -COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_HINT="-----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDPF9uyDuHtD+sCYBaEIV34uAc+eRa62souVUcmsVwKUUBbk7sY -bnO6ixjouEbhis1L4m854895tJ99SSPu5cXxYTFimCJDjp47fjro4x8js9em10kK -VCP2fP60/jO+mTruGc25C1SksMtRj5XlsGW3avoOV2RjsqAwKxhk6AUF6QIDAQAB -AoGAYGGlMOB2S2NeJ7PaptH0rz3OuUeXyYzsDdZIj/x5bp/UCQrfR4aYO9hi1mR1 -MKDt3QRcaZ/ZvrXOiHuSyquLjG0R1tVVR+OZE+haBSunUUq05ZFT7zUJRPHVKoSK -QOV/c831tCA5gCUupXiaak/vYMZRf+xs9wHDyuZstEoU8tUCQQD/GGV/8cuiYQK4 -MlpXgvOeYEYayhbQ80qe2aVolQIlRXyY6N9dV1lfbUO8rlTJ2EDVOFc8NDkPHf2f -xzbplDCDAkEAz9PhT8ji8fJgKuDAhWDXF0TuwVWk2hjtYCVGsksE3w16lv9OCwoK -UuWOY2b7wEYh0y8Z9AKBDHM1xhS8Bl7MIwJBANAkNd1Zi5Aom7Fz1GcHQIR/hXQi -ZM+FU+OdLuvQeXmz4uBZUre0qAXG/7gafrBbNTtEx1kmO1BsZh9Syyl3csUCQQDF -MD4pm2tpMRV52YIRi07J70ex/PbLULd5cCTh6jgXAwz71AVSiBY/jTtKqV3YkzJo -09oGIZIcI/wzk1zLloqNAkB8qHxAtmUZFdo5sssaUDTOB82QAPfiHUqIFPaYuc0f -4NqtXZm+fv4liR3QJEo8zkiBs3NjBnm7Hh3BMSqGh3d+ ------END RSA PRIVATE KEY-----" +COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_HINT="-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDPF9uyDuHtD+sCYBaEIV34uAc+eRa62souVUcmsVwKUUBbk7sYbnO6ixjouEbhis1L4m854895tJ99SSPu5cXxYTFimCJDjp47fjro4x8js9em10kKVCP2fP60/jO+mTruGc25C1SksMtRj5XlsGW3avoOV2RjsqAwKxhk6AUF6QIDAQABAoGAYGGlMOB2S2NeJ7PaptH0rz3OuUeXyYzsDdZIj/x5bp/UCQrfR4aYO9hi1mR1MKDt3QRcaZ/ZvrXOiHuSyquLjG0R1tVVR+OZE+haBSunUUq05ZFT7zUJRPHVKoSKQOV/c831tCA5gCUupXiaak/vYMZRf+xs9wHDyuZstEoU8tUCQQD/GGV/8cuiYQK4MlpXgvOeYEYayhbQ80qe2aVolQIlRXyY6N9dV1lfbUO8rlTJ2EDVOFc8NDkPHf2fxzbplDCDAkEAz9PhT8ji8fJgKuDAhWDXF0TuwVWk2hjtYCVGsksE3w16lv9OCwoKUuWOY2b7wEYh0y8Z9AKBDHM1xhS8Bl7MIwJBANAkNd1Zi5Aom7Fz1GcHQIR/hXQiZM+FU+OdLuvQeXmz4uBZUre0qAXG/7gafrBbNTtEx1kmO1BsZh9Syyl3csUCQQDFMD4pm2tpMRV52YIRi07J70ex/PbLULd5cCTh6jgXAwz71AVSiBY/jTtKqV3YkzJo09oGIZIcI/wzk1zLloqNAkB8qHxAtmUZFdo5sssaUDTOB82QAPfiHUqIFPaYuc0f4NqtXZm+fv4liR3QJEo8zkiBs3NjBnm7Hh3BMSqGh3d+-----END RSA PRIVATE KEY-----" COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_LABEL="PRIVATE KEY
(encrypted field)" COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_TEXT_FIELD="Private Key - Text Field" COM_COMPONENTBUILDER_SERVER_PRIVATE_LABEL="Private Key Path
(encrypted field)" @@ -8288,6 +7881,7 @@ COM_COMPONENTBUILDER_SERVER_VERSION_DESC="A count of the number of times this Se COM_COMPONENTBUILDER_SERVER_VERSION_LABEL="Version" COM_COMPONENTBUILDER_SET_A_CLASS_VALUE_FOR_THE_LIST_VIEW_OF_THIS_FIELD="Set a class value for the list view of this field." COM_COMPONENTBUILDER_SET_CUSTOM="Set Custom" +COM_COMPONENTBUILDER_SET_THE_SEARCH_BEHAVIOUR_HERE="Set the search behaviour here." COM_COMPONENTBUILDER_SHARE_SNIPPETS="Share Snippets" COM_COMPONENTBUILDER_SHOULD_JCB_ADD_ANY_POWERS_THAT_ARE_CONNECTED_TO_THIS_COMPONENT_THIS_MAY_BE_HELPFUL_IF_YOU_ARE_LOADING_POWERS_VIA_ANOTHER_COMPONENT_AND_WOULD_LIKE_TO_AVOID_ADDING_IT_TO_BOTH_JUST_REMEMBER_THAT_IN_THIS_CASE_YOU_NEED_TO_LOAD_THE_POWERS_VIA_A_PLUGIN="Should JCB add any powers that are connected to this component? This may be helpful if you are loading powers via another component, and would like to avoid adding it to both, just remember that in this case you need to load the powers via a plugin." COM_COMPONENTBUILDER_SHOULD_JCB_INSERT_THE_CUSTOM_CODE_PLACEHOLDERS_THIS_IS_ONLY_APPLICABLE_IF_THIS_COMPONENT_HAS_CUSTOM_CODE="Should JCB insert the custom code placeholders? This is only applicable if this component has custom code." @@ -8298,6 +7892,7 @@ COM_COMPONENTBUILDER_SHOULD_THIS_FIELD_BE_ESCAPED_IN_THE_LIST_VIEW="Should this COM_COMPONENTBUILDER_SHOULD_WE_BE_SHOWING_MORE_ELABORATE_INFORMATION_DURING_IMPORT="Should we be showing more elaborate information during import." COM_COMPONENTBUILDER_SHOULD_WE_FORCE_THE_UPDATE_OF_ALL_LOCAL_DATA_EVEN_IF_IT_IS_NEWER_THEN_THE_DATA_BEING_IMPORTED="Should we force the update of all local data, even if it is newer then the data being imported." COM_COMPONENTBUILDER_SHOULD_WE_MERGE_THE_COMPONENTS_WITH_SIMILAR_LOCAL_COMPONENTS_MERGING_THE_COMPONENTS_USE_TO_BE_THE_DEFAULT_BEHAVIOUR_BUT_NOW_YOU_CAN_IMPORT_THE_COMPONENTS_AND_FORCE_IT_NOT_TO_MERGE_THE_FOLLOWING_AREAS_VALIDATION_RULE_FIELDTYPE_SNIPPET_LANGUAGE_LANGUAGE_TRANSLATION_JOOMLA_PLUGIN_GROUP_CLASS_EXTENDS_CLASS_PROPERTY_CLASS_METHOD_BMUST_AND_WILL_STILLB_MERGE_EVEN_OF_YOUR_SELECTION_IS_BNOB_BECAUSE_OF_THE_SINGULAR_NATURE_OF_THOSE_AREAS="Should we merge the component/s with similar local component/s. Merging the component/s use to be the default behaviour, but now you can import the component/s and force it not to merge. The following areas (validation_rule, fieldtype, snippet, language, language_translation, joomla_plugin_group, class_extends, class_property, class_method) must and will still merge even of your selection is No, because of the singular nature of those areas." +COM_COMPONENTBUILDER_SHOW_ADVANCED_OPTIONS="Show Advanced Options" COM_COMPONENTBUILDER_SHOW_IN_ALL_LIST_VIEWS="Show in All List Views" COM_COMPONENTBUILDER_SHOW_ONLY="Show Only" COM_COMPONENTBUILDER_SHOW_TOGGLE="Show Toggle" @@ -8310,11 +7905,9 @@ COM_COMPONENTBUILDER_SITE_VIEWS_ACCESS_DESC="Allows the users in this group to a COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_OPTIONS="Batch process the selected Site Views" COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_TIP="All changes will be applied to all selected Site Views" COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_USE="Site Views Batch Use" -COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch site views" +COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch site views" COM_COMPONENTBUILDER_SITE_VIEWS_CREATE="Site Views Create" COM_COMPONENTBUILDER_SITE_VIEWS_CREATE_DESC="Allows the users in this group to create create site views" -COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_ADD="Site Views Dashboard Add" -COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of site view" COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_LIST="Site Views Dashboard List" COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of site view" COM_COMPONENTBUILDER_SITE_VIEWS_DELETE="Site Views Delete" @@ -8327,7 +7920,7 @@ COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_STATE="Site Views Edit State" COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the site view" COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_VERSION="Site Views Edit Version" -COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version site views" +COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version site views" COM_COMPONENTBUILDER_SITE_VIEWS_EXPORT="Site Views Export" COM_COMPONENTBUILDER_SITE_VIEWS_EXPORT_DESC="Allows the users in this group to export export site views" COM_COMPONENTBUILDER_SITE_VIEWS_IMPORT="Site Views Import" @@ -8428,8 +8021,7 @@ COM_COMPONENTBUILDER_SITE_VIEW_CLOCK="Clock" COM_COMPONENTBUILDER_SITE_VIEW_CMD="CMD" COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_DESCRIPTION="Add Name in Code Here" COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_HINT="codename" -COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_LABEL="Name in Code
-Naming Conventions" +COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_LABEL="Name in Code
Naming Conventions" COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_MESSAGE="Error! Please add name in code here." COM_COMPONENTBUILDER_SITE_VIEW_COG="Cog" COM_COMPONENTBUILDER_SITE_VIEW_COGS="Cogs" @@ -8587,10 +8179,7 @@ COM_COMPONENTBUILDER_SITE_VIEW_NEW_TAB_2="New Tab 2" COM_COMPONENTBUILDER_SITE_VIEW_NEXT="Next" COM_COMPONENTBUILDER_SITE_VIEW_NO="No" COM_COMPONENTBUILDER_SITE_VIEW_NONE="None" -COM_COMPONENTBUILDER_SITE_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_SITE_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_SITE_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_SITE_VIEW_NOTE_CUSTOM_TOOLBAR_PLACEHOLDER_DESCRIPTION="Use this placeholder in the body [[[SITE_TOOLBAR]]] to add the custom position of the toolbar." COM_COMPONENTBUILDER_SITE_VIEW_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." @@ -8746,7 +8335,7 @@ COM_COMPONENTBUILDER_SNIPPETS_ACCESS_DESC="Allows the users in this group to acc COM_COMPONENTBUILDER_SNIPPETS_BATCH_OPTIONS="Batch process the selected Snippets" COM_COMPONENTBUILDER_SNIPPETS_BATCH_TIP="All changes will be applied to all selected Snippets" COM_COMPONENTBUILDER_SNIPPETS_BATCH_USE="Snippets Batch Use" -COM_COMPONENTBUILDER_SNIPPETS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch snippets" +COM_COMPONENTBUILDER_SNIPPETS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch snippets" COM_COMPONENTBUILDER_SNIPPETS_COULD_NOT_BE_UPDATEDSAVED="Snippets could not be updated/saved" COM_COMPONENTBUILDER_SNIPPETS_CREATE="Snippets Create" COM_COMPONENTBUILDER_SNIPPETS_CREATE_DESC="Allows the users in this group to create create snippets" @@ -8761,7 +8350,7 @@ COM_COMPONENTBUILDER_SNIPPETS_EDIT_OWN_DESC="Allows the users in this group to e COM_COMPONENTBUILDER_SNIPPETS_EDIT_STATE="Snippets Edit State" COM_COMPONENTBUILDER_SNIPPETS_EDIT_STATE_DESC="Allows the users in this group to update the state of the snippet" COM_COMPONENTBUILDER_SNIPPETS_EDIT_VERSION="Snippets Edit Version" -COM_COMPONENTBUILDER_SNIPPETS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version snippets" +COM_COMPONENTBUILDER_SNIPPETS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version snippets" COM_COMPONENTBUILDER_SNIPPETS_EXPORT="Snippets Export" COM_COMPONENTBUILDER_SNIPPETS_EXPORT_DESC="Allows the users in this group to export export snippets" COM_COMPONENTBUILDER_SNIPPETS_IMPORT="Snippets Import" @@ -8854,7 +8443,7 @@ COM_COMPONENTBUILDER_SNIPPET_TYPES_ACCESS_DESC="Allows the users in this group t COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_OPTIONS="Batch process the selected Snippet Types" COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_TIP="All changes will be applied to all selected Snippet Types" COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_USE="Snippet Types Batch Use" -COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch snippet types" +COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch snippet types" COM_COMPONENTBUILDER_SNIPPET_TYPES_CREATE="Snippet Types Create" COM_COMPONENTBUILDER_SNIPPET_TYPES_CREATE_DESC="Allows the users in this group to create create snippet types" COM_COMPONENTBUILDER_SNIPPET_TYPES_DELETE="Snippet Types Delete" @@ -8866,7 +8455,7 @@ COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_STATE="Snippet Types Edit State" COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_STATE_DESC="Allows the users in this group to update the state of the snippet type" COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_VERSION="Snippet Types Edit Version" -COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version snippet types" +COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version snippet types" COM_COMPONENTBUILDER_SNIPPET_TYPES_N_ITEMS_ARCHIVED="%s Snippet Types archived." COM_COMPONENTBUILDER_SNIPPET_TYPES_N_ITEMS_ARCHIVED_1="%s Snippet Type archived." COM_COMPONENTBUILDER_SNIPPET_TYPES_N_ITEMS_CHECKED_IN_0="No Snippet Type successfully checked in." @@ -8933,6 +8522,10 @@ COM_COMPONENTBUILDER_SORRY_THIS_PLACEHOLDER_IS_ALREADY_IN_USE_IN_THE_COMPILER="S COM_COMPONENTBUILDER_SORRY_THIS_VALIDATION_RULE_NAME_S_ALREADY_EXIST_AS_PART_OF_THE_JOOMLA_CORE_NO_NEED_TO_CREATE_IT_IF_YOU_ARE_ADAPTING_IT_GIVE_IT_YOUR_OWN_UNIQUE_NAME="Sorry this validation rule name (%s) already exist as part of the Joomla core! No need to create it, if you are adapting it give it your own unique name." COM_COMPONENTBUILDER_SORRY_THIS_VALIDATION_RULE_NAME_S_ALREADY_EXIST_IN_YOUR_SYSTEM="Sorry this validation rule name (%s) already exist in your system!" COM_COMPONENTBUILDER_SORTABLE="Sortable" +COM_COMPONENTBUILDER_SOURCE_CODE="source code" +COM_COMPONENTBUILDER_SOURCE_CODE_FOR_JOOMLA_COMPONENT="Source Code for Joomla Component" +COM_COMPONENTBUILDER_START_A_SEARCH="Start a Search" +COM_COMPONENTBUILDER_STOP_A_SEARCH="Stop a Search" COM_COMPONENTBUILDER_SUBMENU="Submenu" COM_COMPONENTBUILDER_SUBMENU_ADMIN_VIEWS="Admin Views" COM_COMPONENTBUILDER_SUBMENU_COMPILER="Compiler" @@ -8953,21 +8546,31 @@ COM_COMPONENTBUILDER_SUBMENU_LAYOUTS="Layouts" COM_COMPONENTBUILDER_SUBMENU_LIBRARIES="Libraries" COM_COMPONENTBUILDER_SUBMENU_PLACEHOLDERS="Placeholders" COM_COMPONENTBUILDER_SUBMENU_POWERS="Powers" +COM_COMPONENTBUILDER_SUBMENU_SEARCH="Search" COM_COMPONENTBUILDER_SUBMENU_SERVERS="Servers" COM_COMPONENTBUILDER_SUBMENU_SITE_VIEWS="Site Views" COM_COMPONENTBUILDER_SUBMENU_SNIPPETS="Snippets" COM_COMPONENTBUILDER_SUBMENU_TEMPLATES="Templates" COM_COMPONENTBUILDER_SUBMENU_VALIDATION_RULES="Validation Rules" +COM_COMPONENTBUILDER_SUCCESS="Success" +COM_COMPONENTBUILDER_SUCCESSFULLY_INITIALIZED_ALL_REMOTE_POWERS="Successfully Initialized all Remote Powers" COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED="Success! The snippet was saved." COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED_BUT_THE_MODIFIED_DATE_COULD_NOT_BE_ADJUSTED_BR_BR_BTHIS_MEANS_THE_SNIPPETS_WILL_CONTINUE_TO_APPEAR_OUT_OF_DATEB="Success! The snippet was saved. But the modified date could not be adjusted.

This means the snippets will continue to appear out of date." -COM_COMPONENTBUILDER_SZDEQZDMVSMHBTRWFIFTYTSQFLVVXJTMTHREEJTWOIXM="%szdEQzdmVsMHBtRW50T%sQFlvVXJTM3J2IXM=" +COM_COMPONENTBUILDER_SUPER_POWER="Super Power" +COM_COMPONENTBUILDER_SUPPORT_JCB_TODAY="Support JCB Today" +COM_COMPONENTBUILDER_SUPPORT_JOOMLA_COMPONENT_BUILDER_JCB_WITH_A_BFINANCIAL_DONATIONB_TO_SHOW_GRATITUDE_FOR_THE_TIME_AND_EFFORT_SAVED_IN_YOUR_DEVELOPMENT_PROCESS_YOUR_CONTRIBUTION_NO_MATTER_THE_SIZE_WILL_BE_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY_HELP_ENSURE_THE_GROWTH_AND_RELEVANCE_OF_THIS_ESSENTIAL_TOOL="Support Joomla Component Builder (JCB) with a financial donation to show gratitude for the time and effort saved in your development process. Your contribution, no matter the size, will be appreciated by the project's team and the wider community. Help ensure the growth and relevance of this essential tool." COM_COMPONENTBUILDER_SZIP_COULD_NOT_BE_INSTALLED="%s.zip could not be installed!" COM_COMPONENTBUILDER_SZIP_WAS_REMOVED_THE_FROM_TMP_FOLDER_DURING_INSTALLATION="%s.zip was removed the from tmp folder during installation!" COM_COMPONENTBUILDER_S_BEING_IMPORTED="%s Being Imported" COM_COMPONENTBUILDER_S_NOT_LINKED="%s Not Linked" COM_COMPONENTBUILDER_S_PLEASE_WAIT="%s, please wait!" COM_COMPONENTBUILDER_S_S_NUMBER_BSB_COULD_NOT_BE_DOWNLOADED_SUCCESSFULLY_TO_THIS_JOOMLA_INSTALL="%s (%s) number %s could not be downloaded successfully to this Joomla Install!" +COM_COMPONENTBUILDER_S_WE_DETECTED_A_CHANGE_IN_BEXTERNALCODEB_BUT_YOU_DO_NOT_HAVE_PERMISSION_TO_ALLOW_THIS_CHANGE_SO_BSB_WAS_REMOVED_FROM_THE_COMPILATION_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFOBR_SMALLADMIN_ACCESS_REQUIREDSMALL="%s, we detected a change in EXTERNALCODE, but you do not have permission to allow this change so %s was removed from the compilation. Please contact your system administrator for more info!
(admin access required)" +COM_COMPONENTBUILDER_S_WE_DETECTED_BNEW_EXTERNALCODEB_BUT_YOU_DO_NOT_HAVE_PERMISSION_TO_ALLOW_THIS_NEW_CODESTRING_SO_BSB_WAS_REMOVED_FROM_THE_COMPILATION_PLEASE_CONTACT_YOU_SYSTEM_ADMINISTRATOR_FOR_MORE_INFOBR_SMALLADMIN_ACCESS_REQUIREDSMALL="%s, we detected NEW EXTERNALCODE, but you do not have permission to allow this new code/string so %s was removed from the compilation. Please contact you system administrator for more info!
(admin access required)" COM_COMPONENTBUILDER_TAB="Tab" +COM_COMPONENTBUILDER_TABLE="Table" +COM_COMPONENTBUILDER_TABLES="Tables" +COM_COMPONENTBUILDER_TABLES_WITH="tables with" COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN="Table %s not found in the local database so its values could not be imported, please update your JCB install and try again." COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_THE_WHOLE_POWERS_FEATURE_IS_ONLY_AVAILABLE_TO_A_HREFSPRO_MEMBERSA_AT_THIS_TIME="Table %s not found in the local database so its values could not be imported. The whole powers feature is only available to PRO Members at this time." COM_COMPONENTBUILDER_TARGET_BEHAVIOUR="Target Behaviour" @@ -8981,7 +8584,7 @@ COM_COMPONENTBUILDER_TEMPLATES_ACCESS_DESC="Allows the users in this group to ac COM_COMPONENTBUILDER_TEMPLATES_BATCH_OPTIONS="Batch process the selected Templates" COM_COMPONENTBUILDER_TEMPLATES_BATCH_TIP="All changes will be applied to all selected Templates" COM_COMPONENTBUILDER_TEMPLATES_BATCH_USE="Templates Batch Use" -COM_COMPONENTBUILDER_TEMPLATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch templates" +COM_COMPONENTBUILDER_TEMPLATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch templates" COM_COMPONENTBUILDER_TEMPLATES_CREATE="Templates Create" COM_COMPONENTBUILDER_TEMPLATES_CREATE_DESC="Allows the users in this group to create create templates" COM_COMPONENTBUILDER_TEMPLATES_DASHBOARD_ADD="Templates Dashboard Add" @@ -8998,7 +8601,7 @@ COM_COMPONENTBUILDER_TEMPLATES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_TEMPLATES_EDIT_STATE="Templates Edit State" COM_COMPONENTBUILDER_TEMPLATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the template" COM_COMPONENTBUILDER_TEMPLATES_EDIT_VERSION="Templates Edit Version" -COM_COMPONENTBUILDER_TEMPLATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version templates" +COM_COMPONENTBUILDER_TEMPLATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version templates" COM_COMPONENTBUILDER_TEMPLATES_EXPORT="Templates Export" COM_COMPONENTBUILDER_TEMPLATES_EXPORT_DESC="Allows the users in this group to export export templates" COM_COMPONENTBUILDER_TEMPLATES_IMPORT="Templates Import" @@ -9062,10 +8665,7 @@ COM_COMPONENTBUILDER_TEMPLATE_NAME_LABEL="Name" COM_COMPONENTBUILDER_TEMPLATE_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_TEMPLATE_NEW="A New Template" COM_COMPONENTBUILDER_TEMPLATE_NO="No" -COM_COMPONENTBUILDER_TEMPLATE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_TEMPLATE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_TEMPLATE_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_TEMPLATE_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." COM_COMPONENTBUILDER_TEMPLATE_NOTE_LIBRARIES_SELECTION_LABEL="Select libraries you would like to use in your code" @@ -9094,6 +8694,7 @@ COM_COMPONENTBUILDER_THERE_ARE_NO_NEW_SNIPPETS_AT_THIS_TIME="There are no new sn COM_COMPONENTBUILDER_THERE_ARE_NO_OUT_OF_DATE_SNIPPETS_AT_THIS_TIME="There are no out of date snippets at this time" COM_COMPONENTBUILDER_THERE_ARE_NO_SNIPPETS_TO_UPDATE_AT_THIS_TIME="There are no snippets to update at this time" COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_IF_THIS_CONTINUES_PLEASE_INFORM_YOUR_SYSTEM_ADMINISTRATOR_OF_A_TYPE_ERROR_IN_THE_FIELDS_DISPLAY_REQUEST="There has been an error, if this continues please inform your system administrator of a type error in the fields display request!" +COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN="There has been an error please try again" COM_COMPONENTBUILDER_THERE_WAS_AN_ERROR_GETTING_THE_PACKAGE_INFO="There was an error getting the package info." COM_COMPONENTBUILDER_THERE_WAS_A_PROBLEM_BNO_VIEW_OR_ID_FOUND_IN_SESSION_OR_VIEW_NOT_ALLOWED_TO_ACCESS_AREAB_WE_COULD_NOT_LOAD_ANY_LINKED_TO_VALUES_PLEASE_INFORM_YOUR_SYSTEM_ADMINISTRATOR="There was a problem, no view or id found in session or view not allowed to access area, we could not load any linked to values. Please inform your system administrator!" COM_COMPONENTBUILDER_THESE_ARE_THE_SAME_PACKAGES_FOUND_ON_A_S_GITHUBA_AND_CAN_BE_IMPORTED_BY_SIMPLY_MAKING_A_SELECTION_AND_THEN_CLICKING_THE_BGET_PACKAGEB_BUTTONBR_SOME_OF_THESE_PACKAGES_WOULD_REQUIRE_A_KEY_SINCE_THEY_ARE_NOT_FREE="These are the same packages found on gitHub and can be imported by simply making a selection and then clicking the [Get Package] button.
Some of these packages would require a key, since they are not free." @@ -9110,13 +8711,21 @@ COM_COMPONENTBUILDER_THE_BNONE_DBB_OPTION_WILL_REMOVE_THIS_FIELD_FROM_BEING_SAVE COM_COMPONENTBUILDER_THE_BONLY_IN_ADMIN_LIST_VIEWB_OPTION_WILL_ONLY_ADD_THIS_FIELD_TO_THE_ADMIN_LIST_VIEW_NOT_TO_ANY_LINKED_VIEWS="The Only in Admin List View option will only Add this field to the admin list view, not to any linked views." COM_COMPONENTBUILDER_THE_BONLY_IN_LINKED_LIST_VIEWSB_OPTION_WILL_ONLY_ADD_THIS_FIELD_TO_THE_LINKED_LIST_VIEW_IF_THIS_VIEW_GETS_LINKED_TO_OTHER_VIEW_NOT_TO_THIS_ADMIN_LIST_VIEW="The Only in Linked List Views option will only Add this field to the linked list view, if this view gets linked to other view, not to this admin list view." COM_COMPONENTBUILDER_THE_BPHPSECLIBNETSFTPB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_BLIBRARIESVDM_IOVENDORB_FOLDER_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="The phpseclib\NET\SFTP library\class is not available! This library\class should have been added to your libraries/vdm_io/vendor folder. Please contact your system administrator for more info" +COM_COMPONENTBUILDER_THE_BSB_BSB_IS_NOT_AVAILABLE_IN_YOUR_COMPONENT_PLEASE_INSURE_TO_ONLY_USED_S_FOR_A_DYNAMIC_DASHBOARD_THAT_ARE_STILL_LINKED_TO_YOUR_COMPONENT="The %s (%s) is not available in your component! Please insure to only used %s, for a dynamic dashboard, that are still linked to your component." +COM_COMPONENTBUILDER_THE_BSB_CUT_SEQUENCE_FAILED_ON_THE_RETURNED_EXTERNAL_CODESTRING_AS_MORE_LINES_HAS_TO_BE_CUT_THEN_WAS_FOUND_IN_THE_CODESTRING_WE_HAVE_COMPLETELY_REMOVED_THE_CODE_PLEASE_CHECK_THIS_CODESTRING="The %s cut sequence failed on the returned external code/string as more lines has to be cut then was found in the code/string. We have completely removed the code. Please check this code/string!" COM_COMPONENTBUILDER_THE_BSB_FILE_COULD_NOT_BE_MOVED_TO_BSB_PATH_ON_BSB_SERVER="The %s file could not be moved to %s path on %s server." COM_COMPONENTBUILDER_THE_BSB_FILE_COULD_NOT_BE_MOVED_TO_BSB_SERVER="The %s file could not be moved to %s server." +COM_COMPONENTBUILDER_THE_BSB_IS_NOT_A_VALID_URLPATH="The %s is not a valid url/path!" COM_COMPONENTBUILDER_THE_BSB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_BLIBRARIESPHPSECLIBVENDORB_FOLDER_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="The %s library\class is not available! This library\class should have been added to your libraries/phpseclib/vendor folder. Please contact your system administrator for more info!" COM_COMPONENTBUILDER_THE_BSB_LIBRARY_CAN_NOT_BE_DELETED_OR_THINGS_WILL_BREAK="The %s library can not be deleted, or things will break." +COM_COMPONENTBUILDER_THE_BSB_RETURNED_AN_INVALID_STRING="The %s returned an invalid string!" +COM_COMPONENTBUILDER_THE_BSB_VALUE_FOR_THE_DYNAMIC_DASHBOARD_IS_INVALID="The %s value for the dynamic dashboard is invalid." COM_COMPONENTBUILDER_THE_BSHOW_IN_ALL_LIST_VIEWSB_OPTION_WILL_ADD_THIS_FIELD_TO_ALL_LIST_VIEWS_ADMIN_AMP_LINKED="The Show in All List Views option will Add this field to all list views, admin & linked." COM_COMPONENTBUILDER_THE_BSINGLE_FILTERB_SELECTION_OPTION_ALLOWS_THE_USER_TO_SELECT_JUST_ONE_VALUE_IN_THIS_FILTERFIELD="The single filter selection option allows the user to select just one value in this filter/field." +COM_COMPONENTBUILDER_THE_CODESTRING_FROM_BSB_HAS_BEEN_ADDED_FOR_THE_BFIRST_TIMEB_PLEASE_IINVESTIGATEI_TO_ENSURE_THE_CORRECT_CODESTRING_WAS_USED_BSHOULD_YOU_NOT_KNOW_ABOUT_THIS_NEW_EXTERNAL_CODESTRING_BEING_ADDED_THEN_THIS_IS_A_SERIOUS_DANGER_AND_REQUIRES_IMMEDIATE_ATTENTIONB_DO_NOT_IGNORE_THIS_WARNING_AS_IT_WILL_ONLY_SHOW_BONCEB="The code/string from %s has been added for the first time. Please investigate to ensure the correct code/string was used! Should you not know about this NEW external code/string being added, then this is a serious danger! and requires immediate attention! Do not ignore this warning as it will only show once." +COM_COMPONENTBUILDER_THE_CODESTRING_FROM_BSB_HAS_BEEN_BCHANGEDB_SINCE_THE_LAST_COMPILATION_PLEASE_INVESTIGATE_TO_ENSURE_THE_CHANGES_ARE_SAFE_BSHOULD_YOU_NOT_EXPECT_THIS_CHANGE_TO_THE_EXTERNAL_CODESTRING_BEING_ADDED_THEN_THIS_IS_A_SERIOUS_ISSUE_AND_REQUIRES_IMMEDIATE_ATTENTIONB_DO_NOT_IGNORE_THIS_WARNING_AS_IT_WILL_ONLY_SHOW_BONCEB="The code/string from %s has been changed since the last compilation. Please investigate to ensure the changes are safe! Should you not expect this change to the external code/string being added, then this is a serious issue! and requires immediate attention! Do not ignore this warning as it will only show once." COM_COMPONENTBUILDER_THE_COMPONENT="The Component" +COM_COMPONENTBUILDER_THE_COMPONENTS_LAST_MODIFIED_DATE_WILL_BE_USED="The component's last modified date will be used." COM_COMPONENTBUILDER_THE_COMPONENT_ADMIN_VIEWS="The component admin views" COM_COMPONENTBUILDER_THE_COMPONENT_CONFIG="The component config" COM_COMPONENTBUILDER_THE_COMPONENT_CUSTOM_ADMIN_MENUS="The component custom admin menus" @@ -9130,25 +8739,35 @@ COM_COMPONENTBUILDER_THE_COMPONENT_PLUGINS="The component plugins" COM_COMPONENTBUILDER_THE_COMPONENT_SITE_VIEWS="The component site views" COM_COMPONENTBUILDER_THE_COMPONENT_UPDATES="The component updates" COM_COMPONENTBUILDER_THE_COMPONENT_WITH_ALL_LINKED_ADMIN_VIEWS_FIELDS_LINKED_TO_ADMIN_VIEWS_CUSTOM_ADMIN_VIEWS_SITE_VIEWS_TEMPLATES_AND_LAYOUTS_WERE_CLONED_SUCCESSFUL="The Component with all linked admin views, fields linked to admin views, custom admin views, site views, templates and layouts were cloned successful!" +COM_COMPONENTBUILDER_THE_CONTINUED_SUPPORT_OF_INDIVIDUALS_LIKE_YOU_HAS_ALLOWED_JOOMLA_COMPONENT_BUILDER_JCB_TO_THRIVE_FOR_SEVEN_YEARS_SINCE_GOING_PUBLIC_YOUR_CONTRIBUTIONS_HAVE_BEEN_CRUCIAL_IN_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_THANK_YOU_FOR_YOUR_SUPPORT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY="The continued support of individuals like you has allowed Joomla Component Builder (JCB) to thrive for seven years since going public. Your contributions have been crucial in ensuring the growth and relevance of this vital tool for PHP programmers. Thank you for your support and for being a part of JCB's journey." +COM_COMPONENTBUILDER_THE_FILE_PATH_BSB_DOES_NOT_EXIST_AND_WAS_NOT_ADDED="The file path: %s does not exist, and was not added!" +COM_COMPONENTBUILDER_THE_FOLDER_PATH_BSB_DOES_NOT_EXIST_AND_WAS_NOT_ADDED="The folder path: %s does not exist, and was not added!" COM_COMPONENTBUILDER_THE_FTP_CONNECTION_FOR_BSB_COULD_NOT_BE_MADE_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP connection for %s could not be made. Please check your signature details!" COM_COMPONENTBUILDER_THE_FTP_SIGNATURE_FOR_BSB_WAS_NOT_WELL_FORMED_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP signature for %s was not well formed, please check your signature details!" +COM_COMPONENTBUILDER_THE_INITIALIZATION_OF_THIS_POWERS_HAS_FAILED="The initialization of this powers has failed." COM_COMPONENTBUILDER_THE_KEY_OF_THIS_PACKAGE="The key of this package." COM_COMPONENTBUILDER_THE_LIBRARY_CONFIG_FIELDS="The library config fields" COM_COMPONENTBUILDER_THE_LIBRARY_FILES_FOLDERS_URLS="The library files, folders & URLs" +COM_COMPONENTBUILDER_THE_LOCAL_DATABASE_POWERS_HAS_SUCCESSFULLY_BEEN_SYNCED_WITH_THE_REMOTE_REPOSITORIES="The local database powers has successfully been synced with the remote repositories." COM_COMPONENTBUILDER_THE_LOGIN_TO_BSB_HAS_FAILED_PLEASE_CHECK_THAT_YOUR_DETAILS_ARE_CORRECT="The login to %s has failed, please check that your details are correct!" COM_COMPONENTBUILDER_THE_MODULE_FILES_FOLDERS="The module files & folders" COM_COMPONENTBUILDER_THE_MODULE_UPDATES="The module updates" COM_COMPONENTBUILDER_THE_NAME_OF_THIS_LIBRARY_BSB_CAN_NOT_BE_CHANGED_TO_BSB_OR_THINGS_WILL_BREAK="The name of this library (%s) can not be changed to %s or things will break." COM_COMPONENTBUILDER_THE_NOTICE_BOARD_IS_LOADING="The notice board is loading" +COM_COMPONENTBUILDER_THE_OPTION_TO_ADD_A_DYNAMIC_BUTTON_IS_NOT_AVAILABLE_IN_BOWN_CUSTOM_FIELD_TYPESB_YOU_WILL_HAVE_TO_CUSTOM_CODE_IT="The option to add a dynamic button is not available in own custom field types, you will have to custom code it." COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_CODESCODE="The package key is: %s" COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_S="The package key is: %s" COM_COMPONENTBUILDER_THE_PLUGIN_FILES_FOLDERS="The plugin files & folders" COM_COMPONENTBUILDER_THE_PLUGIN_UPDATES="The plugin updates" +COM_COMPONENTBUILDER_THE_POWER_HAS_SUCCESSFULLY_BEEN_RESET="The power has successfully been reset." COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FIELD_COULD_NOT_BE_LOADED_FOR_BSB_SERVER="The private key field could not be loaded for %s server!" COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER="The private key file could not be loaded/found for %s server!" COM_COMPONENTBUILDER_THE_PRO_BOARD_IS_LOADING="The pro board is loading" COM_COMPONENTBUILDER_THE_README_IS_LOADING="The readme is loading" +COM_COMPONENTBUILDER_THE_REPLACE_PROCESS_HAD_AN_ERROR_WITH_TABLE="The replace process had an error with table" +COM_COMPONENTBUILDER_THE_RESET_OF_THIS_POWER_HAS_FAILED="The reset of this power has failed." COM_COMPONENTBUILDER_THE_SEARCH_FOR_THE_SNIPPETS_ARE_CASE_SENSITIVE_SO_IF_YOU_CHANGED_THE_LOCAL_BNAMESB_OF_EITHER_OR_THE_BSNIPPET_LIBRARY_OR_SNIPPET_TYPESB_IN_ANY_SMALL_WAY_THE_SYSTEM_WILL_NOT_BE_ABLE_TO_CONNECT_YOUR_LOCAL_SNIPPETS_WITH_THOSE_IN_THE_COMMUNITY_REPOSITORY_SO_WE_STRONGLY_ADVICE_TO_BKEEP_TO_THE_COMMUNITY_NAMINGB_TO_AVOID_MISMATCHING_THAT_WILL_IN_TURN_CAUSE_DUPLICATION_SO_IF_YOU_CHANGED_ANY_NAMES_JUST_CHANGE_THEM_BACK_AND_ALL_WILL_AGAIN_WORK_AS_EXPECTED="The search for the snippets are case sensitive so if you changed the local names of either or the snippet, library or snippet types in any small way, the system will not be able to connect your local snippets with those in the community repository. So we strongly advice to keep to the community naming to avoid mismatching, that will in turn cause duplication. So if you changed any names, just change them back and all will again work as expected." +COM_COMPONENTBUILDER_THE_SEARCH_PROCESS_HAD_AN_ERROR_WITH_TABLE="The search process had an error with table" COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED="The server details for (ID: %s) could not be retrieved!" COM_COMPONENTBUILDER_THE_SNIPPETS_WERE_SUCCESSFULLY_EXPORTED="The Snippets Were Successfully Exported!" COM_COMPONENTBUILDER_THE_SNIPPET_WAS_SUCCESSFULLY_EXPORTED="The Snippet Was Successfully Exported!" @@ -9156,12 +8775,16 @@ COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DID_NOT_RETURN_S_DAT COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DID_NOT_RETURN_VALID_DATA="The url (%s) set to retrieve the packages did not return valid data!" COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST="The url (%s) set to retrieve the packages does not exist!" COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_RETURN_ANY_DATA="The url (%s) set to retrieve the packages does not return any data!" -COM_COMPONENTBUILDER_THE_WIKI_CAN_ONLY_BE_LOADED_WHEN_YOUR_JCB_SYSTEM_HAS_INTERNET_CONNECTION="The wiki can only be loaded when your JCB system has internet connection." +COM_COMPONENTBUILDER_THE_WIKI_CAN_ONLY_BE_LOADED_WHEN_YOUR_JOOMLA_COMPONENT_BUILDER_SYSTEM_HAS_INTERNET_CONNECTION="The wiki can only be loaded when your Joomla Component Builder system has internet connection." COM_COMPONENTBUILDER_THE_WIKI_IS_LOADING="The wiki is loading" +COM_COMPONENTBUILDER_THIS_ADDS_POWERS_TO_A_LOCAL_REPOSITORY_FOLDER_ALL_BAPPROVEDB_POWERS_LINKED_TO_THIS_COMPONENT_WILL_BE_MOVED_TO_YOUR_BLOCALB_POWERS_REPOSITORY_FOLDER_INTO_THEIR_SELECTIVE_TARGET_PATHS_THIS_LOCAL_FOLDER_PATH_MUST_BE_SET_IN_THE_GLOBAL_OPTIONS_OF_JCB_UNDER_THE_BSUPER_POWERB_TAB="This adds powers to a local repository folder. All approved powers, linked to this component, will be moved to your local powers repository folder into their selective target paths. This local folder path must be set in the global options of JCB under the super power tab." COM_COMPONENTBUILDER_THIS_BSB_IS_NOT_LINKED_TO_ANY_OTHER_AREAS_OF_JCB_AT_THIS_TIME="This %s is not linked to any other areas of JCB at this time!" +COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE="This can not be undone, are you sure you want to continue?" +COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_BYOU_HAVE_BEEN_WARNEDB="This can not be undone, you have been warned!" COM_COMPONENTBUILDER_THIS_MAY_TAKE_A_WHILE_DEPENDING_ON_THE_SIZE_OF_YOUR_PROJECT="This may take a while depending on the size of your project." COM_COMPONENTBUILDER_THIS_PACKAGE_BPASSEDB_THE_CHECKSUM_VALIDATIONBR_BR_SMALLMANUALLY_ALSO_VALIDATE_THAT_THE_CORRECT_CHECKSUM_WAS_USEDSMALLBR_THIS_CHECKSUM_BSB_MUST_BE_THE_SAME_AS_THE_ONE_FOUND_A_S_SA="This package PASSED the checksum validation!

Manually also validate that the correct checksum was used.
This checksum: %s must be the same as the one found @ " COM_COMPONENTBUILDER_THIS_PACKAGE_HAS_NO_KEY="This package has no key." +COM_COMPONENTBUILDER_THIS_RESET_FEATURE_IS_STILL_UNDER_DEVELOPMENT="This (reset) feature is still under development!" COM_COMPONENTBUILDER_TITLE="Title" COM_COMPONENTBUILDER_TO_ADD_SIMPLY_COPY_AND_PAST_THE_SNIPPET_INTO_YOUR_CODE="To add simply copy and past the snippet into your code." COM_COMPONENTBUILDER_TO_ADD_VALIDATION_TO_A_FIELD_IF_VALIDATION_IS_NOT_PART_OF_FIELD_TYPE_PROPERTIES_LOADED_ABOVE_SO_IF_YOU_HAVE_VALIDATION_SET_AS_A_FIELD_PROPERTY_THIS_EXTRA_PROPERTY_WILL_NOT_BE_NEEDED="To add validation to a field if validation is not part of field type properties loaded above. So if you have validation set as a field property this extra property will not be needed." @@ -9177,6 +8800,7 @@ COM_COMPONENTBUILDER_TRASHED_ITEMS="Trashed items" COM_COMPONENTBUILDER_TRASH_AREA="Trash Area" COM_COMPONENTBUILDER_TUTORIAL_ON_FORKING_JCB_SNIPPETS_BSB="Tutorial on forking JCB snippets: %s" COM_COMPONENTBUILDER_TUTORIAL_ON_MAKING_A_PULL_REQUEST_BSB="Tutorial on making a pull request: %s" +COM_COMPONENTBUILDER_TWO_SPACES="2 Spaces" COM_COMPONENTBUILDER_TYPE="Type" COM_COMPONENTBUILDER_TYPE_ADMIN_CUSTOM_TABS="Admin Custom Tabs" COM_COMPONENTBUILDER_TYPE_ADMIN_FIELDS="Admin Fields" @@ -9234,7 +8858,9 @@ COM_COMPONENTBUILDER_TYPE_VALIDATION_RULE="Validation Rule" COM_COMPONENTBUILDER_UNACTIVE_ONLY_FOUR_TEXT_FIELD="Unactive (only 4 text_field)" COM_COMPONENTBUILDER_UNDERNEATH_TABS="Underneath Tabs" COM_COMPONENTBUILDER_UPDATE="Update" +COM_COMPONENTBUILDER_UPDATE_ALL="Update All" COM_COMPONENTBUILDER_UPDATE_ALL_DIVERGED_SNIPPETS="Update All Diverged Snippets" +COM_COMPONENTBUILDER_UPDATE_ALL_ITEMS_FOUND_WITH_THIS_DATABASE_SEARCH_WITH_THE_REPLACE_VALUE="Update all items found with this database search, with the replace value." COM_COMPONENTBUILDER_UPDATE_ALL_OUT_DATED_SNIPPETS="Update All Out Dated Snippets" COM_COMPONENTBUILDER_UP_TO_DATE="Up to date" COM_COMPONENTBUILDER_USAGE="Usage" @@ -9252,7 +8878,7 @@ COM_COMPONENTBUILDER_VALIDATION_RULES_ACCESS_DESC="Allows the users in this grou COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_OPTIONS="Batch process the selected Validation Rules" COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_TIP="All changes will be applied to all selected Validation Rules" COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_USE="Validation Rules Batch Use" -COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch validation rules" +COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_CREATE="Validation Rules Create" COM_COMPONENTBUILDER_VALIDATION_RULES_CREATE_DESC="Allows the users in this group to create create validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_DASHBOARD_LIST="Validation Rules Dashboard List" @@ -9266,7 +8892,7 @@ COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_STATE="Validation Rules Edit State" COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_STATE_DESC="Allows the users in this group to update the state of the validation rule" COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_VERSION="Validation Rules Edit Version" -COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version validation rules" +COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_EXPORT="Validation Rules Export" COM_COMPONENTBUILDER_VALIDATION_RULES_EXPORT_DESC="Allows the users in this group to export export validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_IMPORT="Validation Rules Import" @@ -9345,13 +8971,30 @@ COM_COMPONENTBUILDER_WEBSITE="Website" COM_COMPONENTBUILDER_WEBSITE_OF_S="Website of %s" COM_COMPONENTBUILDER_WEBSITE_S="Website: %s" COM_COMPONENTBUILDER_WE_DID_NOT_CHECK_THE_SNIPPET_IT_SELF_TO_SEE_IF_IT_CHANGED_WE_ONLY_WORK_ON_DATES="We did not check the snippet it self, to see if it changed. We only work on dates." +COM_COMPONENTBUILDER_WE_EXTEND_OUR_GRATITUDE_TO_ALL_THOSE_WHO_SUPPORT_JOOMLA_COMPONENT_BUILDER_JCB_WHETHER_AS_A_HOBBY_OR_AS_A_PART_OF_THEIR_BUSINESS_YOUR_CONTRIBUTIONS_WHETHER_FINANCIAL_OR_IN_THE_FORM_OF_ACTIVE_INVOLVEMENT_HAVE_HAD_A_SIGNIFICANT_IMPACT_ON_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_WE_HIGHLY_VALUE_THE_DEDICATION_OF_HOBBYISTS_AND_THE_COMMITMENT_OF_COMPANIES_WHO_SUPPORT_JCB_AS_THEY_HAVE_ALLOWED_THE_PROJECT_TO_CONTINUE_ITS_DEVELOPMENT_AND_MAINTENANCE_PROVIDING_VALUABLE_RESOURCES_FOR_THE_COMMUNITY_WE_ARE_GRATEFUL_FOR_YOUR_CONTRIBUTIONS_NO_MATTER_HOW_SMALL_AND_THANK_YOU_FOR_BEING_A_PART_OF_THE_POSITIVE_IMPACT_THAT_JCB_HAS_ON_THE_PHP_PROGRAMMING_COMMUNITY="We extend our gratitude to all those who support Joomla Component Builder (JCB), whether as a hobby or as a part of their business. Your contributions, whether financial or in the form of active involvement, have had a significant impact on ensuring the growth and relevance of this vital tool for PHP programmers. We highly value the dedication of hobbyists and the commitment of companies who support JCB, as they have allowed the project to continue its development and maintenance, providing valuable resources for the community. We are grateful for your contributions, no matter how small, and thank you for being a part of the positive impact that JCB has on the PHP programming community." +COM_COMPONENTBUILDER_WE_EXTEND_OUR_HEARTFELT_APPRECIATION_TO_THOSE_WHO_HAVE_SUPPORTED_THE_JOOMLA_COMPONENT_BUILDER_JCB_PROJECT_OVER_THE_YEARS_YOUR_CONTRIBUTIONS_NO_MATTER_HOW_BIG_OR_SMALL_HAVE_BEEN_INSTRUMENTAL_IN_ENSURING_ITS_GROWTH_AND_RELEVANCE_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS_SEVEN_YEARS_AFTER_GOING_PUBLIC_JCB_IS_STILL_HERE_TODAY_BECAUSE_OF_THE_SUPPORT_OF_INDIVIDUALS_LIKE_YOU_WHO_BELIEVE_IN_THE_IMPORTANCE_OF_THIS_OPENSOURCE_PROJECT_YOUR_GENEROSITY_HAS_ALLOWED_THE_PROJECT_TO_CONTINUE_ITS_DEVELOPMENT_AND_MAINTENANCE_PROVIDING_VALUABLE_RESOURCES_FOR_THE_COMMUNITY_THANK_YOU_FOR_YOUR_UNWAVERING_SUPPORT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY="We extend our heartfelt appreciation to those who have supported the Joomla Component Builder (JCB) project over the years. Your contributions, no matter how big or small, have been instrumental in ensuring its growth and relevance as a vital tool for PHP programmers. Seven years after going public, JCB is still here today because of the support of individuals like you who believe in the importance of this open-source project. Your generosity has allowed the project to continue its development and maintenance, providing valuable resources for the community. Thank you for your unwavering support and for being a part of JCB's journey." +COM_COMPONENTBUILDER_WE_EXTEND_OUR_SINCERE_APPRECIATION_TO_THE_COMPANIES_WHO_USE_JOOMLA_COMPONENT_BUILDER_JCB_AND_SUPPORT_THE_PROJECT_YOUR_CONTRIBUTIONS_WHETHER_FINANCIAL_OR_IN_THE_FORM_OF_ACTIVE_INVOLVEMENT_HAVE_BEEN_INSTRUMENTAL_IN_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_YOUR_SUPPORT_HAS_ALLOWED_JCB_TO_CONTINUE_ITS_DEVELOPMENT_AND_MAINTENANCE_PROVIDING_VALUABLE_RESOURCES_FOR_THE_COMMUNITY_THANK_YOU_FOR_YOUR_UNWAVERING_COMMITMENT_TO_THE_PROJECT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY="We extend our sincere appreciation to the companies who use Joomla Component Builder (JCB) and support the project. Your contributions, whether financial or in the form of active involvement, have been instrumental in ensuring the growth and relevance of this vital tool for PHP programmers. Your support has allowed JCB to continue its development and maintenance, providing valuable resources for the community. Thank you for your unwavering commitment to the project and for being a part of JCB's journey." COM_COMPONENTBUILDER_WE_FAILED_TO_MOVE_BSB="We failed to move %s!" +COM_COMPONENTBUILDER_WE_FOUND_DYNAMIC_CODE_BALL_IN_ONE_LINEB_AND_IGNORED_IT_PLEASE_REVIEW_S_FOR_MORE_DETAILS="We found dynamic code all in one line, and ignored it! Please review (%s) for more details!" +COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S="We found some instances in %s" COM_COMPONENTBUILDER_WE_SUCCESSFULLY_MOVED_BSB="We successfully moved %s!" +COM_COMPONENTBUILDER_WHAT_VERSION_OF_JOOMLA_WOULD_YOU_LIKE_TO_TARGET="What version of Joomla would you like to target." +COM_COMPONENTBUILDER_WHICH_TYPE_OF_INDENTATION_WOULD_YOU_LIKE_TO_USE_PLEASE_NOTE_THAT_THIS_DOES_NOT_YET_IMPACT_THE_STATIC_TEMPLATES="Which type of indentation would you like to use? Please note that this does not yet impact the static templates." COM_COMPONENTBUILDER_WHILE_WE_DOWNLOAD_ALL_TWENTY_SIX_COMPILER_GIF_ANIMATIONS_RANDOMLY_USED_IN_THE_COMPILER_GUI_DURING_COMPILATION="While we download all 26 compiler GIF animations randomly used in the compiler GUI during compilation" +COM_COMPONENTBUILDER_WHOLE_WORD="Whole Word" COM_COMPONENTBUILDER_WIKI="Wiki" +COM_COMPONENTBUILDER_WITH="with" +COM_COMPONENTBUILDER_WITHOUT_SUFFICIENT_SUPPORT_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_IS_IN_JEOPARDY_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS_IT_IS_CRUCIAL_TO_ENSURE_ITS_CONTINUED_DEVELOPMENT_AND_MAINTENANCE_BY_MAKING_A_BFINANCIAL_CONTRIBUTIONB_NO_MATTER_HOW_SMALL_YOU_ARE_HELPING_TO_SAFEGUARD_THE_FUTURE_OF_THIS_OPENSOURCE_PROJECT_NEGLECTING_TO_SUPPORT_JCB_COULD_RESULT_IN_ITS_DECLINE_AND_LOSS_AS_A_RESOURCE_FOR_THE_COMMUNITY="Without sufficient support, the future of Joomla Component Builder (JCB) is in jeopardy. As a vital tool for PHP programmers, it is crucial to ensure its continued development and maintenance. By making a financial contribution, no matter how small, you are helping to safeguard the future of this open-source project. Neglecting to support JCB could result in its decline and loss as a resource for the community." +COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_DO_A_REVERSE_SEARCH="Would you like to do a reverse search?" +COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_OVERRIDE_THE_BUILD_DATE="Would you like to override the build date." +COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_REPEAT_THE_SAME_SEARCH="Would you like to repeat the same search?" +COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_SEE_THE_ADVANCED_COMPILER_OPTIONS="Would you like to see the advanced compiler options?" COM_COMPONENTBUILDER_YES="Yes" -COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY="Your data is encrypted with a AES 128 bit encryption using the above 32 character key." -COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY_UNLESS_THEY_HAVE_THIS_KEY_ABOVE_SO_DO_KEEP_IT_SAFE="Your data is encrypted with a AES 128 bit encryption using the above 32 character key. Without this key it will take the current technology with a brute force attack method more then 700 000 000 000 000 000 000 000 000 000 000 years to crack theoretically. Unless they have this key above, so do keep it safe." +COM_COMPONENTBUILDER_YES_UPDATE_ALL="Yes! Update ALL" +COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_BALLB_VALUES_THAT_CAN_BE_FOUND_IN_THE_DATABASE="Your are about to update ALL values that can be found in the database." +COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_ROW="Your are about to update row" +COM_COMPONENTBUILDER_YOUR_COMPONENT_WILL_BE_COMPILED_TO_WORK_IN_JOOMLA_THREE="Your component will be compiled to work in Joomla 3" +COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_TWO_HUNDRED_AND_FIFTY_SIX_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY="Your data is encrypted with a AES 256 bit encryption using the above 32 character key." COM_COMPONENTBUILDER_YOU_ARE_CURRENTLY_VIEWING_THE_TRASHED_ITEMS="You are currently viewing the trashed items." COM_COMPONENTBUILDER_YOU_ARE_CURRENTLY_VIEWING_THE_TRASH_AREA_AND_YOU_DONT_HAVE_ANY_ITEMS_IN_TRASH_AT_THE_MOMENT="You are currently viewing the trash area, and you don't have any items in trash at the moment!" COM_COMPONENTBUILDER_YOU_CAN_DIRECTLY_DOWNLOAD_THE_LATEST_UPDATE_OR_USE_THE_JOOMLA_UPDATE_AREA="You can directly download the latest update, or use the Joomla update area." @@ -9360,10 +9003,12 @@ COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_ COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_CLONE_A_COMPONENT_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to clone a component, please contact your system administrator for more help." COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_DOWNLOAD_THE_COMPILER_ANIMATIONS="You do not have permission to download the compiler animations!" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_IMPORT_A_COMPONENT_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to import a component, please contact your system administrator for more help." +COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_INITIALIZE_POWERS="You do not have permission to initialize powers" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_INSTALL_THESE_EXTENSIONS="You do not have permission to install these extensions!" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_INSTALL_THE_COMPONENT="You do not have permission to install the component!" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_INSTALL_THE_MODULE="You do not have permission to install the module!" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_INSTALL_THE_PLUGIN="You do not have permission to install the plugin!" +COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_RESET_THIS_POWER="You do not have permission to reset this power" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_RUN_THE_EXPANSION_MODULE="You do not have permission to run the expansion module!" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_RUN_THE_GET_BOILERPLATE_MODULE="You do not have permission to run the get boilerplate module!" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_RUN_THE_TRANSLATOR_MODULE="You do not have permission to run the translator module!" @@ -9373,14 +9018,18 @@ COM_COMPONENTBUILDER_YOU_HAVE_S_S_ADDING_MORE_THEN_S_S_IS_CONSIDERED_BAD_PRACTIC COM_COMPONENTBUILDER_YOU_MUST_ADD_AN_UNIQUE_FUNCTION_NAME="You must add an unique function name." COM_COMPONENTBUILDER_YOU_MUST_ADD_AN_UNIQUE_PLACEHOLDER="You must add an unique placeholder." COM_COMPONENTBUILDER_YOU_MUST_ADD_AN_UNIQUE_VALIDATION_RULE_NAME="You must add an unique validation rule name." +COM_COMPONENTBUILDER_YOU_MUST_ENABLE_THE_BTIDYB_EXTENSION_IN_YOUR_PHPINI_FILE_SO_WE_CAN_TIDY_UP_YOUR_XML_IF_YOU_NEED_HELP_PLEASE_A_SSTART_HEREA="You must enable the Tidy extension in your php.ini file so we can tidy up your xml! If you need help please start here!" COM_COMPONENTBUILDER_YOU_MUST_FIRST_LINK_AN_ADMIN_OR_A_CUSTOM_ADMIN_VIEW_TO_THIS_COMPONENT_THEN_YOU_CAN_SELECT_IT_HERE="You must first link an admin or a custom admin view to this component, then you can select it here" +COM_COMPONENTBUILDER_YOU_MUST_FIRST_SAVE_THE_POWER_BEFORE_YOU_CAN_USE_THIS_FEATURE="You must first save the power, before you can use this feature." COM_COMPONENTBUILDER_YOU_MUST_SELECT_A_COMPONENT="You must select a component!" COM_COMPONENTBUILDER_YOU_SHOULD_ADD_THE_CORRECT_OWNER_DETAILS="You should add the correct owner details." COM_COMPONENTBUILDER_YOU_SHOULD_ONLY_CONTINUE_THIS_IMPORT_IF_YOU_HAVE_BACKUP_YOUR_COMPONENTS_AND_INSURED_THAT_THE_PACKAGE_OWNER_IS_REPUTABLE="You should only continue this import if you have backup your components, and insured that the package owner is reputable." COM_COMPONENTBUILDER_YOU_WILL_NEED_TO_KNOW_HOW_S_WORKS_BASIC_YOU_WILL_ALSO_NEED_A_S_ACCOUNT_AND_KNOW_HOW_TO_MAKE_A_PULL_REQUEST_ON_GITHUB="you will need to know how %s works (basic). You will also need a %s account and know how to make a pull request on github." +COM_COMPONENTBUILDER_YOU_WILL_REPLACE="You will replace" COM_COMPONENTBUILDER_ZIPPED_FILE_LOCATION="Zipped File Location" COM_COMPONENTBUILDER__ADD_YOUR_PHP_SCRIPT_HERE="// Add your php script here" COM_COMPONENTBUILDER__HAS_BEEN_CHECKED_OUT_BY_S="% has been checked out by %s" +COM_COMPONENTBUILDER__SEARCH_ALL_="- Search All -" COM_COMPONENTBUILDER__SELECT_COMPONENT_="- Select Component -" COM_COMPONENTBUILDER__SELECT_PACKAGE_="- Select Package -" COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_CREATE_S=", since you don't have permission to create %s!" diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini index 4e7b3ff77..b1d0e533b 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini @@ -2,7 +2,7 @@ COM_COMPONENTBUILDER="Component Builder" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_ACCESS="Admins Custom Tabs Access" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_ACCESS_DESC="Allows the users in this group to access access admins custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_USE="Admins Custom Tabs Batch Use" -COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins custom tabs" +COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_CREATE="Admins Custom Tabs Create" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_CREATE_DESC="Allows the users in this group to create create admins custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_DELETE="Admins Custom Tabs Delete" @@ -18,15 +18,15 @@ COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_STATE="Admins Custom Tabs Edit State" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin custom tabs" COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_VERSION="Admins Custom Tabs Edit Version" -COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins custom tabs" +COM_COMPONENTBUILDER_ADMINS_CUSTOM_TABS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins custom tabs" COM_COMPONENTBUILDER_ADMINS_FIELDS_ACCESS="Admins Fields Access" COM_COMPONENTBUILDER_ADMINS_FIELDS_ACCESS_DESC="Allows the users in this group to access access admins fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_USE="Admins Fields Batch Use" -COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins fields" +COM_COMPONENTBUILDER_ADMINS_FIELDS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_ACCESS="Admins Fields Conditions Access" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_ACCESS_DESC="Allows the users in this group to access access admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_USE="Admins Fields Conditions Batch Use" -COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins fields conditions" +COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_CREATE="Admins Fields Conditions Create" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_CREATE_DESC="Allows the users in this group to create create admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_DELETE="Admins Fields Conditions Delete" @@ -42,7 +42,7 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_STATE="Admins Fields Conditions Edit State" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_VERSION="Admins Fields Conditions Edit Version" -COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins fields conditions" +COM_COMPONENTBUILDER_ADMINS_FIELDS_CONDITIONS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins fields conditions" COM_COMPONENTBUILDER_ADMINS_FIELDS_CREATE="Admins Fields Create" COM_COMPONENTBUILDER_ADMINS_FIELDS_CREATE_DESC="Allows the users in this group to create create admins fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_DELETE="Admins Fields Delete" @@ -58,11 +58,11 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_STATE="Admins Fields Edit State" COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_VERSION="Admins Fields Edit Version" -COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins fields" +COM_COMPONENTBUILDER_ADMINS_FIELDS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins fields" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_ACCESS="Admins Fields Relations Access" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_ACCESS_DESC="Allows the users in this group to access access admins fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_USE="Admins Fields Relations Batch Use" -COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admins fields relations" +COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admins fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_CREATE="Admins Fields Relations Create" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_CREATE_DESC="Allows the users in this group to create create admins fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_DELETE="Admins Fields Relations Delete" @@ -78,15 +78,13 @@ COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_STATE="Admins Fields Relations Edit State" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin fields relations" COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_VERSION="Admins Fields Relations Edit Version" -COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admins fields relations" +COM_COMPONENTBUILDER_ADMINS_FIELDS_RELATIONS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admins fields relations" COM_COMPONENTBUILDER_ADMIN_VIEWS_ACCESS="Admin Views Access" COM_COMPONENTBUILDER_ADMIN_VIEWS_ACCESS_DESC="Allows the users in this group to access access admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_USE="Admin Views Batch Use" -COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch admin views" +COM_COMPONENTBUILDER_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_CREATE="Admin Views Create" COM_COMPONENTBUILDER_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create admin views" -COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_ADD="Admin Views Dashboard Add" -COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of admin view" COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_LIST="Admin Views Dashboard List" COM_COMPONENTBUILDER_ADMIN_VIEWS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of admin view" COM_COMPONENTBUILDER_ADMIN_VIEWS_DELETE="Admin Views Delete" @@ -102,7 +100,7 @@ COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the users in this group t COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_STATE="Admin Views Edit State" COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the admin view" COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_VERSION="Admin Views Edit Version" -COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version admin views" +COM_COMPONENTBUILDER_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_EXPORT="Admin Views Export" COM_COMPONENTBUILDER_ADMIN_VIEWS_EXPORT_DESC="Allows the users in this group to export export admin views" COM_COMPONENTBUILDER_ADMIN_VIEWS_IMPORT="Admin Views Import" @@ -114,7 +112,7 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the use COM_COMPONENTBUILDER_CLASS_EXTENDINGS_ACCESS="Class Extendings Access" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_ACCESS_DESC="Allows the users in this group to access access class extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_USE="Class Extendings Batch Use" -COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch class extendings" +COM_COMPONENTBUILDER_CLASS_EXTENDINGS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch class extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_CREATE="Class Extendings Create" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_CREATE_DESC="Allows the users in this group to create create class extendings" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_DELETE="Class Extendings Delete" @@ -130,11 +128,11 @@ COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_STATE="Class Extendings Edit State" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_STATE_DESC="Allows the users in this group to update the state of the class extends" COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_VERSION="Class Extendings Edit Version" -COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version class extendings" +COM_COMPONENTBUILDER_CLASS_EXTENDINGS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version class extendings" COM_COMPONENTBUILDER_CLASS_METHODS_ACCESS="Class Methods Access" COM_COMPONENTBUILDER_CLASS_METHODS_ACCESS_DESC="Allows the users in this group to access access class methods" COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_USE="Class Methods Batch Use" -COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch class methods" +COM_COMPONENTBUILDER_CLASS_METHODS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch class methods" COM_COMPONENTBUILDER_CLASS_METHODS_CREATE="Class Methods Create" COM_COMPONENTBUILDER_CLASS_METHODS_CREATE_DESC="Allows the users in this group to create create class methods" COM_COMPONENTBUILDER_CLASS_METHODS_DELETE="Class Methods Delete" @@ -150,7 +148,7 @@ COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_STATE="Class Methods Edit State" COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_STATE_DESC="Allows the users in this group to update the state of the class method" COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_VERSION="Class Methods Edit Version" -COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version class methods" +COM_COMPONENTBUILDER_CLASS_METHODS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version class methods" COM_COMPONENTBUILDER_CLASS_METHODS_EXPORT="Class Methods Export" COM_COMPONENTBUILDER_CLASS_METHODS_EXPORT_DESC="Allows the users in this group to export export class methods" COM_COMPONENTBUILDER_CLASS_METHODS_IMPORT="Class Methods Import" @@ -158,7 +156,7 @@ COM_COMPONENTBUILDER_CLASS_METHODS_IMPORT_DESC="Allows the users in this group t COM_COMPONENTBUILDER_CLASS_PROPERTIES_ACCESS="Class Properties Access" COM_COMPONENTBUILDER_CLASS_PROPERTIES_ACCESS_DESC="Allows the users in this group to access access class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_USE="Class Properties Batch Use" -COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch class properties" +COM_COMPONENTBUILDER_CLASS_PROPERTIES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_CREATE="Class Properties Create" COM_COMPONENTBUILDER_CLASS_PROPERTIES_CREATE_DESC="Allows the users in this group to create create class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_DELETE="Class Properties Delete" @@ -174,7 +172,7 @@ COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_STATE="Class Properties Edit State" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_STATE_DESC="Allows the users in this group to update the state of the class property" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_VERSION="Class Properties Edit Version" -COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version class properties" +COM_COMPONENTBUILDER_CLASS_PROPERTIES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EXPORT="Class Properties Export" COM_COMPONENTBUILDER_CLASS_PROPERTIES_EXPORT_DESC="Allows the users in this group to export export class properties" COM_COMPONENTBUILDER_CLASS_PROPERTIES_IMPORT="Class Properties Import" @@ -196,7 +194,7 @@ COM_COMPONENTBUILDER_COMPILER_TRANSLATE_BUTTON_ACCESS_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_ACCESS="Components Admin Views Access" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_ACCESS_DESC="Allows the users in this group to access access components admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_USE="Components Admin Views Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components admin views" +COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_CREATE="Components Admin Views Create" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create components admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_DELETE="Components Admin Views Delete" @@ -212,11 +210,11 @@ COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the users in t COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_STATE="Components Admin Views Edit State" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component admin views" COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_VERSION="Components Admin Views Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components admin views" +COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components admin views" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_ACCESS="Components Config Access" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_ACCESS_DESC="Allows the users in this group to access access components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_USE="Components Config Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components config" +COM_COMPONENTBUILDER_COMPONENTS_CONFIG_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_CREATE="Components Config Create" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_CREATE_DESC="Allows the users in this group to create create components config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_DELETE="Components Config Delete" @@ -232,11 +230,11 @@ COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_OWN_DESC="Allows the users in this g COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_STATE="Components Config Edit State" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_STATE_DESC="Allows the users in this group to update the state of the component config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_VERSION="Components Config Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components config" +COM_COMPONENTBUILDER_COMPONENTS_CONFIG_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components config" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_ACCESS="Components Custom Admin Menus Access" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_ACCESS_DESC="Allows the users in this group to access access components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_USE="Components Custom Admin Menus Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components custom admin menus" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_CREATE="Components Custom Admin Menus Create" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_CREATE_DESC="Allows the users in this group to create create components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_DELETE="Components Custom Admin Menus Delete" @@ -252,11 +250,11 @@ COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_OWN_DESC="Allows the use COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_STATE="Components Custom Admin Menus Edit State" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_VERSION="Components Custom Admin Menus Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components custom admin menus" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_MENUS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components custom admin menus" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_ACCESS="Components Custom Admin Views Access" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_ACCESS_DESC="Allows the users in this group to access access components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_USE="Components Custom Admin Views Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components custom admin views" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_CREATE="Components Custom Admin Views Create" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_DELETE="Components Custom Admin Views Delete" @@ -272,11 +270,11 @@ COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the use COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_STATE="Components Custom Admin Views Edit State" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component custom admin views" COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_VERSION="Components Custom Admin Views Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components custom admin views" +COM_COMPONENTBUILDER_COMPONENTS_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components custom admin views" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_ACCESS="Components Dashboard Access" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_ACCESS_DESC="Allows the users in this group to access access components dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_USE="Components Dashboard Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components dashboard" +COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_CREATE="Components Dashboard Create" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_CREATE_DESC="Allows the users in this group to create create components dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_DELETE="Components Dashboard Delete" @@ -292,11 +290,11 @@ COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_OWN_DESC="Allows the users in thi COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_STATE="Components Dashboard Edit State" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_STATE_DESC="Allows the users in this group to update the state of the component dashboard" COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_VERSION="Components Dashboard Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components dashboard" +COM_COMPONENTBUILDER_COMPONENTS_DASHBOARD_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components dashboard" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_ACCESS="Components Files Folders Access" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_ACCESS_DESC="Allows the users in this group to access access components files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_USE="Components Files Folders Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components files folders" +COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_CREATE="Components Files Folders Create" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_CREATE_DESC="Allows the users in this group to create create components files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_DELETE="Components Files Folders Delete" @@ -312,11 +310,11 @@ COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_STATE="Components Files Folders Edit State" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component files folders" COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_VERSION="Components Files Folders Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components files folders" +COM_COMPONENTBUILDER_COMPONENTS_FILES_FOLDERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components files folders" COM_COMPONENTBUILDER_COMPONENTS_MODULES_ACCESS="Components Modules Access" COM_COMPONENTBUILDER_COMPONENTS_MODULES_ACCESS_DESC="Allows the users in this group to access access components modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_USE="Components Modules Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components modules" +COM_COMPONENTBUILDER_COMPONENTS_MODULES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_CREATE="Components Modules Create" COM_COMPONENTBUILDER_COMPONENTS_MODULES_CREATE_DESC="Allows the users in this group to create create components modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_DELETE="Components Modules Delete" @@ -332,11 +330,11 @@ COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_STATE="Components Modules Edit State" COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_STATE_DESC="Allows the users in this group to update the state of the component modules" COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_VERSION="Components Modules Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components modules" +COM_COMPONENTBUILDER_COMPONENTS_MODULES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components modules" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_ACCESS="Components Mysql Tweaks Access" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_ACCESS_DESC="Allows the users in this group to access access components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_USE="Components Mysql Tweaks Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components mysql tweaks" +COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_CREATE="Components Mysql Tweaks Create" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_CREATE_DESC="Allows the users in this group to create create components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_DELETE="Components Mysql Tweaks Delete" @@ -352,11 +350,11 @@ COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_STATE="Components Mysql Tweaks Edit State" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION="Components Mysql Tweaks Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components mysql tweaks" +COM_COMPONENTBUILDER_COMPONENTS_MYSQL_TWEAKS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components mysql tweaks" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS="Components Placeholders Access" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to access access components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE="Components Placeholders Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE="Components Placeholders Create" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_DELETE="Components Placeholders Delete" @@ -372,11 +370,11 @@ COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE="Components Placeholders Edit State" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION="Components Placeholders Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components placeholders" +COM_COMPONENTBUILDER_COMPONENTS_PLACEHOLDERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components placeholders" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_ACCESS="Components Plugins Access" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_ACCESS_DESC="Allows the users in this group to access access components plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_USE="Components Plugins Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components plugins" +COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_CREATE="Components Plugins Create" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_CREATE_DESC="Allows the users in this group to create create components plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_DELETE="Components Plugins Delete" @@ -392,11 +390,11 @@ COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_STATE="Components Plugins Edit State" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component plugins" COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_VERSION="Components Plugins Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components plugins" +COM_COMPONENTBUILDER_COMPONENTS_PLUGINS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components plugins" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS="Components Site Views Access" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_ACCESS_DESC="Allows the users in this group to access access components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE="Components Site Views Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components site views" +COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_CREATE="Components Site Views Create" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_CREATE_DESC="Allows the users in this group to create create components site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_DELETE="Components Site Views Delete" @@ -412,11 +410,11 @@ COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_OWN_DESC="Allows the users in th COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_STATE="Components Site Views Edit State" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the component site views" COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_VERSION="Components Site Views Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components site views" +COM_COMPONENTBUILDER_COMPONENTS_SITE_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components site views" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_ACCESS="Components Updates Access" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_ACCESS_DESC="Allows the users in this group to access access components updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_USE="Components Updates Batch Use" -COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch components updates" +COM_COMPONENTBUILDER_COMPONENTS_UPDATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch components updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_CREATE="Components Updates Create" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_CREATE_DESC="Allows the users in this group to create create components updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_DELETE="Components Updates Delete" @@ -432,16 +430,14 @@ COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_STATE="Components Updates Edit State" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the component updates" COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_VERSION="Components Updates Edit Version" -COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version components updates" +COM_COMPONENTBUILDER_COMPONENTS_UPDATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version components updates" COM_COMPONENTBUILDER_CONFIGURATION="Component Builder Configuration" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_ACCESS="Custom Admin Views Access" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_ACCESS_DESC="Allows the users in this group to access access custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_USE="Custom Admin Views Batch Use" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch custom admin views" +COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_CREATE="Custom Admin Views Create" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_CREATE_DESC="Allows the users in this group to create create custom admin views" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_ADD="Custom Admin Views Dashboard Add" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of custom admin view" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_LIST="Custom Admin Views Dashboard List" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of custom admin view" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_DELETE="Custom Admin Views Delete" @@ -453,7 +449,7 @@ COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_OWN_DESC="Allows the users in this COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_STATE="Custom Admin Views Edit State" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the custom admin view" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_VERSION="Custom Admin Views Edit Version" -COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version custom admin views" +COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EXPORT="Custom Admin Views Export" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_EXPORT_DESC="Allows the users in this group to export export custom admin views" COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEWS_IMPORT="Custom Admin Views Import" @@ -465,7 +461,7 @@ COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_GET_SNIPPETS_BUTTON_ACCESS_DESC="Allows t COM_COMPONENTBUILDER_CUSTOM_CODES_ACCESS="Custom Codes Access" COM_COMPONENTBUILDER_CUSTOM_CODES_ACCESS_DESC="Allows the users in this group to access access custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_USE="Custom Codes Batch Use" -COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch custom codes" +COM_COMPONENTBUILDER_CUSTOM_CODES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_CREATE="Custom Codes Create" COM_COMPONENTBUILDER_CUSTOM_CODES_CREATE_DESC="Allows the users in this group to create create custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_DASHBOARD_LIST="Custom Codes Dashboard List" @@ -483,7 +479,7 @@ COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_STATE="Custom Codes Edit State" COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_STATE_DESC="Allows the users in this group to update the state of the custom code" COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_VERSION="Custom Codes Edit Version" -COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version custom codes" +COM_COMPONENTBUILDER_CUSTOM_CODES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_EXPORT="Custom Codes Export" COM_COMPONENTBUILDER_CUSTOM_CODES_EXPORT_DESC="Allows the users in this group to export export custom codes" COM_COMPONENTBUILDER_CUSTOM_CODES_IMPORT="Custom Codes Import" @@ -495,7 +491,7 @@ COM_COMPONENTBUILDER_CUSTOM_CODE_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the us COM_COMPONENTBUILDER_DYNAMIC_GETS_ACCESS="Dynamic Gets Access" COM_COMPONENTBUILDER_DYNAMIC_GETS_ACCESS_DESC="Allows the users in this group to access access dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_USE="Dynamic Gets Batch Use" -COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch dynamic gets" +COM_COMPONENTBUILDER_DYNAMIC_GETS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_CREATE="Dynamic Gets Create" COM_COMPONENTBUILDER_DYNAMIC_GETS_CREATE_DESC="Allows the users in this group to create create dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_DASHBOARD_ADD="Dynamic Gets Dashboard Add" @@ -511,7 +507,7 @@ COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_STATE="Dynamic Gets Edit State" COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_STATE_DESC="Allows the users in this group to update the state of the dynamic get" COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_VERSION="Dynamic Gets Edit Version" -COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version dynamic gets" +COM_COMPONENTBUILDER_DYNAMIC_GETS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_EXPORT="Dynamic Gets Export" COM_COMPONENTBUILDER_DYNAMIC_GETS_EXPORT_DESC="Allows the users in this group to export export dynamic gets" COM_COMPONENTBUILDER_DYNAMIC_GETS_IMPORT="Dynamic Gets Import" @@ -531,7 +527,7 @@ COM_COMPONENTBUILDER_EXPORT_DATA_DESC="Allows users in this group to export data COM_COMPONENTBUILDER_FIELDS_ACCESS="Fields Access" COM_COMPONENTBUILDER_FIELDS_ACCESS_DESC="Allows the users in this group to access access fields" COM_COMPONENTBUILDER_FIELDS_BATCH_USE="Fields Batch Use" -COM_COMPONENTBUILDER_FIELDS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch fields" +COM_COMPONENTBUILDER_FIELDS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch fields" COM_COMPONENTBUILDER_FIELDS_CREATE="Fields Create" COM_COMPONENTBUILDER_FIELDS_CREATE_DESC="Allows the users in this group to create create fields" COM_COMPONENTBUILDER_FIELDS_DASHBOARD_ADD="Fields Dashboard Add" @@ -547,7 +543,7 @@ COM_COMPONENTBUILDER_FIELDS_EDIT_OWN_DESC="Allows the users in this group to edi COM_COMPONENTBUILDER_FIELDS_EDIT_STATE="Fields Edit State" COM_COMPONENTBUILDER_FIELDS_EDIT_STATE_DESC="Allows the users in this group to update the state of the field" COM_COMPONENTBUILDER_FIELDS_EDIT_VERSION="Fields Edit Version" -COM_COMPONENTBUILDER_FIELDS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version fields" +COM_COMPONENTBUILDER_FIELDS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version fields" COM_COMPONENTBUILDER_FIELDS_EXPORT="Fields Export" COM_COMPONENTBUILDER_FIELDS_EXPORT_DESC="Allows the users in this group to export export fields" COM_COMPONENTBUILDER_FIELDS_IMPORT="Fields Import" @@ -557,7 +553,7 @@ COM_COMPONENTBUILDER_FIELDS_SUBMENU_DESC="Allows the users in this group to subm COM_COMPONENTBUILDER_FIELDTYPES_ACCESS="Fieldtypes Access" COM_COMPONENTBUILDER_FIELDTYPES_ACCESS_DESC="Allows the users in this group to access access fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE="Fieldtypes Batch Use" -COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch fieldtypes" +COM_COMPONENTBUILDER_FIELDTYPES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_CREATE="Fieldtypes Create" COM_COMPONENTBUILDER_FIELDTYPES_CREATE_DESC="Allows the users in this group to create create fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_DASHBOARD_LIST="Fieldtypes Dashboard List" @@ -571,7 +567,7 @@ COM_COMPONENTBUILDER_FIELDTYPES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_FIELDTYPES_EDIT_STATE="Fieldtypes Edit State" COM_COMPONENTBUILDER_FIELDTYPES_EDIT_STATE_DESC="Allows the users in this group to update the state of the fieldtype" COM_COMPONENTBUILDER_FIELDTYPES_EDIT_VERSION="Fieldtypes Edit Version" -COM_COMPONENTBUILDER_FIELDTYPES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version fieldtypes" +COM_COMPONENTBUILDER_FIELDTYPES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_EXPORT="Fieldtypes Export" COM_COMPONENTBUILDER_FIELDTYPES_EXPORT_DESC="Allows the users in this group to export export fieldtypes" COM_COMPONENTBUILDER_FIELDTYPES_IMPORT="Fieldtypes Import" @@ -601,7 +597,7 @@ COM_COMPONENTBUILDER_GET_SNIPPETS_TEMPLATES_BUTTON_ACCESS_DESC="Allows the users COM_COMPONENTBUILDER_HELP_DOCUMENTS_ACCESS="Help Documents Access" COM_COMPONENTBUILDER_HELP_DOCUMENTS_ACCESS_DESC="Allows the users in this group to access access help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_USE="Help Documents Batch Use" -COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch help documents" +COM_COMPONENTBUILDER_HELP_DOCUMENTS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_CREATE="Help Documents Create" COM_COMPONENTBUILDER_HELP_DOCUMENTS_CREATE_DESC="Allows the users in this group to create create help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_DASHBOARD_LIST="Help Documents Dashboard List" @@ -615,7 +611,7 @@ COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_OWN_DESC="Allows the users in this grou COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_STATE="Help Documents Edit State" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_STATE_DESC="Allows the users in this group to update the state of the help document" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_VERSION="Help Documents Edit Version" -COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version help documents" +COM_COMPONENTBUILDER_HELP_DOCUMENTS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EXPORT="Help Documents Export" COM_COMPONENTBUILDER_HELP_DOCUMENTS_EXPORT_DESC="Allows the users in this group to export export help documents" COM_COMPONENTBUILDER_HELP_DOCUMENTS_IMPORT="Help Documents Import" @@ -627,7 +623,7 @@ COM_COMPONENTBUILDER_IMPORT_DATA_DESC="Allows users in this group to import data COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_ACCESS="Joomla Components Access" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_ACCESS_DESC="Allows the users in this group to access access joomla components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE="Joomla Components Batch Use" -COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla components" +COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_CREATE="Joomla Components Create" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_CREATE_DESC="Allows the users in this group to create create joomla components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_DASHBOARD_LIST="Joomla Components Dashboard List" @@ -645,7 +641,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_OWN_DESC="Allows the users in this g COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_STATE="Joomla Components Edit State" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla component" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION="Joomla Components Edit Version" -COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla components" +COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla components" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU="Joomla Components Submenu" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU_DESC="Allows the users in this group to submenu of joomla component" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS="Joomla Component Backup Button Access" @@ -663,7 +659,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows t COM_COMPONENTBUILDER_JOOMLA_MODULES_ACCESS="Joomla Modules Access" COM_COMPONENTBUILDER_JOOMLA_MODULES_ACCESS_DESC="Allows the users in this group to access access joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_USE="Joomla Modules Batch Use" -COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla modules" +COM_COMPONENTBUILDER_JOOMLA_MODULES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_CREATE="Joomla Modules Create" COM_COMPONENTBUILDER_JOOMLA_MODULES_CREATE_DESC="Allows the users in this group to create create joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_DASHBOARD_LIST="Joomla Modules Dashboard List" @@ -681,13 +677,13 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_OWN_DESC="Allows the users in this grou COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_STATE="Joomla Modules Edit State" COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla module" COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_VERSION="Joomla Modules Edit Version" -COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla modules" +COM_COMPONENTBUILDER_JOOMLA_MODULES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_EXPORT="Joomla Modules Export" COM_COMPONENTBUILDER_JOOMLA_MODULES_EXPORT_DESC="Allows the users in this group to export export joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_ACCESS="Joomla Modules Files Folders Urls Access" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_ACCESS_DESC="Allows the users in this group to access access joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_USE="Joomla Modules Files Folders Urls Batch Use" -COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla modules files folders urls" +COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_CREATE="Joomla Modules Files Folders Urls Create" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_CREATE_DESC="Allows the users in this group to create create joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_DELETE="Joomla Modules Files Folders Urls Delete" @@ -703,7 +699,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_OWN_DESC="Allows the COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_STATE="Joomla Modules Files Folders Urls Edit State" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla module files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_VERSION="Joomla Modules Files Folders Urls Edit Version" -COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla modules files folders urls" +COM_COMPONENTBUILDER_JOOMLA_MODULES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla modules files folders urls" COM_COMPONENTBUILDER_JOOMLA_MODULES_IMPORT="Joomla Modules Import" COM_COMPONENTBUILDER_JOOMLA_MODULES_IMPORT_DESC="Allows the users in this group to import import joomla modules" COM_COMPONENTBUILDER_JOOMLA_MODULES_SUBMENU="Joomla Modules Submenu" @@ -711,7 +707,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_SUBMENU_DESC="Allows the users in this group COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_ACCESS="Joomla Modules Updates Access" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_ACCESS_DESC="Allows the users in this group to access access joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_USE="Joomla Modules Updates Batch Use" -COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla modules updates" +COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_CREATE="Joomla Modules Updates Create" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_CREATE_DESC="Allows the users in this group to create create joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_DELETE="Joomla Modules Updates Delete" @@ -727,7 +723,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_OWN_DESC="Allows the users in t COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_STATE="Joomla Modules Updates Edit State" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla module updates" COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_VERSION="Joomla Modules Updates Edit Version" -COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla modules updates" +COM_COMPONENTBUILDER_JOOMLA_MODULES_UPDATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla modules updates" COM_COMPONENTBUILDER_JOOMLA_MODULE_GET_SNIPPETS_BUTTON_ACCESS="Joomla Module Get Snippets Button Access" COM_COMPONENTBUILDER_JOOMLA_MODULE_GET_SNIPPETS_BUTTON_ACCESS_DESC="Allows the users in this group to access the get snippets button." COM_COMPONENTBUILDER_JOOMLA_MODULE_RUN_EXPANSION_BUTTON_ACCESS="Joomla Module Run Expansion Button Access" @@ -735,7 +731,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULE_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the COM_COMPONENTBUILDER_JOOMLA_PLUGINS_ACCESS="Joomla Plugins Access" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_ACCESS_DESC="Allows the users in this group to access access joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_USE="Joomla Plugins Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugins" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_CREATE="Joomla Plugins Create" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_CREATE_DESC="Allows the users in this group to create create joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_DASHBOARD_LIST="Joomla Plugins Dashboard List" @@ -753,11 +749,11 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_OWN_DESC="Allows the users in this grou COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_STATE="Joomla Plugins Edit State" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla plugin" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_VERSION="Joomla Plugins Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugins" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugins" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_ACCESS="Joomla Plugins Files Folders Urls Access" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_ACCESS_DESC="Allows the users in this group to access access joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_USE="Joomla Plugins Files Folders Urls Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugins files folders urls" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_CREATE="Joomla Plugins Files Folders Urls Create" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_CREATE_DESC="Allows the users in this group to create create joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_DELETE="Joomla Plugins Files Folders Urls Delete" @@ -773,13 +769,13 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_OWN_DESC="Allows the COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_STATE="Joomla Plugins Files Folders Urls Edit State" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla plugin files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_VERSION="Joomla Plugins Files Folders Urls Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugins files folders urls" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugins files folders urls" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_SUBMENU="Joomla Plugins Submenu" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_SUBMENU_DESC="Allows the users in this group to submenu of joomla plugin" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_ACCESS="Joomla Plugins Updates Access" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_ACCESS_DESC="Allows the users in this group to access access joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_USE="Joomla Plugins Updates Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugins updates" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_CREATE="Joomla Plugins Updates Create" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_CREATE_DESC="Allows the users in this group to create create joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_DELETE="Joomla Plugins Updates Delete" @@ -795,15 +791,15 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_OWN_DESC="Allows the users in t COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_STATE="Joomla Plugins Updates Edit State" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the joomla plugin updates" COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_VERSION="Joomla Plugins Updates Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugins updates" +COM_COMPONENTBUILDER_JOOMLA_PLUGINS_UPDATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugins updates" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GET_BOILERPLATE_BUTTON_ACCESS="Joomla Plugin Get Boilerplate Button Access" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GET_BOILERPLATE_BUTTON_ACCESS_DESC="Allows the users in this group to access the get boilerplate button." COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_ACCESS="Joomla Plugin Groups Access" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_ACCESS_DESC="Allows the users in this group to access access joomla plugin groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_USE="Joomla Plugin Groups Batch Use" -COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch joomla plugin groups" +COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch joomla plugin groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_EDIT_VERSION="Joomla Plugin Groups Edit Version" -COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version joomla plugin groups" +COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUPS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version joomla plugin groups" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_METHODS_BUTTON_ACCESS="Joomla Plugin Methods Button Access" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_METHODS_BUTTON_ACCESS_DESC="Allows the users in this group to access the methods button." COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PROPERTIES_BUTTON_ACCESS="Joomla Plugin Properties Button Access" @@ -813,7 +809,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the COM_COMPONENTBUILDER_LANGUAGES_ACCESS="Languages Access" COM_COMPONENTBUILDER_LANGUAGES_ACCESS_DESC="Allows the users in this group to access access languages" COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE="Languages Batch Use" -COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch languages" +COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch languages" COM_COMPONENTBUILDER_LANGUAGES_CREATE="Languages Create" COM_COMPONENTBUILDER_LANGUAGES_CREATE_DESC="Allows the users in this group to create create languages" COM_COMPONENTBUILDER_LANGUAGES_DELETE="Languages Delete" @@ -825,7 +821,7 @@ COM_COMPONENTBUILDER_LANGUAGES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_LANGUAGES_EDIT_STATE="Languages Edit State" COM_COMPONENTBUILDER_LANGUAGES_EDIT_STATE_DESC="Allows the users in this group to update the state of the language" COM_COMPONENTBUILDER_LANGUAGES_EDIT_VERSION="Languages Edit Version" -COM_COMPONENTBUILDER_LANGUAGES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version languages" +COM_COMPONENTBUILDER_LANGUAGES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version languages" COM_COMPONENTBUILDER_LANGUAGES_EXPORT="Languages Export" COM_COMPONENTBUILDER_LANGUAGES_EXPORT_DESC="Allows the users in this group to export export languages" COM_COMPONENTBUILDER_LANGUAGES_IMPORT="Languages Import" @@ -837,7 +833,7 @@ COM_COMPONENTBUILDER_LANGUAGE_BUILD_BUTTON_ACCESS_DESC="Allows the users in this COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_ACCESS="Language Translations Access" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_ACCESS_DESC="Allows the users in this group to access access language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE="Language Translations Batch Use" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch language translations" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_CREATE="Language Translations Create" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_CREATE_DESC="Allows the users in this group to create create language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_DASHBOARD_LIST="Language Translations Dashboard List" @@ -851,7 +847,7 @@ COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_OWN_DESC="Allows the users in th COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_STATE="Language Translations Edit State" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_STATE_DESC="Allows the users in this group to update the state of the language translation" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_VERSION="Language Translations Edit Version" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version language translations" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EXPORT="Language Translations Export" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_EXPORT_DESC="Allows the users in this group to export export language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_IMPORT="Language Translations Import" @@ -861,7 +857,7 @@ COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_SUBMENU_DESC="Allows the users in thi COM_COMPONENTBUILDER_LAYOUTS_ACCESS="Layouts Access" COM_COMPONENTBUILDER_LAYOUTS_ACCESS_DESC="Allows the users in this group to access access layouts" COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE="Layouts Batch Use" -COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch layouts" +COM_COMPONENTBUILDER_LAYOUTS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch layouts" COM_COMPONENTBUILDER_LAYOUTS_CREATE="Layouts Create" COM_COMPONENTBUILDER_LAYOUTS_CREATE_DESC="Allows the users in this group to create create layouts" COM_COMPONENTBUILDER_LAYOUTS_DASHBOARD_LIST="Layouts Dashboard List" @@ -875,7 +871,7 @@ COM_COMPONENTBUILDER_LAYOUTS_EDIT_OWN_DESC="Allows the users in this group to ed COM_COMPONENTBUILDER_LAYOUTS_EDIT_STATE="Layouts Edit State" COM_COMPONENTBUILDER_LAYOUTS_EDIT_STATE_DESC="Allows the users in this group to update the state of the layout" COM_COMPONENTBUILDER_LAYOUTS_EDIT_VERSION="Layouts Edit Version" -COM_COMPONENTBUILDER_LAYOUTS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version layouts" +COM_COMPONENTBUILDER_LAYOUTS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version layouts" COM_COMPONENTBUILDER_LAYOUTS_EXPORT="Layouts Export" COM_COMPONENTBUILDER_LAYOUTS_EXPORT_DESC="Allows the users in this group to export export layouts" COM_COMPONENTBUILDER_LAYOUTS_IMPORT="Layouts Import" @@ -887,11 +883,11 @@ COM_COMPONENTBUILDER_LAYOUT_GET_SNIPPETS_BUTTON_ACCESS_DESC="Allows the users in COM_COMPONENTBUILDER_LIBRARIES_ACCESS="Libraries Access" COM_COMPONENTBUILDER_LIBRARIES_ACCESS_DESC="Allows the users in this group to access access libraries" COM_COMPONENTBUILDER_LIBRARIES_BATCH_USE="Libraries Batch Use" -COM_COMPONENTBUILDER_LIBRARIES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch libraries" +COM_COMPONENTBUILDER_LIBRARIES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch libraries" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_ACCESS="Libraries Config Access" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_ACCESS_DESC="Allows the users in this group to access access libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_USE="Libraries Config Batch Use" -COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch libraries config" +COM_COMPONENTBUILDER_LIBRARIES_CONFIG_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_CREATE="Libraries Config Create" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_CREATE_DESC="Allows the users in this group to create create libraries config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_DELETE="Libraries Config Delete" @@ -907,7 +903,7 @@ COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_STATE="Libraries Config Edit State" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_STATE_DESC="Allows the users in this group to update the state of the library config" COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_VERSION="Libraries Config Edit Version" -COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_VERSION_DESC="Allows users in this group to edit versions of version libraries config" +COM_COMPONENTBUILDER_LIBRARIES_CONFIG_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version libraries config" COM_COMPONENTBUILDER_LIBRARIES_CREATE="Libraries Create" COM_COMPONENTBUILDER_LIBRARIES_CREATE_DESC="Allows the users in this group to create create libraries" COM_COMPONENTBUILDER_LIBRARIES_DASHBOARD_LIST="Libraries Dashboard List" @@ -921,11 +917,11 @@ COM_COMPONENTBUILDER_LIBRARIES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_LIBRARIES_EDIT_STATE="Libraries Edit State" COM_COMPONENTBUILDER_LIBRARIES_EDIT_STATE_DESC="Allows the users in this group to update the state of the library" COM_COMPONENTBUILDER_LIBRARIES_EDIT_VERSION="Libraries Edit Version" -COM_COMPONENTBUILDER_LIBRARIES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version libraries" +COM_COMPONENTBUILDER_LIBRARIES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version libraries" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_ACCESS="Libraries Files Folders Urls Access" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_ACCESS_DESC="Allows the users in this group to access access libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_USE="Libraries Files Folders Urls Batch Use" -COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch libraries files folders urls" +COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_CREATE="Libraries Files Folders Urls Create" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_CREATE_DESC="Allows the users in this group to create create libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_DELETE="Libraries Files Folders Urls Delete" @@ -941,7 +937,7 @@ COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_OWN_DESC="Allows the user COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_STATE="Libraries Files Folders Urls Edit State" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_STATE_DESC="Allows the users in this group to update the state of the library files folders urls" COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_VERSION="Libraries Files Folders Urls Edit Version" -COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version libraries files folders urls" +COM_COMPONENTBUILDER_LIBRARIES_FILES_FOLDERS_URLS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version libraries files folders urls" COM_COMPONENTBUILDER_LIBRARIES_SUBMENU="Libraries Submenu" COM_COMPONENTBUILDER_LIBRARIES_SUBMENU_DESC="Allows the users in this group to submenu of library" COM_COMPONENTBUILDER_LIBRARY_GET_SNIPPETS_BUTTON_ACCESS="Library Get Snippets Button Access" @@ -963,6 +959,7 @@ COM_COMPONENTBUILDER_MENU_LAYOUTS="Layouts" COM_COMPONENTBUILDER_MENU_LIBRARIES="Libraries" COM_COMPONENTBUILDER_MENU_PLACEHOLDERS="Placeholders" COM_COMPONENTBUILDER_MENU_POWERS="Powers" +COM_COMPONENTBUILDER_MENU_SEARCH="Search" COM_COMPONENTBUILDER_MENU_SITE_VIEWS="Site Views" COM_COMPONENTBUILDER_MENU_SNIPPETS="Snippets" COM_COMPONENTBUILDER_MENU_TEMPLATES="Templates" @@ -970,7 +967,7 @@ COM_COMPONENTBUILDER_MENU_VALIDATION_RULES="Validation Rules" COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS="Placeholders Access" COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS_DESC="Allows the users in this group to access access placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE="Placeholders Batch Use" -COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE="Placeholders Create" COM_COMPONENTBUILDER_PLACEHOLDERS_CREATE_DESC="Allows the users in this group to create create placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_DASHBOARD_LIST="Placeholders Dashboard List" @@ -984,7 +981,7 @@ COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE="Placeholders Edit State" COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the placeholder" COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION="Placeholders Edit Version" -COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version placeholders" +COM_COMPONENTBUILDER_PLACEHOLDERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT="Placeholders Export" COM_COMPONENTBUILDER_PLACEHOLDERS_EXPORT_DESC="Allows the users in this group to export export placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_IMPORT="Placeholders Import" @@ -994,7 +991,7 @@ COM_COMPONENTBUILDER_PLACEHOLDERS_SUBMENU_DESC="Allows the users in this group t COM_COMPONENTBUILDER_POWERS_ACCESS="Powers Access" COM_COMPONENTBUILDER_POWERS_ACCESS_DESC="Allows the users in this group to access access powers" COM_COMPONENTBUILDER_POWERS_BATCH_USE="Powers Batch Use" -COM_COMPONENTBUILDER_POWERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch powers" +COM_COMPONENTBUILDER_POWERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch powers" COM_COMPONENTBUILDER_POWERS_CREATE="Powers Create" COM_COMPONENTBUILDER_POWERS_CREATE_DESC="Allows the users in this group to create create powers" COM_COMPONENTBUILDER_POWERS_DASHBOARD_LIST="Powers Dashboard List" @@ -1012,15 +1009,27 @@ COM_COMPONENTBUILDER_POWERS_EDIT_OWN_DESC="Allows the users in this group to edi COM_COMPONENTBUILDER_POWERS_EDIT_STATE="Powers Edit State" COM_COMPONENTBUILDER_POWERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the power" COM_COMPONENTBUILDER_POWERS_EDIT_VERSION="Powers Edit Version" -COM_COMPONENTBUILDER_POWERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version powers" +COM_COMPONENTBUILDER_POWERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version powers" COM_COMPONENTBUILDER_POWERS_SUBMENU="Powers Submenu" COM_COMPONENTBUILDER_POWERS_SUBMENU_DESC="Allows the users in this group to submenu of power" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS="Power Init Button Access" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS_DESC="Allows the users in this group to access the init button." +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS="Power Reset Button Access" +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS_DESC="Allows the users in this group to access the reset button." COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS="Power Run Expansion Button Access" COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the users in this group to access the run expansion button." +COM_COMPONENTBUILDER_SEARCH_ACCESS="Search Access" +COM_COMPONENTBUILDER_SEARCH_ACCESS_DESC="Allows the users in this group to access search." +COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS="Search Compiler Button Access" +COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS_DESC="Allows the users in this group to access the compiler button." +COM_COMPONENTBUILDER_SEARCH_DASHBOARD_LIST="Search Dashboard List" +COM_COMPONENTBUILDER_SEARCH_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of Search" +COM_COMPONENTBUILDER_SEARCH_SUBMENU="Search Submenu" +COM_COMPONENTBUILDER_SEARCH_SUBMENU_DESC="Allows the users in this group to submenu of Search" COM_COMPONENTBUILDER_SERVERS_ACCESS="Servers Access" COM_COMPONENTBUILDER_SERVERS_ACCESS_DESC="Allows the users in this group to access access servers" COM_COMPONENTBUILDER_SERVERS_BATCH_USE="Servers Batch Use" -COM_COMPONENTBUILDER_SERVERS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch servers" +COM_COMPONENTBUILDER_SERVERS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch servers" COM_COMPONENTBUILDER_SERVERS_CREATE="Servers Create" COM_COMPONENTBUILDER_SERVERS_CREATE_DESC="Allows the users in this group to create create servers" COM_COMPONENTBUILDER_SERVERS_DASHBOARD_LIST="Servers Dashboard List" @@ -1038,7 +1047,7 @@ COM_COMPONENTBUILDER_SERVERS_EDIT_OWN_DESC="Allows the users in this group to ed COM_COMPONENTBUILDER_SERVERS_EDIT_STATE="Servers Edit State" COM_COMPONENTBUILDER_SERVERS_EDIT_STATE_DESC="Allows the users in this group to update the state of the server" COM_COMPONENTBUILDER_SERVERS_EDIT_VERSION="Servers Edit Version" -COM_COMPONENTBUILDER_SERVERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version servers" +COM_COMPONENTBUILDER_SERVERS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version servers" COM_COMPONENTBUILDER_SERVERS_EXPORT="Servers Export" COM_COMPONENTBUILDER_SERVERS_EXPORT_DESC="Allows the users in this group to export export servers" COM_COMPONENTBUILDER_SERVERS_IMPORT="Servers Import" @@ -1048,11 +1057,9 @@ COM_COMPONENTBUILDER_SERVERS_SUBMENU_DESC="Allows the users in this group to sub COM_COMPONENTBUILDER_SITE_VIEWS_ACCESS="Site Views Access" COM_COMPONENTBUILDER_SITE_VIEWS_ACCESS_DESC="Allows the users in this group to access access site views" COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_USE="Site Views Batch Use" -COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch site views" +COM_COMPONENTBUILDER_SITE_VIEWS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch site views" COM_COMPONENTBUILDER_SITE_VIEWS_CREATE="Site Views Create" COM_COMPONENTBUILDER_SITE_VIEWS_CREATE_DESC="Allows the users in this group to create create site views" -COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_ADD="Site Views Dashboard Add" -COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_ADD_DESC="Allows the users in this group to dashboard add of site view" COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_LIST="Site Views Dashboard List" COM_COMPONENTBUILDER_SITE_VIEWS_DASHBOARD_LIST_DESC="Allows the users in this group to dashboard list of site view" COM_COMPONENTBUILDER_SITE_VIEWS_DELETE="Site Views Delete" @@ -1064,7 +1071,7 @@ COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_STATE="Site Views Edit State" COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_STATE_DESC="Allows the users in this group to update the state of the site view" COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_VERSION="Site Views Edit Version" -COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version site views" +COM_COMPONENTBUILDER_SITE_VIEWS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version site views" COM_COMPONENTBUILDER_SITE_VIEWS_EXPORT="Site Views Export" COM_COMPONENTBUILDER_SITE_VIEWS_EXPORT_DESC="Allows the users in this group to export export site views" COM_COMPONENTBUILDER_SITE_VIEWS_IMPORT="Site Views Import" @@ -1076,7 +1083,7 @@ COM_COMPONENTBUILDER_SITE_VIEW_GET_SNIPPETS_BUTTON_ACCESS_DESC="Allows the users COM_COMPONENTBUILDER_SNIPPETS_ACCESS="Snippets Access" COM_COMPONENTBUILDER_SNIPPETS_ACCESS_DESC="Allows the users in this group to access access snippets" COM_COMPONENTBUILDER_SNIPPETS_BATCH_USE="Snippets Batch Use" -COM_COMPONENTBUILDER_SNIPPETS_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch snippets" +COM_COMPONENTBUILDER_SNIPPETS_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch snippets" COM_COMPONENTBUILDER_SNIPPETS_CREATE="Snippets Create" COM_COMPONENTBUILDER_SNIPPETS_CREATE_DESC="Allows the users in this group to create create snippets" COM_COMPONENTBUILDER_SNIPPETS_DASHBOARD_LIST="Snippets Dashboard List" @@ -1090,7 +1097,7 @@ COM_COMPONENTBUILDER_SNIPPETS_EDIT_OWN_DESC="Allows the users in this group to e COM_COMPONENTBUILDER_SNIPPETS_EDIT_STATE="Snippets Edit State" COM_COMPONENTBUILDER_SNIPPETS_EDIT_STATE_DESC="Allows the users in this group to update the state of the snippet" COM_COMPONENTBUILDER_SNIPPETS_EDIT_VERSION="Snippets Edit Version" -COM_COMPONENTBUILDER_SNIPPETS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version snippets" +COM_COMPONENTBUILDER_SNIPPETS_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version snippets" COM_COMPONENTBUILDER_SNIPPETS_EXPORT="Snippets Export" COM_COMPONENTBUILDER_SNIPPETS_EXPORT_DESC="Allows the users in this group to export export snippets" COM_COMPONENTBUILDER_SNIPPETS_IMPORT="Snippets Import" @@ -1104,7 +1111,7 @@ COM_COMPONENTBUILDER_SNIPPET_SHARE_SNIPPETS_BUTTON_ACCESS_DESC="Allows the users COM_COMPONENTBUILDER_SNIPPET_TYPES_ACCESS="Snippet Types Access" COM_COMPONENTBUILDER_SNIPPET_TYPES_ACCESS_DESC="Allows the users in this group to access access snippet types" COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_USE="Snippet Types Batch Use" -COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch snippet types" +COM_COMPONENTBUILDER_SNIPPET_TYPES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch snippet types" COM_COMPONENTBUILDER_SNIPPET_TYPES_CREATE="Snippet Types Create" COM_COMPONENTBUILDER_SNIPPET_TYPES_CREATE_DESC="Allows the users in this group to create create snippet types" COM_COMPONENTBUILDER_SNIPPET_TYPES_DELETE="Snippet Types Delete" @@ -1116,11 +1123,11 @@ COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_OWN_DESC="Allows the users in this group COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_STATE="Snippet Types Edit State" COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_STATE_DESC="Allows the users in this group to update the state of the snippet type" COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_VERSION="Snippet Types Edit Version" -COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version snippet types" +COM_COMPONENTBUILDER_SNIPPET_TYPES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version snippet types" COM_COMPONENTBUILDER_TEMPLATES_ACCESS="Templates Access" COM_COMPONENTBUILDER_TEMPLATES_ACCESS_DESC="Allows the users in this group to access access templates" COM_COMPONENTBUILDER_TEMPLATES_BATCH_USE="Templates Batch Use" -COM_COMPONENTBUILDER_TEMPLATES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch templates" +COM_COMPONENTBUILDER_TEMPLATES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch templates" COM_COMPONENTBUILDER_TEMPLATES_CREATE="Templates Create" COM_COMPONENTBUILDER_TEMPLATES_CREATE_DESC="Allows the users in this group to create create templates" COM_COMPONENTBUILDER_TEMPLATES_DASHBOARD_ADD="Templates Dashboard Add" @@ -1136,7 +1143,7 @@ COM_COMPONENTBUILDER_TEMPLATES_EDIT_OWN_DESC="Allows the users in this group to COM_COMPONENTBUILDER_TEMPLATES_EDIT_STATE="Templates Edit State" COM_COMPONENTBUILDER_TEMPLATES_EDIT_STATE_DESC="Allows the users in this group to update the state of the template" COM_COMPONENTBUILDER_TEMPLATES_EDIT_VERSION="Templates Edit Version" -COM_COMPONENTBUILDER_TEMPLATES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version templates" +COM_COMPONENTBUILDER_TEMPLATES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version templates" COM_COMPONENTBUILDER_TEMPLATES_EXPORT="Templates Export" COM_COMPONENTBUILDER_TEMPLATES_EXPORT_DESC="Allows the users in this group to export export templates" COM_COMPONENTBUILDER_TEMPLATES_IMPORT="Templates Import" @@ -1150,7 +1157,7 @@ COM_COMPONENTBUILDER_USE_BATCH_DESC="Allows users in this group to use batch cop COM_COMPONENTBUILDER_VALIDATION_RULES_ACCESS="Validation Rules Access" COM_COMPONENTBUILDER_VALIDATION_RULES_ACCESS_DESC="Allows the users in this group to access access validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_USE="Validation Rules Batch Use" -COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_USE_DESC="Allows users in this group to use batch copy/update method of batch validation rules" +COM_COMPONENTBUILDER_VALIDATION_RULES_BATCH_USE_DESC="Allows the users in this group to use batch copy/update method of batch validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_CREATE="Validation Rules Create" COM_COMPONENTBUILDER_VALIDATION_RULES_CREATE_DESC="Allows the users in this group to create create validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_DASHBOARD_LIST="Validation Rules Dashboard List" @@ -1164,7 +1171,7 @@ COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_OWN_DESC="Allows the users in this gr COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_STATE="Validation Rules Edit State" COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_STATE_DESC="Allows the users in this group to update the state of the validation rule" COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_VERSION="Validation Rules Edit Version" -COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_VERSION_DESC="Allows users in this group to edit versions of version validation rules" +COM_COMPONENTBUILDER_VALIDATION_RULES_EDIT_VERSION_DESC="Allows the users in this group to edit versions of version validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_EXPORT="Validation Rules Export" COM_COMPONENTBUILDER_VALIDATION_RULES_EXPORT_DESC="Allows the users in this group to export export validation rules" COM_COMPONENTBUILDER_VALIDATION_RULES_IMPORT="Validation Rules Import" diff --git a/admin/layouts/field/database_right.php b/admin/layouts/field/database_right.php index d2af03303..644649025 100644 --- a/admin/layouts/field/database_right.php +++ b/admin/layouts/field/database_right.php @@ -29,6 +29,8 @@ $fields = $displayData->get($fields_tab_layout) ?: array( 'indexes', 'null_switch', 'store', + 'medium_encryption_note', + 'basic_encryption_note', 'note_whmcs_encryption', 'note_expert_field_save_mode', 'initiator_on_save_model', diff --git a/admin/layouts/fieldtype/database_defaults_right.php b/admin/layouts/fieldtype/database_defaults_right.php index ceb67b129..0f650d05d 100644 --- a/admin/layouts/fieldtype/database_defaults_right.php +++ b/admin/layouts/fieldtype/database_defaults_right.php @@ -29,6 +29,8 @@ $fields = $displayData->get($fields_tab_layout) ?: array( 'indexes', 'null_switch', 'store', + 'basic_encryption_note', + 'medium_encryption_note', 'note_whmcs_encryption' ); diff --git a/admin/layouts/jcbsupportmessage.php b/admin/layouts/jcbsupportmessage.php new file mode 100644 index 000000000..1aaa5a707 --- /dev/null +++ b/admin/layouts/jcbsupportmessage.php @@ -0,0 +1,116 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('JPATH_BASE') or die('Restricted access'); + +// Different support requests/appreciation +$support = [ + JText::_("COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDER_JCB_IS_A_CRUCIAL_TOOL_FOR_PHP_PROGRAMMERS_WHO_USE_JOOMLA_TO_EARN_A_LIVING_BY_MAKING_A_BFINANCIAL_DONATIONB_YOU_CAN_SUPPORT_THE_GROWTH_AND_CONTINUITY_OF_THIS_VITAL_RESOURCE_AND_ENSURE_ITS_RELEVANCE_FOR_YEARS_TO_COME_YOUR_CONTRIBUTION_NO_MATTER_HOW_BIG_OR_SMALL_WILL_BE_DEEPLY_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_THE_CONTINUED_SUPPORT_OF_INDIVIDUALS_LIKE_YOU_HAS_ALLOWED_JOOMLA_COMPONENT_BUILDER_JCB_TO_THRIVE_FOR_SEVEN_YEARS_SINCE_GOING_PUBLIC_YOUR_CONTRIBUTIONS_HAVE_BEEN_CRUCIAL_IN_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_THANK_YOU_FOR_YOUR_SUPPORT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY"), + JText::_("COM_COMPONENTBUILDER_SUPPORT_JOOMLA_COMPONENT_BUILDER_JCB_WITH_A_BFINANCIAL_DONATIONB_TO_SHOW_GRATITUDE_FOR_THE_TIME_AND_EFFORT_SAVED_IN_YOUR_DEVELOPMENT_PROCESS_YOUR_CONTRIBUTION_NO_MATTER_THE_SIZE_WILL_BE_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY_HELP_ENSURE_THE_GROWTH_AND_RELEVANCE_OF_THIS_ESSENTIAL_TOOL"), + JText::_("COM_COMPONENTBUILDER_INVEST_IN_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_BY_MAKING_A_BFINANCIAL_DONATIONB_SUPPORT_THE_NECESSARY_DEVELOPMENT_AND_MAINTENANCE_OF_THIS_OPENSOURCE_PROJECT_ENSURING_ITS_CONTINUED_GROWTH_AND_RELEVANCE_FOR_THE_COMMUNITY_YOUR_CONTRIBUTION_WILL_HELP_SECURE_THE_FUTURE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS"), + JText::_("COM_COMPONENTBUILDER_INVEST_IN_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_BY_MAKING_A_BFINANCIAL_CONTRIBUTIONB_NO_MATTER_HOW_SMALL_THE_CONTINUAL_SUPPORT_OF_ALL_THOSE_USING_THE_TOOL_WILL_BE_MORE_THAN_ENOUGH_TO_ENSURE_ITS_CONTINUED_GROWTH_AND_RELEVANCE_BY_INVESTING_IN_THIS_OPENSOURCE_PROJECT_YOU_ARE_SECURING_ITS_FUTURE_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS"), + JText::_("COM_COMPONENTBUILDER_WE_EXTEND_OUR_GRATITUDE_TO_ALL_THOSE_WHO_SUPPORT_JOOMLA_COMPONENT_BUILDER_JCB_WHETHER_AS_A_HOBBY_OR_AS_A_PART_OF_THEIR_BUSINESS_YOUR_CONTRIBUTIONS_WHETHER_FINANCIAL_OR_IN_THE_FORM_OF_ACTIVE_INVOLVEMENT_HAVE_HAD_A_SIGNIFICANT_IMPACT_ON_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_WE_HIGHLY_VALUE_THE_DEDICATION_OF_HOBBYISTS_AND_THE_COMMITMENT_OF_COMPANIES_WHO_SUPPORT_JCB_AS_THEY_HAVE_ALLOWED_THE_PROJECT_TO_CONTINUE_ITS_DEVELOPMENT_AND_MAINTENANCE_PROVIDING_VALUABLE_RESOURCES_FOR_THE_COMMUNITY_WE_ARE_GRATEFUL_FOR_YOUR_CONTRIBUTIONS_NO_MATTER_HOW_SMALL_AND_THANK_YOU_FOR_BEING_A_PART_OF_THE_POSITIVE_IMPACT_THAT_JCB_HAS_ON_THE_PHP_PROGRAMMING_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_WITHOUT_SUFFICIENT_SUPPORT_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_IS_IN_JEOPARDY_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS_IT_IS_CRUCIAL_TO_ENSURE_ITS_CONTINUED_DEVELOPMENT_AND_MAINTENANCE_BY_MAKING_A_BFINANCIAL_CONTRIBUTIONB_NO_MATTER_HOW_SMALL_YOU_ARE_HELPING_TO_SAFEGUARD_THE_FUTURE_OF_THIS_OPENSOURCE_PROJECT_NEGLECTING_TO_SUPPORT_JCB_COULD_RESULT_IN_ITS_DECLINE_AND_LOSS_AS_A_RESOURCE_FOR_THE_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_WE_EXTEND_OUR_HEARTFELT_APPRECIATION_TO_THOSE_WHO_HAVE_SUPPORTED_THE_JOOMLA_COMPONENT_BUILDER_JCB_PROJECT_OVER_THE_YEARS_YOUR_CONTRIBUTIONS_NO_MATTER_HOW_BIG_OR_SMALL_HAVE_BEEN_INSTRUMENTAL_IN_ENSURING_ITS_GROWTH_AND_RELEVANCE_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS_SEVEN_YEARS_AFTER_GOING_PUBLIC_JCB_IS_STILL_HERE_TODAY_BECAUSE_OF_THE_SUPPORT_OF_INDIVIDUALS_LIKE_YOU_WHO_BELIEVE_IN_THE_IMPORTANCE_OF_THIS_OPENSOURCE_PROJECT_YOUR_GENEROSITY_HAS_ALLOWED_THE_PROJECT_TO_CONTINUE_ITS_DEVELOPMENT_AND_MAINTENANCE_PROVIDING_VALUABLE_RESOURCES_FOR_THE_COMMUNITY_THANK_YOU_FOR_YOUR_UNWAVERING_SUPPORT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY"), + JText::_("COM_COMPONENTBUILDER_WE_EXTEND_OUR_SINCERE_APPRECIATION_TO_THE_COMPANIES_WHO_USE_JOOMLA_COMPONENT_BUILDER_JCB_AND_SUPPORT_THE_PROJECT_YOUR_CONTRIBUTIONS_WHETHER_FINANCIAL_OR_IN_THE_FORM_OF_ACTIVE_INVOLVEMENT_HAVE_BEEN_INSTRUMENTAL_IN_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_YOUR_SUPPORT_HAS_ALLOWED_JCB_TO_CONTINUE_ITS_DEVELOPMENT_AND_MAINTENANCE_PROVIDING_VALUABLE_RESOURCES_FOR_THE_COMMUNITY_THANK_YOU_FOR_YOUR_UNWAVERING_COMMITMENT_TO_THE_PROJECT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY") +]; + +// build the support message +$support_message = $support[random_int(0, 8)]; + +// the button titles +$titles = [ + JText::_("COM_COMPONENTBUILDER_JCB_ENABLES_PHP_DEVELOPMENT"), + JText::_("COM_COMPONENTBUILDER_JCB_SUPPORTS_OPENSOURCE"), + JText::_("COM_COMPONENTBUILDER_JCB_SAVES_TIME"), + JText::_("COM_COMPONENTBUILDER_JCB_IMPROVES_WORKFLOW"), + JText::_("COM_COMPONENTBUILDER_JCB_EMPOWERS_PHP_DEVELOPERS"), + JText::_("COM_COMPONENTBUILDER_JCB_STREAMLINES_DEVELOPMENT"), + JText::_("COM_COMPONENTBUILDER_JCB_PROMOTES_EFFICIENCY"), + JText::_("COM_COMPONENTBUILDER_JCB_ENHANCES_PRODUCTIVITY"), + JText::_("COM_COMPONENTBUILDER_JCB_INCREASES_REVENUE"), + JText::_("COM_COMPONENTBUILDER_JCB_REDUCES_DEVELOPMENT_COSTS"), + JText::_("COM_COMPONENTBUILDER_JCB_SUPPORTS_THE_PHP_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_JCB_IMPROVES_PHP_DEVELOPMENT"), + JText::_("COM_COMPONENTBUILDER_JCB_HELPS_GROW_BUSINESSES"), + JText::_("COM_COMPONENTBUILDER_JCB_SUPPORTS_PHP_INNOVATION"), + JText::_("COM_COMPONENTBUILDER_JCB_CONTRIBUTES_TO_OPENSOURCE"), + JText::_("COM_COMPONENTBUILDER_JCB_PROVIDES_A_BETTER_EXPERIENCE"), + JText::_("COM_COMPONENTBUILDER_JCB_OFFERS_MORE_FEATURES"), + JText::_("COM_COMPONENTBUILDER_JCB_INCREASES_DEVELOPMENT_SPEED"), + JText::_("COM_COMPONENTBUILDER_JCB_IMPROVES_USER_EXPERIENCE"), + JText::_("COM_COMPONENTBUILDER_JCB_INCREASES_USER_SATISFACTION"), + JText::_("COM_COMPONENTBUILDER_JCB_LOWERS_DEVELOPMENT_STRESS"), + JText::_("COM_COMPONENTBUILDER_JCB_PROMOTES_GOODWILL"), + JText::_("COM_COMPONENTBUILDER_JCB_OFFERS_A_STRONGER_SOLUTION"), + JText::_("COM_COMPONENTBUILDER_JCB_SUPPORTS_A_WORTHY_CAUSE"), + JText::_("COM_COMPONENTBUILDER_JCB_BUILDS_A_BETTER_FUTURE"), + JText::_("COM_COMPONENTBUILDER_JCB_FOSTERS_A_STRONG_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_JCB_IMPROVES_PHPS_REPUTATION"), + JText::_("COM_COMPONENTBUILDER_JCB_SUPPORTS_A_THRIVING_ECOSYSTEM"), + JText::_("COM_COMPONENTBUILDER_JCB_HELPS_PHP_THRIVE"), + JText::_("COM_COMPONENTBUILDER_JCB_INVESTS_IN_PHPS_SUCCESS") +]; + +// build the support button +$support_titles = $titles[random_int(0, 29)]; + +// the button names +$button_names = [ + JText::_("COM_COMPONENTBUILDER_DONATE_TO_JCB"), + JText::_("COM_COMPONENTBUILDER_SUPPORT_JCB_TODAY"), + JText::_("COM_COMPONENTBUILDER_CONTRIBUTE_TO_JCB"), + JText::_("COM_COMPONENTBUILDER_INVEST_IN_JCB"), + JText::_("COM_COMPONENTBUILDER_GIVE_TO_JCB"), + JText::_("COM_COMPONENTBUILDER_JOIN_JCBS_MISSION"), + JText::_("COM_COMPONENTBUILDER_HELP_JCB_GROW"), + JText::_("COM_COMPONENTBUILDER_BE_A_PART_OF_JCB"), + JText::_("COM_COMPONENTBUILDER_JCB_NEEDS_YOU"), + JText::_("COM_COMPONENTBUILDER_BECOME_A_CONTRIBUTOR"), + JText::_("COM_COMPONENTBUILDER_EMPOWER_JCB"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_IMPACT"), + JText::_("COM_COMPONENTBUILDER_JOIN_JCBS_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_MAKE_A_DIFFERENCE_WITH_JCB"), + JText::_("COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_MATTERS"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_THE_FUTURE"), + JText::_("COM_COMPONENTBUILDER_JOIN_JCBS_JOURNEY"), + JText::_("COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_COUNTS"), + JText::_("COM_COMPONENTBUILDER_EMPOWER_THE_FUTURE_WITH_JCB"), + JText::_("COM_COMPONENTBUILDER_JCB_YOUR_CONTRIBUTION_MATTERS"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_PROGRESS"), + JText::_("COM_COMPONENTBUILDER_JOIN_JCBS_VISION"), + JText::_("COM_COMPONENTBUILDER_ELEVATE_JCB_TODAY"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_CHANGE"), + JText::_("COM_COMPONENTBUILDER_JCB_YOUR_DONATION_MATTERS"), + JText::_("COM_COMPONENTBUILDER_JCB_BE_THE_CHANGE"), + JText::_("COM_COMPONENTBUILDER_JOIN_JCBS_SUCCESS"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_SUCCESS"), + JText::_("COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_IS_KEY"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_THE_COMMUNITY"), + JText::_("COM_COMPONENTBUILDER_JCB_YOUR_SUPPORT_MATTERS_MOST"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_YOUR_FUTURE"), + JText::_("COM_COMPONENTBUILDER_JCB_INVEST_IN_PROGRESS_TODAY") +]; + +// build the support button +$support_button = $button_names[random_int(0, 32)]; + +?> + +

+ +

+ + + +
diff --git a/admin/layouts/joomla_component/dynamic_integration_left.php b/admin/layouts/joomla_component/dynamic_integration_left.php index c35d75f98..f1b7da7e0 100644 --- a/admin/layouts/joomla_component/dynamic_integration_left.php +++ b/admin/layouts/joomla_component/dynamic_integration_left.php @@ -34,7 +34,13 @@ $fields = $displayData->get($fields_tab_layout) ?: array( 'note_update_server_note_other', 'update_server', 'add_sales_server', - 'sales_server' + 'sales_server', + 'add_backup_folder_path', + 'note_backup_folder_path', + 'backup_folder_path', + 'add_git_folder_path', + 'note_git_folder_path', + 'git_folder_path' ); $hiddenFields = $displayData->get('hidden_fields') ?: array(); diff --git a/admin/layouts/power/code_left.php b/admin/layouts/power/code_left.php index 098dc960b..85ed07e9f 100644 --- a/admin/layouts/power/code_left.php +++ b/admin/layouts/power/code_left.php @@ -29,10 +29,10 @@ $fields = $displayData->get($fields_tab_layout) ?: array( 'name', 'description', 'extends', - 'implements_custom', - 'implements', - 'namespace', 'extends_custom', + 'implements', + 'implements_custom', + 'namespace', 'add_head' ); diff --git a/admin/layouts/power/composer_fullwidth.php b/admin/layouts/power/composer_fullwidth.php new file mode 100644 index 000000000..be49af6e3 --- /dev/null +++ b/admin/layouts/power/composer_fullwidth.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// get the form +$form = $displayData->getForm(); + +// get the layout fields override method name (from layout path/ID) +$layout_path_array = explode('.', $this->getLayoutId()); +// Since we cannot pass the layout and tab names as parameters to the model method +// this name combination of tab and layout in the method name is the only work around +// seeing that JCB uses those two values (tab_name & layout_name) as the layout file name. +// example of layout name: details_left.php +// example of method name: getFields_details_left() +$fields_tab_layout = 'fields_' . $layout_path_array[1]; + +// get the fields +$fields = $displayData->get($fields_tab_layout) ?: array( + 'autoload_composer_note', + 'composer' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + +
+ + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + +
+ diff --git a/admin/layouts/power/licensing_fullwidth.php b/admin/layouts/power/licensing_fullwidth.php new file mode 100644 index 000000000..56e874540 --- /dev/null +++ b/admin/layouts/power/licensing_fullwidth.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// get the form +$form = $displayData->getForm(); + +// get the layout fields override method name (from layout path/ID) +$layout_path_array = explode('.', $this->getLayoutId()); +// Since we cannot pass the layout and tab names as parameters to the model method +// this name combination of tab and layout in the method name is the only work around +// seeing that JCB uses those two values (tab_name & layout_name) as the layout file name. +// example of layout name: details_left.php +// example of method name: getFields_details_left() +$fields_tab_layout = 'fields_' . $layout_path_array[1]; + +// get the fields +$fields = $displayData->get($fields_tab_layout) ?: array( + 'add_licensing_template', + 'licensing_template' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + +
+ + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + +
+ diff --git a/admin/layouts/power/super_power_left.php b/admin/layouts/power/super_power_left.php new file mode 100644 index 000000000..8b1e5cc6c --- /dev/null +++ b/admin/layouts/power/super_power_left.php @@ -0,0 +1,43 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// get the form +$form = $displayData->getForm(); + +// get the layout fields override method name (from layout path/ID) +$layout_path_array = explode('.', $this->getLayoutId()); +// Since we cannot pass the layout and tab names as parameters to the model method +// this name combination of tab and layout in the method name is the only work around +// seeing that JCB uses those two values (tab_name & layout_name) as the layout file name. +// example of layout name: details_left.php +// example of method name: getFields_details_left() +$fields_tab_layout = 'fields_' . $layout_path_array[1]; + +// get the fields +$fields = $displayData->get($fields_tab_layout) ?: array( + 'approved', + 'approved_paths' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + + diff --git a/admin/layouts/power/super_power_right.php b/admin/layouts/power/super_power_right.php new file mode 100644 index 000000000..e0dac78ab --- /dev/null +++ b/admin/layouts/power/super_power_right.php @@ -0,0 +1,42 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// get the form +$form = $displayData->getForm(); + +// get the layout fields override method name (from layout path/ID) +$layout_path_array = explode('.', $this->getLayoutId()); +// Since we cannot pass the layout and tab names as parameters to the model method +// this name combination of tab and layout in the method name is the only work around +// seeing that JCB uses those two values (tab_name & layout_name) as the layout file name. +// example of layout name: details_left.php +// example of method name: getFields_details_left() +$fields_tab_layout = 'fields_' . $layout_path_array[1]; + +// get the fields +$fields = $displayData->get($fields_tab_layout) ?: array( + 'note_approved_paths' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + + diff --git a/admin/layouts/rows.php b/admin/layouts/rows.php new file mode 100644 index 000000000..5379aea33 --- /dev/null +++ b/admin/layouts/rows.php @@ -0,0 +1,43 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('JPATH_BASE') or die('Restricted access'); + +$headers = $displayData['headers']; +$items = $displayData['items']; + +?> + + $values): ?> + + + + + + + + + + +    + + + + + + + +    + + + + diff --git a/admin/layouts/server/linked_components_fullwidth.php b/admin/layouts/server/linked_components_fullwidth.php index b34bfea22..403302ea3 100644 --- a/admin/layouts/server/linked_components_fullwidth.php +++ b/admin/layouts/server/linked_components_fullwidth.php @@ -11,6 +11,8 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; // set the defaults $items = $displayData->vymlinked_components; @@ -90,7 +92,7 @@ else $this->return_here = urlencode(base64_encode((string) JUri::getInstance())); } // setup the buttons - if (!isset($_buttons) || !ComponentbuilderHelper::checkArray($_buttons)) + if (!isset($_buttons) || !ArrayHelper::check($_buttons)) { $_buttons = array(); $_buttons[0] = array( @@ -201,16 +203,16 @@ else
escape($item->companyname); ?>
- author)) : ?> + author)) : ?> escape($item->author); ?>
- email) && ComponentbuilderHelper::checkString($item->author)) : ?> + email) && StringHelper::check($item->author)) : ?> escape($item->email); ?>
- website) && ComponentbuilderHelper::checkString($item->author)) : ?> + website) && StringHelper::check($item->author)) : ?> escape($item->website); ?> diff --git a/admin/layouts/table.php b/admin/layouts/table.php new file mode 100644 index 000000000..b526bfa0a --- /dev/null +++ b/admin/layouts/table.php @@ -0,0 +1,74 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('JPATH_BASE') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; + +$table_id = (isset($displayData['id'])) ? $displayData['id'] : StringHelper::random(7); +$name = (isset($displayData['name'])) ? $displayData['name'] : false; +$table_class = (isset($displayData['table_class'])) ? $displayData['table_class'] : 'uk-table'; +$headers = (isset($displayData['headers'])) ? $displayData['headers'] : [JText::_('COM_COMPONENTBUILDER_NO'), JText::_('COM_COMPONENTBUILDER_HEADERS'), JText::_('COM_COMPONENTBUILDER_FOUND')]; +$items = (isset($displayData['items'])) ? $displayData['items'] : 6; + +?> +
+ + + + + + + + + + $header): ?> + + + + + + + + + + + + + + + + + + + $headers, 'items' => $items]); ?> + +
+
+ + + diff --git a/admin/models/admin_custom_tabs.php b/admin/models/admin_custom_tabs.php index 63b715029..76dd3d7fc 100644 --- a/admin/models/admin_custom_tabs.php +++ b/admin/models/admin_custom_tabs.php @@ -284,7 +284,7 @@ class ComponentbuilderModelAdmin_custom_tabs extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('admin_custom_tabs.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/admin_fields.php b/admin/models/admin_fields.php index 43284a4b2..121d0718b 100644 --- a/admin/models/admin_fields.php +++ b/admin/models/admin_fields.php @@ -305,7 +305,7 @@ class ComponentbuilderModelAdmin_fields extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('admin_fields.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/admin_fields_conditions.php b/admin/models/admin_fields_conditions.php index bee9651dd..5d748acca 100644 --- a/admin/models/admin_fields_conditions.php +++ b/admin/models/admin_fields_conditions.php @@ -305,7 +305,7 @@ class ComponentbuilderModelAdmin_fields_conditions extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('admin_fields_conditions.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/admin_fields_relations.php b/admin/models/admin_fields_relations.php index 492168f4d..022006cca 100644 --- a/admin/models/admin_fields_relations.php +++ b/admin/models/admin_fields_relations.php @@ -16,6 +16,8 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; /** * Componentbuilder Admin_fields_relations Admin Model @@ -101,7 +103,7 @@ class ComponentbuilderModelAdmin_fields_relations extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'admin_fields_relations__'.$id); ComponentbuilderHelper::set('admin_fields_relations__'.$id, $this->vastDevMod); // set a return value if found @@ -109,7 +111,7 @@ class ComponentbuilderModelAdmin_fields_relations extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -175,7 +177,7 @@ class ComponentbuilderModelAdmin_fields_relations extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'admin_fields_relations__'.$id); ComponentbuilderHelper::set('admin_fields_relations__'.$id, $this->vastDevMod); // set a return value if found @@ -183,7 +185,7 @@ class ComponentbuilderModelAdmin_fields_relations extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -367,7 +369,7 @@ class ComponentbuilderModelAdmin_fields_relations extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('admin_fields_relations.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/admin_view.php b/admin/models/admin_view.php index fcd4b6339..1d543331d 100644 --- a/admin/models/admin_view.php +++ b/admin/models/admin_view.php @@ -16,6 +16,11 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Admin_view Admin Model @@ -249,7 +254,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'admin_view__'.$id); ComponentbuilderHelper::set('admin_view__'.$id, $this->vastDevMod); // set a return value if found @@ -257,7 +262,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -599,7 +604,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'admin_view__'.$id); ComponentbuilderHelper::set('admin_view__'.$id, $this->vastDevMod); // set a return value if found @@ -607,7 +612,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -785,7 +790,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -800,7 +805,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } return $form; @@ -864,7 +869,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('admin_view.edit.state', 'com_componentbuilder'); } @@ -1030,7 +1035,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel } // we must also delete the linked tables found - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { $_tablesArray = array( 'admin_fields', @@ -1072,7 +1077,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel } // we must also update all linked tables - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { $_tablesArray = array( 'admin_fields', @@ -1482,7 +1487,7 @@ class ComponentbuilderModelAdmin_view extends AdminModel } // if system name is empty create a system name from the name_single - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name_single']; } @@ -1491,15 +1496,15 @@ class ComponentbuilderModelAdmin_view extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('admin_view', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('admin_view', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "admin_view", $data['id'])) + while (!GuidHelper::valid($data['guid'], "admin_view", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the addpermissions items to data. if (isset($data['addpermissions']) && is_array($data['addpermissions'])) diff --git a/admin/models/admin_views.php b/admin/models/admin_views.php index 6c5fee144..3b306c9a7 100644 --- a/admin/models/admin_views.php +++ b/admin/models/admin_views.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; +use VDM\Joomla\Utilities\FormHelper as JCBFormHelper; /** * Admin_views List Model @@ -70,7 +72,7 @@ class ComponentbuilderModelAdmin_views extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND') . ' -' ); // check if we have joomla components - if (($joomla_components = ComponentbuilderHelper::getByTypeTheIdsSystemNames('joomla_component')) !== false) + if (($joomla_components = JCBFilterHelper::names('joomla_component')) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_COMPONENT') . ' -' @@ -79,7 +81,7 @@ class ComponentbuilderModelAdmin_views extends ListModel $options = $options + $joomla_components; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'joomla_component', 'filter', @@ -88,7 +90,8 @@ class ComponentbuilderModelAdmin_views extends ListModel array_push($this->filter_fields, 'joomla_component'); return $form; - } + } + /** * Method to auto-populate the model state. @@ -354,7 +357,7 @@ class ComponentbuilderModelAdmin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -589,7 +592,7 @@ class ComponentbuilderModelAdmin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/models/ajax.php b/admin/models/ajax.php index ffa98741d..97c2a5f34 100644 --- a/admin/models/ajax.php +++ b/admin/models/ajax.php @@ -14,8 +14,18 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Gitea\Factory as GiteaFactory; +use VDM\Joomla\Componentbuilder\Package\Factory as PackageFactory; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; use Joomla\Registry\Registry; -use VDM\Gitea\Gitea; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\Base64Helper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\FieldHelper; /** * Componentbuilder Ajax List Model @@ -33,54 +43,6 @@ class ComponentbuilderModelAjax extends ListModel } // Used in joomla_component - - /** - * Check and if a vdm notice is new (per/user) - **/ - public function isNew($notice) - { - // first get the file path - $path_filename = ComponentbuilderHelper::getFilePath('path', 'usernotice', 'md', JFactory::getUser()->username, JPATH_COMPONENT_ADMINISTRATOR); - // check if the file is set - if (($content = @file_get_contents($path_filename)) !== FALSE) - { - if ($notice == $content) - { - return false; - } - } - return true; - } - - /** - * set That a notice has been read (per/user) - **/ - public function isRead($notice) - { - // first get the file path - $path_filename = ComponentbuilderHelper::getFilePath('path', 'usernotice', 'md', JFactory::getUser()->username, JPATH_COMPONENT_ADMINISTRATOR); - // set as read if not already set - if (($content = @file_get_contents($path_filename)) !== FALSE) - { - if ($notice == $content) - { - return true; - } - } - return $this->saveFile($notice,$path_filename); - } - - protected function saveFile($data,$path_filename) - { - if (ComponentbuilderHelper::checkString($data)) - { - $fp = fopen($path_filename, 'w'); - fwrite($fp, $data); - fclose($fp); - return true; - } - return false; - } /** * get the crowdin project details (html) **/ @@ -89,7 +51,7 @@ class ComponentbuilderModelAjax extends ListModel // set the url $url = "https://api.crowdin.com/api/project/$identifier/info?key=$key&json"; // get the details - if (($details = ComponentbuilderHelper::getFileContents($url, false)) !== false && ComponentbuilderHelper::checkJson($details)) + if (($details = FileHelper::getContent($url, false)) !== false && JsonHelper::check($details)) { $details = json_decode($details, true); // check if there is an error @@ -101,9 +63,9 @@ class ComponentbuilderModelAjax extends ListModel if (isset($details['details'])) { $html = '
'; - $html .= '

' . JText::_('COM_COMPONENTBUILDER_COMPONENT_SUCCESSFULLY_LINKED') . '

'; + $html .= '

' . Text::_('COM_COMPONENTBUILDER_COMPONENT_SUCCESSFULLY_LINKED') . '

'; $html .= '

' . $details['details']['name'] . '

'; - if (ComponentbuilderHelper::checkString($details['details']['description'])) + if (StringHelper::check($details['details']['description'])) { $html .= '

'; $html .= $details['details']['description']; @@ -127,7 +89,7 @@ class ComponentbuilderModelAjax extends ListModel $html .= ''; $html .= ''; $html .= '

'; - return array('html' => $html); + return ['html' => $html]; } } return false; @@ -152,7 +114,7 @@ class ComponentbuilderModelAjax extends ListModel $db->execute(); if ($db->loadRowList()) { - return array( 'html' => $this->componentDetailsDisplay($db->loadObject())); + return ['html' => $this->componentDetailsDisplay($db->loadObject())]; } return false; } @@ -165,47 +127,33 @@ class ComponentbuilderModelAjax extends ListModel // convert URL $url = base64_decode($package); $url = str_replace('.zip', '.info', $url); + // check if url exist - if ($info = ComponentbuilderHelper::getFileContents($url, false)) + if ($info = FileHelper::getContent($url, false)) { - // Get the encryption object. - $db = 'COM_COMPONENTBUILDER_VJRZDESSMHBTRWFIFTYTWVZEROAESFLVVXJTMTHREEJTWOIXM'; - $password = base64_decode(JText::sprintf($db, 'QzdmV', '9kQ')); - // we first use the new encryption - // load phpseclib - $opened = false; - if(ComponentbuilderHelper::crypt('AES', 'CBC') instanceof \phpseclib\Crypt\Rijndael) - { - // load the system password - ComponentbuilderHelper::crypt('AES', 'CBC')->setPassword($password, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); - // open the info block - $_info = ComponentbuilderHelper::crypt('AES', 'CBC')->decrypt(base64_decode($info)); - // check if we had success - if ($_info !== false) - { - $opened = true; - } - } + $_info = PackageFactory::_('Crypt')->decrypt($info, 'local.legacy'); + // check if we had success - if (!$opened && class_exists('FOFEncryptAes')) + if (!JsonHelper::check($_info)) { - $opener = new FOFEncryptAes($password, 128); - $_info = $opener->decryptString($info); - // check if we had success - if ($_info !== false) - { - $opened = true; - $_info = rtrim($_info, "\0"); - } + $_info = PackageFactory::_('Crypt')->decrypt($info, 'local.fof'); } + // check if we have json - if ($opened && ComponentbuilderHelper::checkJson($_info)) + if (JsonHelper::check($_info)) { $info = json_decode($_info, true); - return array('owner' => ComponentbuilderHelper::getPackageOwnerDetailsDisplay($info, true), 'packages' => ComponentbuilderHelper::getPackageComponentsDetailsDisplay($info)); + + return [ + 'owner' => PackageFactory::_('Display.Details')->owner($info, true), + 'packages' => PackageFactory::_('Display.Details')->components($info) + ]; } } - return array('error' => JText::_('COM_COMPONENTBUILDER_JCB_PACKAGE_INFO_PATH_DOES_NOT_WORK_WE_ADVICE_YOU_BNOT_TO_CONTINUEB_WITH_THE_IMPORT_OF_THE_SELECTED_PACKAGE')); + + return [ + 'error' => Text::_('COM_COMPONENTBUILDER_JCB_PACKAGE_INFO_PATH_DOES_NOT_WORK_WE_ADVICE_YOU_BNOT_TO_CONTINUEB_WITH_THE_IMPORT_OF_THE_SELECTED_PACKAGE') + ]; } /** @@ -214,29 +162,29 @@ class ComponentbuilderModelAjax extends ListModel protected function componentDetailsDisplay($object) { // set some vars - $image = (ComponentbuilderHelper::checkString($object->image)) ? 'Joomla Component Image': ''; - $desc = (ComponentbuilderHelper::checkString($object->description)) ? $object->description : $object->short_description; - $placeholder = ($object->add_placeholders == 1) ? ' ' . JText::_('COM_COMPONENTBUILDER_YES') . ' ' : ' ' .JText::_('COM_COMPONENTBUILDER_NO') . ' ' ; - $debug = ($object->debug_linenr == 1) ? ' ' .JText::_('COM_COMPONENTBUILDER_YES') . '' : ' ' .JText::_('COM_COMPONENTBUILDER_NO') . ' ' ; + $image = (StringHelper::check($object->image)) ? 'Joomla Component Image': ''; + $desc = (StringHelper::check($object->description)) ? $object->description : $object->short_description; + $placeholder = ($object->add_placeholders == 1) ? ' ' . Text::_('COM_COMPONENTBUILDER_YES') . ' ' : ' ' .Text::_('COM_COMPONENTBUILDER_NO') . ' ' ; + $debug = ($object->debug_linenr == 1) ? ' ' .Text::_('COM_COMPONENTBUILDER_YES') . '' : ' ' .Text::_('COM_COMPONENTBUILDER_NO') . ' ' ; $html = array(); $html[] = '

' . $object->name . ' (v' . $object->component_version . ')

'; $html[] = '

' . $desc . $image . '

'; $html[] = '
    '; - $html[] = '
  • ' . JText::_('COM_COMPONENTBUILDER_COMPANY') . ': ' . $object->companyname . '
  • '; - $html[] = '
  • ' . JText::_('COM_COMPONENTBUILDER_AUTHOR') . ': ' . $object->author . '
  • '; - $html[] = '
  • ' . JText::_('COM_COMPONENTBUILDER_EMAIL') . ': ' . $object->email . '
  • '; - $html[] = '
  • ' . JText::_('COM_COMPONENTBUILDER_WEBSITE') . ': ' . $object->website . '
  • '; + $html[] = '
  • ' . Text::_('COM_COMPONENTBUILDER_COMPANY') . ': ' . $object->companyname . '
  • '; + $html[] = '
  • ' . Text::_('COM_COMPONENTBUILDER_AUTHOR') . ': ' . $object->author . '
  • '; + $html[] = '
  • ' . Text::_('COM_COMPONENTBUILDER_EMAIL') . ': ' . $object->email . '
  • '; + $html[] = '
  • ' . Text::_('COM_COMPONENTBUILDER_WEBSITE') . ': ' . $object->website . '
  • '; $html[] = '
'; - $html[] = '

' . JText::_('COM_COMPONENTBUILDER_COMPONENT_GLOBAL_SETTINGS') . '

'; + $html[] = '

' . Text::_('COM_COMPONENTBUILDER_COMPONENT_GLOBAL_SETTINGS') . '

'; $html[] = '

'; - $html[] = JText::_('COM_COMPONENTBUILDER_ADD_CUSTOM_CODE_PLACEHOLDERS') . '
' . $placeholder . '
'; - $html[] = JText::_('COM_COMPONENTBUILDER_DEBUG_LINE_NUMBERS') . '
' . $debug ; + $html[] = Text::_('COM_COMPONENTBUILDER_ADD_CUSTOM_CODE_PLACEHOLDERS') . '
' . $placeholder . '
'; + $html[] = Text::_('COM_COMPONENTBUILDER_DEBUG_LINE_NUMBERS') . '
' . $debug ; $html[] = '

'; - $html[] = '

' . JText::_('COM_COMPONENTBUILDER_LICENSE') . '

'; + $html[] = '

' . Text::_('COM_COMPONENTBUILDER_LICENSE') . '

'; $html[] = '

' . $object->license . '

'; - $html[] = '

' . JText::_('COM_COMPONENTBUILDER_COPYRIGHT') . '

'; + $html[] = '

' . Text::_('COM_COMPONENTBUILDER_COPYRIGHT') . '

'; $html[] = '

' . $object->copyright . '

'; - $html[] = ' ' . JText::_('COM_COMPONENTBUILDER_EDIT') . ' ' .$object->system_name . '

'; + $html[] = ' ' . Text::_('COM_COMPONENTBUILDER_EDIT') . ' ' .$object->system_name . '

'; // now return the diplay return implode("\n", $html); } @@ -246,7 +194,7 @@ class ComponentbuilderModelAjax extends ListModel **/ public function getCronPath($type) { - $result = array('error' => '' . JText::_('COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_SINCE_INCORRECT_TYPE_REQUESTED') . ''); + $result = array('error' => '' . Text::_('COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_SINCE_INCORRECT_TYPE_REQUESTED') . ''); if ('backup' === $type) { $result['error'] = '' . JText::sprintf('COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_FOR_S', $type) . ''; @@ -280,78 +228,79 @@ class ComponentbuilderModelAjax extends ListModel { return function_exists('curl_version'); } - - public function getWiki($name = 'Home') + + /** + * Check and if a notice is new (per/user) + * + * @param string|null $notice The current notice + * + * @return bool true if is new + * @since 2.0.0 + */ + public function isNew(?string $notice): bool { - // get the token if set - $token = JComponentHelper::getParams('com_componentbuilder')->get('gitea_token', false); + // first get the file path + $path_filename = FileHelper::getPath('path', 'usernotice', 'md', JFactory::getUser()->username, JPATH_COMPONENT_ADMINISTRATOR); - // setup a registry - $options = new Registry; - - // only add if token is set - if ($token) + // check if the file is set + if (($content = FileHelper::getContent($path_filename, FALSE)) !== FALSE) { - $options->set('access.token', $token); + if ($notice == $content) + { + return false; + } } - - try - { - // get gitea object - $gitea = new Gitea($options); - - // get the gitea wiki page TODO: we hard coded the page name - $page = $gitea->repo->wiki->getHtml('joomla', 'Component-Builder', 'Home'); - } - catch (DomainException $e) - { - return $this->getTokenForWiki($e->getMessage()); - } - catch (InvalidArgumentException $e) - { - return $this->getTokenForWiki($e->getMessage()); - } - catch (Exception $e) - { - return $this->getTokenForWiki($e->getMessage()); - } - - // get the html - if (isset($page)) - { - return ['page' => $page]; - } - - return $this->getTokenForWiki(); + return true; } - protected function getTokenForWiki($message = null) + /** + * Check if a notice has been read (per/user) + * + * @param string|null $notice The current notice + * + * @return bool true if is read + * @since 2.0.0 + */ + public function isRead(?string $notice): bool { - if ($message) + // first get the file path + $path_filename = FileHelper::getPath('path', 'usernotice', 'md', JFactory::getUser()->username, JPATH_COMPONENT_ADMINISTRATOR); + + // set as read if not already set + if (($content = FileHelper::getContent($path_filename, FALSE)) !== FALSE) { - return ['error' => $message]; + if ($notice == $content) + { + return true; + } } - return ['error' => JText::_('COM_COMPONENTBUILDER_THE_WIKI_CAN_ONLY_BE_LOADED_WHEN_YOUR_JCB_SYSTEM_HAS_INTERNET_CONNECTION')]; + return FileHelper::write($path_filename, $notice); } - + + /** + * get Current Version + * + * @param string|null $message The error messages if any. + * + * @return array The array of the notice or error message + * @since 2.3.0 + */ public function getVersion($version = null) { // get the token if set - $token = JComponentHelper::getParams('com_componentbuilder')->get('gitea_token', false); + $token = $this->app_params->get('gitea_token'); + // only add if token is set if ($token) { - // setup a registry - $options = new Registry; - $options->set('access.token', $token); - // get the gitea http try { - // get gitea object - $gitea = new Gitea($options); - // get a list of all the repos tags - $tags = $gitea->repo->getListTags('joomla', 'Component-Builder'); + // load the API details + GiteaFactory::_('Gitea.Repository.Tags')->load_('https://git.vdm.dev', $token); + + // get the repository tags + $tags = GiteaFactory::_('Gitea.Repository.Tags')->list('joomla', 'Component-Builder'); } catch (DomainException $e) { @@ -376,7 +325,7 @@ class ComponentbuilderModelAjax extends ListModel // now check if this version is out dated if ($current_version === $local_version) { - return ['notice' => '' . JText::_('COM_COMPONENTBUILDER_UP_TO_DATE') . '']; + return ['notice' => '' . Text::_('COM_COMPONENTBUILDER_UP_TO_DATE') . '']; } else { @@ -387,15 +336,15 @@ class ComponentbuilderModelAjax extends ListModel ($local_array[0] == $current_array[0] && $local_array[1] > $current_array[1]) || ($local_array[0] == $current_array[0] && $local_array[1] == $current_array[1] && $local_array[2] > $current_array[2])) { - return ['notice' => '' . JText::_('COM_COMPONENTBUILDER_BETA_RELEASE') . '']; + return ['notice' => '' . Text::_('COM_COMPONENTBUILDER_BETA_RELEASE') . '']; } else { // download link of the latest version $download = "https://git.vdm.dev/api/v1/repos/joomla/Component-Builder/archive/" . $tags[0]->name . ".zip?access_token=" . $token; - return ['notice' => '' . JText::_('COM_COMPONENTBUILDER_OUT_OF_DATE') . '! ' . JText::_('COM_COMPONENTBUILDER_DOWNLOAD_UPDATE') . '!']; + return ['notice' => '' . Text::_('COM_COMPONENTBUILDER_OUT_OF_DATE') . '! ' . Text::_('COM_COMPONENTBUILDER_DOWNLOAD_UPDATE') . '!']; } } } @@ -403,11 +352,20 @@ class ComponentbuilderModelAjax extends ListModel return $this->getTokenForVersion(); } - - protected function getTokenForVersion($message = null) + + /** + * Instructions to get Token for version + * + * @param string|null $message The error messages if any. + * + * @return array The array of the error message + * @since 2.3.0 + */ + protected function getTokenForVersion(?string $message = null): array { // the URL $url = 'https://git.vdm.dev/user/settings/applications'; + // create link $a = ''; @@ -415,19 +373,82 @@ class ComponentbuilderModelAjax extends ListModel if ($message) { - return ['error' => $a . $message . $a_ . JText::_('COM_COMPONENTBUILDER_GET_TOKEN') . $_a]; + return ['error' => $a . $message . $a_ . Text::_('COM_COMPONENTBUILDER_GET_TOKEN') . $_a]; } - return ['error' => $a . JText::_('COM_COMPONENTBUILDER_GET_TOKEN_FROM_VDM_TO_GET_UPDATE_NOTICE_AND_ADD_IT_TO_YOUR_GLOBAL_OPTIONS') . $a_ . JText::_('COM_COMPONENTBUILDER_GET_TOKEN') . $_a]; + return ['error' => $a . Text::_('COM_COMPONENTBUILDER_GET_TOKEN_FROM_VDM_TO_GET_UPDATE_NOTICE_AND_ADD_IT_TO_YOUR_GLOBAL_OPTIONS') . $a_ . Text::_('COM_COMPONENTBUILDER_GET_TOKEN') . $_a]; } + /** + * get Wiki Page + * + * @param string|null $message The error messages if any. + * + * @return array The array of the page or error message + * @since 2.3.0 + */ + public function getWiki(string $name = 'Home'): array + { + try + { + // get the token if set + $token = $this->app_params->get('gitea_token'); + + // load the API details + GiteaFactory::_('Gitea.Repository.Wiki')->load_('https://git.vdm.dev', $token); + + // get the gitea wiki page im markdown + $wiki = GiteaFactory::_('Gitea.Repository.Wiki')->get('joomla', 'Component-Builder', $name); + + // now render the page in HTML + $page = GiteaFactory::_('Gitea.Miscellaneous.Markdown')->render($wiki->content, true); + } + catch (DomainException $e) + { + return $this->getTokenForWiki($e->getMessage()); + } + catch (InvalidArgumentException $e) + { + return $this->getTokenForWiki($e->getMessage()); + } + catch (Exception $e) + { + return $this->getTokenForWiki($e->getMessage()); + } + + // get the html + if (isset($page)) + { + return ['page' => $page]; + } + + return $this->getTokenForWiki(); + } + + /** + * Instructions to get Token for wiki + * + * @param string|null $message The error messages if any. + * + * @return array The array of the error message + * @since 2.3.0 + */ + protected function getTokenForWiki(?string $message = null): array + { + if ($message) + { + return ['error' => $message]; + } + + return ['error' => Text::_('COM_COMPONENTBUILDER_THE_WIKI_CAN_ONLY_BE_LOADED_WHEN_YOUR_JOOMLA_COMPONENT_BUILDER_SYSTEM_HAS_INTERNET_CONNECTION')]; + } // Used in joomla_module public function getModuleCode($data) { // reset the return array $code = array(); - if (ComponentbuilderHelper::checkJson($data)) + if (JsonHelper::check($data)) { // convert the data to object $data = json_decode($data); @@ -443,7 +464,7 @@ class ComponentbuilderModelAjax extends ListModel $code['class']['merge_target'] = 'prepend'; } // get data - if (isset($data->get) && ComponentbuilderHelper::checkArray($data->get)) + if (isset($data->get) && UtilitiesArrayHelper::check($data->get)) { $code['get'] = array(); // add the code @@ -454,7 +475,7 @@ class ComponentbuilderModelAjax extends ListModel $code['get']['merge_target'] = 'prepend'; } // get libraries - if (isset($data->lib) && ComponentbuilderHelper::checkArray($data->lib)) + if (isset($data->lib) && UtilitiesArrayHelper::check($data->lib)) { $code['lib'] = array(); // add the code @@ -511,7 +532,7 @@ class ComponentbuilderModelAjax extends ListModel public function getClassHeaderCode($id, $type) { - if ('extends' === $type && ($head = ComponentbuilderHelper::getVar('class_' . $type, $id, 'id', 'head')) !== false && ComponentbuilderHelper::checkString($head)) + if ('extends' === $type && ($head = ComponentbuilderHelper::getVar('class_' . $type, $id, 'id', 'head')) !== false && StringHelper::check($head)) { return base64_decode($head); } @@ -556,10 +577,10 @@ class ComponentbuilderModelAjax extends ListModel if ($fields = ComponentbuilderHelper::getVar('admin_fields', $values['a_id'], 'admin_view', 'addfields')) { // open the fields - if (ComponentbuilderHelper::checkJson($fields)) + if (JsonHelper::check($fields)) { $fields = json_decode($fields, true); - if (ComponentbuilderHelper::checkArray($fields)) + if (UtilitiesArrayHelper::check($fields)) { foreach($fields as $field) { @@ -585,10 +606,10 @@ class ComponentbuilderModelAjax extends ListModel if ($fields = ComponentbuilderHelper::getVar('admin_fields', $values['a_id'], 'admin_view', 'addfields')) { // open the fields - if (ComponentbuilderHelper::checkJson($fields)) + if (JsonHelper::check($fields)) { $fields = json_decode($fields, true); - if (ComponentbuilderHelper::checkArray($fields)) + if (UtilitiesArrayHelper::check($fields)) { foreach($fields as $field) { @@ -730,7 +751,7 @@ class ComponentbuilderModelAjax extends ListModel return $language[$keys[1]]; } } - return ComponentbuilderHelper::safeString($keys[1], 'Ww'); + return StringHelper::safe($keys[1], 'Ww'); } protected $ref; @@ -785,7 +806,7 @@ class ComponentbuilderModelAjax extends ListModel protected function checkRepeatableConversion($type, &$fieldsData, $fieldsArrayType, $id, $linked_id_name) { - if (ComponentbuilderHelper::checkJson($fieldsData) && isset($this->conversionCheck[$fieldsArrayType])) + if (JsonHelper::check($fieldsData) && isset($this->conversionCheck[$fieldsArrayType])) { $fieldsData = json_decode($fieldsData, true); if (isset($fieldsData[$this->conversionCheck[$fieldsArrayType]])) @@ -821,12 +842,12 @@ class ComponentbuilderModelAjax extends ListModel protected function setPermissions($header, $values) { // check if value is array - if (!ComponentbuilderHelper::checkArray($values)) + if (!UtilitiesArrayHelper::check($values)) { $values = array($values); } // check if value is array - if (ComponentbuilderHelper::checkArray($values)) + if (UtilitiesArrayHelper::check($values)) { // Editing, Access, View $bucket = array(); @@ -846,7 +867,7 @@ class ComponentbuilderModelAjax extends ListModel } } // check if value is array - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { return implode(', ', $bucket); } @@ -887,7 +908,7 @@ class ComponentbuilderModelAjax extends ListModel protected function setIcoMoon($header, $value) { - if (ComponentbuilderHelper::checkString($value)) + if (StringHelper::check($value)) { return ''; } @@ -954,7 +975,7 @@ class ComponentbuilderModelAjax extends ListModel { return JText::_('COM_COMPONENTBUILDER_PUBLISHING'); } - if (!ComponentbuilderHelper::checkArray($this->tabNames)) + if (!UtilitiesArrayHelper::check($this->tabNames)) { // get the view name & id $values = $this->getViewID(); @@ -963,12 +984,12 @@ class ComponentbuilderModelAjax extends ListModel if ($tabs = ComponentbuilderHelper::getVar('admin_view', $values['a_id'], 'id', 'addtabs')) { $tabs = json_decode($tabs, true); - if (ComponentbuilderHelper::checkArray($tabs)) + if (UtilitiesArrayHelper::check($tabs)) { $nr = 1; foreach ($tabs as $tab) { - if (ComponentbuilderHelper::checkArray($tab) && isset($tab['name'])) + if (UtilitiesArrayHelper::check($tab) && isset($tab['name'])) { $this->tabNames[$nr] = $tab['name']; $nr++; @@ -979,7 +1000,7 @@ class ComponentbuilderModelAjax extends ListModel } } // has it been set - if (ComponentbuilderHelper::checkArray($this->tabNames) && isset($this->tabNames[$value])) + if (UtilitiesArrayHelper::check($this->tabNames) && isset($this->tabNames[$value])) { return $this->tabNames[$value]; } @@ -1119,7 +1140,7 @@ class ComponentbuilderModelAjax extends ListModel // load the values form params $xml = json_decode($result->xml); - $xmlOptions = ComponentbuilderHelper::getBetween($xml,'option="','"'); + $xmlOptions = GetHelper::between($xml,'option="','"'); $optionSet = ''; if (strpos($xmlOptions,',') !== false) @@ -1129,7 +1150,7 @@ class ComponentbuilderModelAjax extends ListModel foreach ($options as $option) { // return both value and text - if (ComponentbuilderHelper::checkString($optionSet)) + if (StringHelper::check($optionSet)) { // no add to option set $optionSet .= "\n".$option; @@ -1144,7 +1165,7 @@ class ComponentbuilderModelAjax extends ListModel else { // return both value and text - if (ComponentbuilderHelper::checkString($optionSet)) + if (StringHelper::check($optionSet)) { // no add to option set $optionSet .= "\n".$xmlOptions; @@ -1182,7 +1203,7 @@ class ComponentbuilderModelAjax extends ListModel { // get the columns $columns = $this->_db->getTableColumns("#__".$tableName); - if (ComponentbuilderHelper::checkArray($columns)) + if (UtilitiesArrayHelper::check($columns)) { // build the return string $tableColumns = array(); @@ -1276,7 +1297,7 @@ class ComponentbuilderModelAjax extends ListModel { // just return it for now a table $table = '
'; - $table .= ''; + $table .= ''; $table .= ''; $table .= '
'.JText::sprintf('COM_COMPONENTBUILDER_PLACES_ACROSS_JCB_WHERE_THIS_S_IS_LINKED', ComponentbuilderHelper::safeString($values['a_view'], 'w')).''.JText::sprintf('COM_COMPONENTBUILDER_PLACES_ACROSS_JCB_WHERE_THIS_S_IS_LINKED', StringHelper::safe($values['a_view'], 'w')).'
'.JText::_('COM_COMPONENTBUILDER_TYPE_NAME').'
' .implode('
', $linked) . '
'; return $table; @@ -1286,7 +1307,7 @@ class ComponentbuilderModelAjax extends ListModel // if not found but has session view name if (strlen($values['a_view'])) { - return '

' . JText::sprintf('COM_COMPONENTBUILDER_S_NOT_LINKED', ComponentbuilderHelper::safeString($values['a_view'], 'Ww')) . '

' . JText::sprintf('COM_COMPONENTBUILDER_THIS_BSB_IS_NOT_LINKED_TO_ANY_OTHER_AREAS_OF_JCB_AT_THIS_TIME', $values['a_view']) . '

'; + return '

' . JText::sprintf('COM_COMPONENTBUILDER_S_NOT_LINKED', StringHelper::safe($values['a_view'], 'Ww')) . '

' . JText::sprintf('COM_COMPONENTBUILDER_THIS_BSB_IS_NOT_LINKED_TO_ANY_OTHER_AREAS_OF_JCB_AT_THIS_TIME', $values['a_view']) . '

'; } // no view or id found in session, or view not allowed to access area return '

' . JText::_('COM_COMPONENTBUILDER_ERROR') . '

' . JText::_('COM_COMPONENTBUILDER_THERE_WAS_A_PROBLEM_BNO_VIEW_OR_ID_FOUND_IN_SESSION_OR_VIEW_NOT_ALLOWED_TO_ACCESS_AREAB_WE_COULD_NOT_LOAD_ANY_LINKED_TO_VALUES_PLEASE_INFORM_YOUR_SYSTEM_ADMINISTRATOR') . '

'; @@ -1362,12 +1383,12 @@ class ComponentbuilderModelAjax extends ListModel else { // check if we have a json - if (ComponentbuilderHelper::checkJson($item->{$key})) + if (JsonHelper::check($item->{$key})) { $item->{$key} = json_decode($item->{$key}, true); } // if array - if (ComponentbuilderHelper::checkArray($item->{$key})) + if (UtilitiesArrayHelper::check($item->{$key})) { if ('ARRAY' === $target) { @@ -1387,7 +1408,7 @@ class ComponentbuilderModelAjax extends ListModel { $_target = (array) explode('.', $target); // check that we have an array and get the size - if (($_size = ComponentbuilderHelper::checkArray($_target)) !== false) + if (($_size = UtilitiesArrayHelper::check($_target)) !== false) { foreach ($item->{$key} as $row) { @@ -1398,7 +1419,7 @@ class ComponentbuilderModelAjax extends ListModel $found = true; } } - elseif ($_size == 3 && isset($row[$_target[0]]) && ComponentbuilderHelper::checkArray($row[$_target[0]])) + elseif ($_size == 3 && isset($row[$_target[0]]) && UtilitiesArrayHelper::check($row[$_target[0]])) { foreach ($row[$_target[0]] as $_row) { @@ -1468,18 +1489,18 @@ class ComponentbuilderModelAjax extends ListModel } } // if string (fields) - if (!$found && 'xml' === $key && ComponentbuilderHelper::checkString($item->{$key}) + if (!$found && 'xml' === $key && StringHelper::check($item->{$key}) && strpos($item->{$key}, $target.'="') !== false) { // now get the fields between - $_fields = ComponentbuilderHelper::getBetween($item->{$key}, $target.'="', '"'); + $_fields = GetHelper::between($item->{$key}, $target.'="', '"'); // check the result - if (ComponentbuilderHelper::checkString($_fields)) + if (StringHelper::check($_fields)) { // get the ids of all the fields linked here $_fields = array_map('trim', (array) explode(',', $_fields)); // check the result - if (ComponentbuilderHelper::checkArray($_fields)) + if (UtilitiesArrayHelper::check($_fields)) { foreach ($_fields as $_field) { @@ -1519,7 +1540,7 @@ class ComponentbuilderModelAjax extends ListModel $type_name = ' (' . $type_name . ') '; } } - elseif (ComponentbuilderHelper::checkString($type_name) || is_numeric($type_name)) + elseif (StringHelper::check($type_name) || is_numeric($type_name)) { $type_name = ' (' . $type_name . ') '; } @@ -1532,7 +1553,7 @@ class ComponentbuilderModelAjax extends ListModel } } // check if we found any - if (ComponentbuilderHelper::checkArray($linked)) + if (UtilitiesArrayHelper::check($linked)) { return $linked; } @@ -1594,7 +1615,7 @@ class ComponentbuilderModelAjax extends ListModel if ($view = ComponentbuilderHelper::get($vdm)) { $current = (array) explode('__', $view); - if (ComponentbuilderHelper::checkString($current[0]) && isset($current[1]) && is_numeric($current[1])) + if (StringHelper::check($current[0]) && isset($current[1]) && is_numeric($current[1])) { // get the view name & id $this->viewid[$call] = array( @@ -1614,7 +1635,7 @@ class ComponentbuilderModelAjax extends ListModel // set return if found if (($return = ComponentbuilderHelper::get($vdm . '__return')) !== false) { - if (ComponentbuilderHelper::checkString($return)) + if (StringHelper::check($return)) { $this->viewid[$call]['a_return'] = $return; } @@ -1653,7 +1674,7 @@ class ComponentbuilderModelAjax extends ListModel $ref = '&ref=' . $values['a_view'] . '&refid=' . $values['a_id'] . '&return=' . urlencode(base64_encode($return_url)); } // build url (A tag) - $startAtag = 'onclick="UIkit2.modal.confirm(\''.JText::_('COM_COMPONENTBUILDER_ALL_UNSAVED_WORK_ON_THIS_PAGE_WILL_BE_LOST_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE').'\', function(){ window.location.href = \'index.php?option=com_componentbuilder&view=' . $type . '&layout=edit' . $ref . '\' })" href="javascript:void(0)" title="'.JText::sprintf('COM_COMPONENTBUILDER_CREATE_NEW_S', ComponentbuilderHelper::safeString($type, 'W')).'">'; + $startAtag = 'onclick="UIkit2.modal.confirm(\''.JText::_('COM_COMPONENTBUILDER_ALL_UNSAVED_WORK_ON_THIS_PAGE_WILL_BE_LOST_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE').'\', function(){ window.location.href = \'index.php?option=com_componentbuilder&view=' . $type . '&layout=edit' . $ref . '\' })" href="javascript:void(0)" title="'.JText::sprintf('COM_COMPONENTBUILDER_CREATE_NEW_S', StringHelper::safe($type, 'W')).'">'; // build the smallest button if (3 == $size) { @@ -1697,7 +1718,7 @@ class ComponentbuilderModelAjax extends ListModel // get the view name & id $values = $this->getViewID(); // set the button ID - $css_class = 'control-group-'.ComponentbuilderHelper::safeString($type. '-' . $size, 'L', '-'); + $css_class = 'control-group-'.StringHelper::safe($type. '-' . $size, 'L', '-'); // check if new item $ref = ''; if (!is_null($values['a_id']) && $values['a_id'] > 0 && strlen($values['a_view'])) @@ -1721,14 +1742,14 @@ class ComponentbuilderModelAjax extends ListModel // get item id if (($id = ComponentbuilderHelper::getVar($type, $key_get_value, $values['a_view'], 'id')) !== false && $id > 0) { - $buttonText = JText::sprintf('COM_COMPONENTBUILDER_EDIT_S_FOR_THIS_S', ComponentbuilderHelper::safeString($type, 'w'), ComponentbuilderHelper::safeString($values['a_view'], 'w')); + $buttonText = JText::sprintf('COM_COMPONENTBUILDER_EDIT_S_FOR_THIS_S', StringHelper::safe($type, 'w'), StringHelper::safe($values['a_view'], 'w')); $buttonTextSmall = JText::_('COM_COMPONENTBUILDER_EDIT'); $editThis = 'index.php?option=com_componentbuilder&view='.$this->buttonArray[$type].'&task='.$type.'.edit&id='.$id; $icon = 'icon-apply'; } else { - $buttonText = JText::sprintf('COM_COMPONENTBUILDER_CREATE_S_FOR_THIS_S', ComponentbuilderHelper::safeString($type, 'w'), ComponentbuilderHelper::safeString($values['a_view'], 'w')); + $buttonText = JText::sprintf('COM_COMPONENTBUILDER_CREATE_S_FOR_THIS_S', StringHelper::safe($type, 'w'), StringHelper::safe($values['a_view'], 'w')); $buttonTextSmall = JText::_('COM_COMPONENTBUILDER_CREATE'); $editThis = 'index.php?option=com_componentbuilder&view='.$type.'&layout=edit'; $icon = 'icon-new'; @@ -1739,7 +1760,7 @@ class ComponentbuilderModelAjax extends ListModel { $button[] = '
'; $button[] = '
'; - $button[] = ''; + $button[] = ''; $button[] = '
'; $button[] = '
'; } @@ -1764,7 +1785,7 @@ class ComponentbuilderModelAjax extends ListModel // only return notice if big button if (1 == $size) { - return '
' . JText::sprintf('COM_COMPONENTBUILDER_BUTTON_TO_CREATE_S_WILL_SHOW_ONCE_S_IS_SAVED_FOR_THE_FIRST_TIME', ComponentbuilderHelper::safeString($type, 'w'), ComponentbuilderHelper::safeString($values['a_view'], 'w')) . '
'; + return '
' . JText::sprintf('COM_COMPONENTBUILDER_BUTTON_TO_CREATE_S_WILL_SHOW_ONCE_S_IS_SAVED_FOR_THE_FIRST_TIME', StringHelper::safe($type, 'w'), StringHelper::safe($values['a_view'], 'w')) . '
'; } } } @@ -1774,12 +1795,12 @@ class ComponentbuilderModelAjax extends ListModel protected function getSubformTable($idName, $data) { // make sure we convert the json to array - if (ComponentbuilderHelper::checkJson($data)) + if (JsonHelper::check($data)) { $data = json_decode($data, true); } // make sure we have an array - if (ComponentbuilderHelper::checkArray($data) && ComponentbuilderHelper::checkString($idName)) + if (UtilitiesArrayHelper::check($data) && StringHelper::check($idName)) { // Build heading $head = array(); @@ -1795,7 +1816,7 @@ class ComponentbuilderModelAjax extends ListModel } // build the rows $rows = array(); - if (ComponentbuilderHelper::checkArray($data) && ComponentbuilderHelper::checkArray($head)) + if (UtilitiesArrayHelper::check($data) && UtilitiesArrayHelper::check($head)) { foreach ($data as $nr => $values) { @@ -1814,7 +1835,7 @@ class ComponentbuilderModelAjax extends ListModel } } // build table - if (ComponentbuilderHelper::checkArray($rows) && ComponentbuilderHelper::checkArray($head)) + if (UtilitiesArrayHelper::check($rows) && UtilitiesArrayHelper::check($head)) { // set the number of rows $this->rowNumber = count($rows); @@ -1832,7 +1853,7 @@ class ComponentbuilderModelAjax extends ListModel $value = $this->{$this->functionArray[$header]}($header, $value); } // if no value are set - if (!ComponentbuilderHelper::checkString($value)) + if (!StringHelper::check($value)) { $value = '-'; } @@ -1857,7 +1878,7 @@ class ComponentbuilderModelAjax extends ListModel if (isset($this->fieldsArray[$type])) { // set type name - $typeName = ComponentbuilderHelper::safeString($type, 'w'); + $typeName = StringHelper::safe($type, 'w'); // get the view name & id $values = $this->getViewID(); // check if we are in the correct view. @@ -1883,7 +1904,7 @@ class ComponentbuilderModelAjax extends ListModel // load the results $result = array(); // return field table - if (ComponentbuilderHelper::checkArray($this->fieldsArray[$type])) + if (UtilitiesArrayHelper::check($this->fieldsArray[$type])) { foreach ($this->fieldsArray[$type] as $fieldName) { @@ -1893,7 +1914,7 @@ class ComponentbuilderModelAjax extends ListModel } } } - elseif (ComponentbuilderHelper::checkString($this->fieldsArray[$type])) + elseif (StringHelper::check($this->fieldsArray[$type])) { if ($table = $this->getFieldTable($type, $key_get_value, $values['a_view'], $this->fieldsArray[$type], $typeName)) { @@ -1901,12 +1922,12 @@ class ComponentbuilderModelAjax extends ListModel } } // check if we have results - if (ComponentbuilderHelper::checkArray($result) && count($result) == 1) + if (UtilitiesArrayHelper::check($result) && count($result) == 1) { // return the display return implode('', $result); } - elseif (ComponentbuilderHelper::checkArray($result)) + elseif (UtilitiesArrayHelper::check($result)) { // return the display return '
' . implode('
', $result) . '
'; @@ -1935,7 +1956,7 @@ class ComponentbuilderModelAjax extends ListModel $getEdit = method_exists('ComponentbuilderHelper', 'getEditButton'); // reset bucket $bucket = array(); - if (ComponentbuilderHelper::checkArray($value)) + if (UtilitiesArrayHelper::check($value)) { foreach ($value as $item) { @@ -1948,7 +1969,7 @@ class ComponentbuilderModelAjax extends ListModel $edit = false; } // check if we should load some get - if ($edit && isset($this->itemKeys[$header]['get']) && ComponentbuilderHelper::checkString($this->itemKeys[$header]['get']) && method_exists(__CLASS__, $this->itemKeys[$header]['get'])) + if ($edit && isset($this->itemKeys[$header]['get']) && StringHelper::check($this->itemKeys[$header]['get']) && method_exists(__CLASS__, $this->itemKeys[$header]['get'])) { // gets $this->itemNames[$this->itemKeys[$header]['table']][$item] .= $this->{$this->itemKeys[$header]['get']}($item); @@ -1980,7 +2001,7 @@ class ComponentbuilderModelAjax extends ListModel $edit = false; } // check if we should load some get - if ($edit && isset($this->itemKeys[$header]['get']) && ComponentbuilderHelper::checkString($this->itemKeys[$header]['get']) && method_exists(__CLASS__, $this->itemKeys[$header]['get'])) + if ($edit && isset($this->itemKeys[$header]['get']) && StringHelper::check($this->itemKeys[$header]['get']) && method_exists(__CLASS__, $this->itemKeys[$header]['get'])) { // gets $this->itemNames[$this->itemKeys[$header]['table']][$value] .= $this->{$this->itemKeys[$header]['get']}($value); @@ -2001,7 +2022,7 @@ class ComponentbuilderModelAjax extends ListModel $bucket[] = $this->itemNames[$this->itemKeys[$header]['table']][$value] . $link; } // return found items - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { return implode('
', $bucket); } @@ -2083,8 +2104,8 @@ class ComponentbuilderModelAjax extends ListModel { $edit = (($button = ComponentbuilderHelper::getEditButton($result->id, 'template', 'templates', $ref)) !== false) ? $button : ''; $editget = (isset($result->dynamic_get) && $result->dynamic_get > 0 && ($button = ComponentbuilderHelper::getEditButton($result->dynamic_get, 'dynamic_get', 'dynamic_gets', $ref)) !== false) ? $button : ''; - $result->name = (ComponentbuilderHelper::checkString($result->name)) ? $result->name : JText::_('COM_COMPONENTBUILDER_NONE_SELECTED'); - $templateString[] = "".$result->name." ".$editget."<?php echo \$this->loadTemplate('".ComponentbuilderHelper::safeString($result->alias)."'); ?> ".$edit.""; + $result->name = (StringHelper::check($result->name)) ? $result->name : JText::_('COM_COMPONENTBUILDER_NONE_SELECTED'); + $templateString[] = "".$result->name." ".$editget."<?php echo \$this->loadTemplate('".StringHelper::safe($result->alias)."'); ?> ".$edit.""; } // build the table $table = '

' . JText::_('COM_COMPONENTBUILDER_TEMPLATE_CODE_SNIPPETS') . '

'; @@ -2135,22 +2156,22 @@ class ComponentbuilderModelAjax extends ListModel { $edit = (($button = ComponentbuilderHelper::getEditButton($result->id, 'layout', 'layouts', $ref)) !== false) ? $button : ''; $editget = (isset($result->dynamic_get) && $result->dynamic_get > 0 && ($button = ComponentbuilderHelper::getEditButton($result->dynamic_get, 'dynamic_get', 'dynamic_gets', $ref)) !== false) ? $button : ''; - $result->name = (ComponentbuilderHelper::checkString($result->name)) ? $result->name : JText::_('COM_COMPONENTBUILDER_NONE_SELECTED'); + $result->name = (StringHelper::check($result->name)) ? $result->name : JText::_('COM_COMPONENTBUILDER_NONE_SELECTED'); switch ($result->gettype) { case 1: // single - $layoutString[] = ""; + $layoutString[] = ""; break; case 2: // list - $layoutString[] = ""; + $layoutString[] = ""; break; case 3: case 4: // custom - $result->getcustom = ComponentbuilderHelper::safeString($result->getcustom); + $result->getcustom = StringHelper::safe($result->getcustom); if (substr($result->getcustom, 0, strlen('get')) == 'get') { $varName = substr($result->getcustom, strlen('get')); @@ -2159,11 +2180,11 @@ class ComponentbuilderModelAjax extends ListModel { $varName = $result->getcustom; } - $layoutString[] = ""; + $layoutString[] = ""; break; default: // no get - $layoutString[] = ""; + $layoutString[] = ""; break; } } @@ -2231,17 +2252,17 @@ class ComponentbuilderModelAjax extends ListModel } // get the joined values (name) $result->join_view_table = json_decode($result->join_view_table, true); - if (!ComponentbuilderHelper::checkArray($result->join_view_table)) + if (!UtilitiesArrayHelper::check($result->join_view_table)) { unset($result->join_view_table); } $result->join_db_table = json_decode($result->join_db_table, true); - if (!ComponentbuilderHelper::checkArray($result->join_db_table)) + if (!UtilitiesArrayHelper::check($result->join_db_table)) { unset($result->join_db_table); } // now load the joined values to the selection set - if (isset($result->join_view_table) && ComponentbuilderHelper::checkArray($result->join_view_table)) + if (isset($result->join_view_table) && UtilitiesArrayHelper::check($result->join_view_table)) { foreach ($result->join_view_table as $join_view_table) { @@ -2263,7 +2284,7 @@ class ComponentbuilderModelAjax extends ListModel } unset($result->join_view_table); } - if (isset($result->join_db_table) && ComponentbuilderHelper::checkArray($result->join_db_table)) + if (isset($result->join_db_table) && UtilitiesArrayHelper::check($result->join_db_table)) { foreach ($result->join_db_table as $join_db_table) { @@ -2289,7 +2310,7 @@ class ComponentbuilderModelAjax extends ListModel if ($result->addcalculation == 1) { $php_calculation = base64_decode($result->php_calculation); - $phpSelections = ComponentbuilderHelper::getAllBetween($php_calculation,'cal__',' '); + $phpSelections = GetHelper::allBetween($php_calculation,'cal__',' '); $selections[] = array_unique($phpSelections); unset($php_calculation); unset($phpSelections); @@ -2311,7 +2332,7 @@ class ComponentbuilderModelAjax extends ListModel case 3: case 4: // custom - $result->getcustom = ComponentbuilderHelper::safeString($result->getcustom); + $result->getcustom = StringHelper::safe($result->getcustom); if (substr($result->getcustom, 0, strlen('get')) == 'get') { $varName = substr($result->getcustom, strlen('get')); @@ -2329,7 +2350,7 @@ class ComponentbuilderModelAjax extends ListModel $buketName = 'displayData'; } // now build the return values - if (ComponentbuilderHelper::checkArray($selections)) + if (UtilitiesArrayHelper::check($selections)) { $buket = array(); switch ($result->gettype) @@ -2350,7 +2371,7 @@ class ComponentbuilderModelAjax extends ListModel } foreach ($selections as $selection) { - if (ComponentbuilderHelper::checkArray($selection)) + if (UtilitiesArrayHelper::check($selection)) { foreach ($selection as $value) { @@ -2366,12 +2387,12 @@ class ComponentbuilderModelAjax extends ListModel } } } - if (ComponentbuilderHelper::checkArray($selectionsList)) + if (UtilitiesArrayHelper::check($selectionsList)) { $buket[] = '
'; foreach ($selectionsList as $name => $selectionList) { - if (ComponentbuilderHelper::checkArray($selectionList)) + if (UtilitiesArrayHelper::check($selectionList)) { $ur = '<?php echo $'.$name; $cf = '; ?>'; @@ -2409,11 +2430,11 @@ class ComponentbuilderModelAjax extends ListModel protected function setListMethodName($names, $table, $as, $type) { $methodNames = array(); - if (ComponentbuilderHelper::checkArray($names)) + if (UtilitiesArrayHelper::check($names)) { foreach ($names as $nr => $name) { - if (ComponentbuilderHelper::checkString($name)) + if (StringHelper::check($name)) { if (strpos($name,'.') !== false) { @@ -2425,11 +2446,11 @@ class ComponentbuilderModelAjax extends ListModel } if ($nr > 0) { - $methodNames[] = ComponentbuilderHelper::safeString($var,'F'); + $methodNames[] = StringHelper::safe($var,'F'); } else { - $methodNames[] = ComponentbuilderHelper::safeString($var); + $methodNames[] = StringHelper::safe($var); } } } @@ -2438,16 +2459,16 @@ class ComponentbuilderModelAjax extends ListModel { // set view name case 1: - $methodNames[] = ComponentbuilderHelper::safeString($this->getViewName($table),'F'); + $methodNames[] = StringHelper::safe($this->getViewName($table),'F'); break; // set db name case 2: - $methodNames[] = ComponentbuilderHelper::safeString($table,'F'); + $methodNames[] = StringHelper::safe($table,'F'); break; } // make sure there is uniqe method names - $methodNames[] = ComponentbuilderHelper::safeString($as,'U'); + $methodNames[] = StringHelper::safe($as,'U'); return $methodNames; } @@ -2476,7 +2497,7 @@ class ComponentbuilderModelAjax extends ListModel $jinput = JFactory::getApplication()->input; $return_here = $jinput->get('return_here', null, 'base64'); // set the return here value if not found - if (ComponentbuilderHelper::checkString($return_here)) + if (StringHelper::check($return_here)) { $return_here = '&return=' . $return_here; } @@ -2503,7 +2524,7 @@ class ComponentbuilderModelAjax extends ListModel { if (!isset($target['not_base64'][$key])) { - $value = ComponentbuilderHelper::openValidBase64($value, null); + $value = Base64Helper::open($value, null); } elseif ('json' === $target['not_base64'][$key] && 'xml' === $key) // just for field search { @@ -2520,17 +2541,17 @@ class ComponentbuilderModelAjax extends ListModel if (strpos($value, '[CUSTOMC' . 'ODE=') !== false) { // get all custom codes in value - $bucket[$key] = ComponentbuilderHelper::getAllBetween($value, '[CUSTOMC' . 'ODE=', ']'); + $bucket[$key] = GetHelper::allBetween($value, '[CUSTOMC' . 'ODE=', ']'); } // check if field has string length - if (ComponentbuilderHelper::checkString($value)) + if (StringHelper::check($value)) { // see if the field needs some help :) $_key = (isset($helper[$key])) ? $helper[$key] : $key; // build the buttons $buttons[$_key] = array(); - if (($button = $this->getButton('custom_code', 3)) && ComponentbuilderHelper::checkString($button)) + if (($button = $this->getButton('custom_code', 3)) && StringHelper::check($button)) { $buttons[$_key]['_create'] = $button; } @@ -2538,7 +2559,7 @@ class ComponentbuilderModelAjax extends ListModel } } // check if any values found - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { foreach ($bucket as $field => $customcodes) { @@ -2554,7 +2575,7 @@ class ComponentbuilderModelAjax extends ListModel // see if we can get the button if (!isset($buttons[$field][$key[0]]) && ($_id = ComponentbuilderHelper::getVar('custom_code', $key[0], 'function_name')) !== false && ($button = ComponentbuilderHelper::getEditTextButton($edit_icon . $key[0], $_id, 'custom_code', 'custom_codes', $return_here, 'com_componentbuilder', false, 'btn btn-small button-edit" style="margin: 0 0 5px 0;')) - && ComponentbuilderHelper::checkString($button)) + && StringHelper::check($button)) { $buttons[$field][$key[0]] = $button; } @@ -2563,7 +2584,7 @@ class ComponentbuilderModelAjax extends ListModel } } // only continue if we have buttons in array - if (ComponentbuilderHelper::checkArray($buttons, true)) + if (UtilitiesArrayHelper::check($buttons, true)) { return $buttons; } @@ -2574,7 +2595,7 @@ class ComponentbuilderModelAjax extends ListModel public function checkFunctionName($name, $id) { $nameArray = (array) $this->splitAtUpperCase($name); - $name = ComponentbuilderHelper::safeString(implode(' ', $nameArray), 'cA'); + $name = StringHelper::safe(implode(' ', $nameArray), 'cA'); if ($found = ComponentbuilderHelper::getVar('custom_code', $name, 'function_name', 'id')) { if ((int) $id !== (int) $found) @@ -2633,7 +2654,7 @@ class ComponentbuilderModelAjax extends ListModel { if (!isset($target['not_base64'][$key])) { - $value = ComponentbuilderHelper::openValidBase64($value, null); + $value = Base64Helper::open($value, null); } elseif ('json' === $target['not_base64'][$key] && 'xml' === $key) // just for field search { @@ -2686,13 +2707,13 @@ class ComponentbuilderModelAjax extends ListModel } } // check if any values found - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { // get input $jinput = JFactory::getApplication()->input; $return_here = $jinput->get('return_here', null, 'base64'); // set the return here value if not found - if (ComponentbuilderHelper::checkString($return_here)) + if (StringHelper::check($return_here)) { $return_here = '&return=' . $return_here; } @@ -2704,7 +2725,7 @@ class ComponentbuilderModelAjax extends ListModel foreach ($bucket as $editId => $values) { if (($button = ComponentbuilderHelper::getEditTextButton($values['name'], $editId, $target['table'], $target['views'], $return_here, 'com_componentbuilder', false, '')) - && ComponentbuilderHelper::checkString($button)) + && StringHelper::check($button)) { $usedin[] = $button. ' (' . implode(', ', $values['fields']) . ')'; } @@ -2734,9 +2755,9 @@ class ComponentbuilderModelAjax extends ListModel if (isset($target['_start'])) { // get all values - $allBetween = ComponentbuilderHelper::getAllBetween($value, $target['start'], $target['_start']); + $allBetween = GetHelper::allBetween($value, $target['start'], $target['_start']); // just again make sure we found some - if (ComponentbuilderHelper::checkArray($allBetween)) + if (UtilitiesArrayHelper::check($allBetween)) { if (count((array) $allBetween) > 1) { @@ -2767,14 +2788,14 @@ class ComponentbuilderModelAjax extends ListModel $starts[] = $target['start']; } // has any been found - if (ComponentbuilderHelper::checkArray($starts)) + if (UtilitiesArrayHelper::check($starts)) { foreach ($starts as $_start) { // get the base64 string - $base64 = ComponentbuilderHelper::getBetween($value, $_start, $target['end']); + $base64 = GetHelper::between($value, $_start, $target['end']); // now open the base64 text - $tmp = ComponentbuilderHelper::openValidBase64($base64); + $tmp = Base64Helper::open($base64); // insert it back into the value (so we still search the whole string) $value = str_replace($base64, $tmp, $value); } @@ -3055,7 +3076,7 @@ class ComponentbuilderModelAjax extends ListModel { if (!isset($target['not_base64'][$key])) { - $value = ComponentbuilderHelper::openValidBase64($value, null); + $value = Base64Helper::open($value, null); } elseif ('json' === $target['not_base64'][$key] && 'xml' === $key) // just for field search { @@ -3108,13 +3129,13 @@ class ComponentbuilderModelAjax extends ListModel } } // check if any values found - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { // get input $jinput = JFactory::getApplication()->input; $return_here = $jinput->get('return_here', null, 'base64'); // set the return here value if not found - if (ComponentbuilderHelper::checkString($return_here)) + if (StringHelper::check($return_here)) { $return_here = '&return=' . $return_here; } @@ -3126,7 +3147,7 @@ class ComponentbuilderModelAjax extends ListModel foreach ($bucket as $editId => $values) { if (($button = ComponentbuilderHelper::getEditTextButton($values['name'], $editId, $target['table'], $target['views'], $return_here, 'com_componentbuilder', false, '')) - && ComponentbuilderHelper::checkString($button)) + && StringHelper::check($button)) { $placedin[] = $button. ' (' . implode(', ', $values['fields']) . ')'; } @@ -3168,7 +3189,7 @@ class ComponentbuilderModelAjax extends ListModel public function checkRuleName($name, $id) { - $name = ComponentbuilderHelper::safeString($name); + $name = StringHelper::safe($name); if ($found = ComponentbuilderHelper::getVar('validation_rule', $name, 'name', 'id')) { if ((int) $id !== (int) $found) @@ -3253,7 +3274,7 @@ class ComponentbuilderModelAjax extends ListModel $names = $db->loadAssocList('name', 'short_description'); } // merge the arrays - $rules = ComponentbuilderHelper::mergeArrays(array($exitingNames, $names)); + $rules = UtilitiesArrayHelper::merge(array($exitingNames, $names)); // sort the array ksort($rules); // return the validation rules @@ -3290,7 +3311,7 @@ class ComponentbuilderModelAjax extends ListModel $field['subform'] = '
'. $properties->label . '
' . $properties->input . '
'; $field['extra'] = '
'. $extras->label . '
' . $extras->input . '
'; // check if we have PHP values - if (ComponentbuilderHelper::checkArray($field['php'])) + if (UtilitiesArrayHelper::check($field['php'])) { $field['textarea'] = array(); foreach($field['php'] as $name => $values) @@ -3320,7 +3341,7 @@ class ComponentbuilderModelAjax extends ListModel { if (!in_array($extra, $options)) { - $value = ComponentbuilderHelper::getValueFromXMLstring($xml, $extra, $confirmation); + $value = FieldHelper::getValue($xml, $extra, $confirmation); if ($confirmation !== $value) { $values['extraproperties' . $nr] = array('name' => $extra, 'value' => $value, 'desc' => JText::_($desc)); @@ -3329,7 +3350,7 @@ class ComponentbuilderModelAjax extends ListModel } } // return only if extras founb - if (ComponentbuilderHelper::checkArray($values)) + if (UtilitiesArrayHelper::check($values)) { return $values; } @@ -3376,7 +3397,7 @@ class ComponentbuilderModelAjax extends ListModel 'layout' => 'joomla.form.field.subform.repeatable-table', 'multiple' => 'true', 'icon' => 'list', - 'max' => (ComponentbuilderHelper::checkArray($nameListOptions)) ? (int) count($nameListOptions) : 4); + 'max' => (UtilitiesArrayHelper::check($nameListOptions)) ? (int) count($nameListOptions) : 4); // load the subform attributes ComponentbuilderHelper::xmlAddAttributes($subformXML, $subformAttribute); // now add the subform child form @@ -3393,15 +3414,15 @@ class ComponentbuilderModelAjax extends ListModel $nameXML = new SimpleXMLElement(''); // subform attributes $nameAttribute = array( - 'type' => (ComponentbuilderHelper::checkArray($nameListOptions)) ? 'list' : 'text', + 'type' => (UtilitiesArrayHelper::check($nameListOptions)) ? 'list' : 'text', 'name' => 'name', 'label' => 'COM_COMPONENTBUILDER_PROPERTY', 'size' => '40', 'maxlength' => '150', - 'class' => (ComponentbuilderHelper::checkArray($nameListOptions)) ? 'list_class field_list_name_options' : 'text_area', + 'class' => (UtilitiesArrayHelper::check($nameListOptions)) ? 'list_class field_list_name_options' : 'text_area', 'filter' => 'STRING'); // add the hint only if not name list and description if name list is an array - if (ComponentbuilderHelper::checkArray($nameListOptions)) + if (UtilitiesArrayHelper::check($nameListOptions)) { $nameAttribute['description'] = 'COM_COMPONENTBUILDER_SELECTION'; $nameAttribute['multiple'] = 'false'; @@ -3414,7 +3435,7 @@ class ComponentbuilderModelAjax extends ListModel // load the subform attributes ComponentbuilderHelper::xmlAddAttributes($nameXML, $nameAttribute); // add name list if found - if (ComponentbuilderHelper::checkArray($nameListOptions)) + if (UtilitiesArrayHelper::check($nameListOptions)) { ComponentbuilderHelper::xmlAddOptions($nameXML, $nameListOptions); } @@ -3490,17 +3511,17 @@ class ComponentbuilderModelAjax extends ListModel // value to check since there are false and null values even 0 in the values returned $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; // make sure we have an array - if (ComponentbuilderHelper::checkArray($properties)) + if (UtilitiesArrayHelper::check($properties)) { foreach ($properties as $property) { if(isset($property['name']) && $_property === $property['name']) { // check if we should load the value - $value = ComponentbuilderHelper::getValueFromXMLstring($xml, $property['name'], $confirmation); + $value = FieldHelper::getValue($xml, $property['name'], $confirmation); if ($confirmation === $value) { - $value = (isset($property['example']) && ComponentbuilderHelper::checkString($property['example'])) ? $property['example'] : ''; + $value = (isset($property['example']) && StringHelper::check($property['example'])) ? $property['example'] : ''; } // return the found values return array('value' => $value, 'desc' => $property['description']); @@ -3529,7 +3550,7 @@ class ComponentbuilderModelAjax extends ListModel $_fieldType = ComponentbuilderHelper::getVar('field', $global['a_id'], 'id', 'fieldtype'); $xmlDB = ComponentbuilderHelper::getVar('field', $global['a_id'], 'id', 'xml'); // check if it is a string - if (ComponentbuilderHelper::checkString($xmlDB)) + if (StringHelper::check($xmlDB)) { $xml = json_decode($xmlDB); } @@ -3604,16 +3625,236 @@ class ComponentbuilderModelAjax extends ListModel return false; } + // Used in search + /** + * Search for value in a table + * + * @param string $tableName The main table to search + * @param int $typeSearch The type of search being done + * @param string $searchValue The value to search for + * @param int $matchCase The switch to control match case + * @param int $wholeWord The switch to control whole word + * @param int $regexSearch The switch to control regex search + * @param int $componentId The option to filter by component + * + * @return array|null + * @since 3.2.0 + **/ + public function doSearch(string $tableName, int $typeSearch, string $searchValue, + int $matchCase, int $wholeWord, int $regexSearch, int $componentId): ?array + { + // check if this is a valid table + if (SearchFactory::_('Table')->exist($tableName)) + { + try + { + // load the configurations + SearchFactory::_('Config')->table_name = $tableName; + SearchFactory::_('Config')->type_search = $typeSearch; + SearchFactory::_('Config')->search_value = $searchValue; + SearchFactory::_('Config')->match_case = $matchCase; + SearchFactory::_('Config')->whole_word = $wholeWord; + SearchFactory::_('Config')->regex_search = $regexSearch; + SearchFactory::_('Config')->component_id = $componentId; + + if (($items = SearchFactory::_('Agent')->table($tableName)) !== null) + { + return [ + 'success' => JText::sprintf('COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S', $tableName), + 'items' => $items, + 'fields_count' => SearchFactory::_('Config')->field_counter, + 'line_count' => SearchFactory::_('Config')->line_counter + ]; + } + + return [ + 'not_found' => JText::sprintf('COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_IN_S', $tableName), + 'fields_count' => SearchFactory::_('Config')->field_counter, + 'line_count' => SearchFactory::_('Config')->line_counter + ]; + } + catch(Exception $error) + { + return ['error' => $error->getMessage()]; + } + } + + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + /** + * Search and replace value in a table + * + * @param string $tableName The main table to search + * @param string $searchValue The value to search for + * @param string|null $replaceValue The value to replace search value + * @param int $matchCase The switch to control match case + * @param int $wholeWord The switch to control whole word + * @param int $regexSearch The switch to control regex search + * @param int $componentId The option to filter by component + * + * @return array|null + * @since 3.2.0 + **/ + public function replaceAll(string $tableName, string $searchValue, ?string $replaceValue = null, + int $matchCase, int $wholeWord, int $regexSearch, int $componentId): ?array + { + // check if this is a valid table + if (SearchFactory::_('Table')->exist($tableName)) + { + try + { + // load the configurations + SearchFactory::_('Config')->table_name = $tableName; + SearchFactory::_('Config')->search_value = $searchValue; + SearchFactory::_('Config')->replace_value = $replaceValue; + SearchFactory::_('Config')->match_case = $matchCase; + SearchFactory::_('Config')->whole_word = $wholeWord; + SearchFactory::_('Config')->regex_search = $regexSearch; + SearchFactory::_('Config')->component_id = $componentId; + + if (($number = SearchFactory::_('Agent')->replace()) !== 0) + { + return ['success' => JText::sprintf('COM_COMPONENTBUILDER_ALL_FOUND_INSTANCES_IN_S_WHERE_REPLACED', $tableName)]; + } + return ['not_found' => JText::sprintf('COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_IN_S', $tableName)]; + } + catch(Exception $error) + { + return ['error' => $error->getMessage()]; + } + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + /** + * Get a selected search value from a given table and row + * + * @param string $fieldName The field key + * @param int $rowId The item ID + * @param string $tableName The table + * @param string $searchValue The value to search for + * @param string|null $replaceValue The value to replace search value + * @param int $matchCase The switch to control match case + * @param int $wholeWord The switch to control whole word + * @param int $regexSearch The switch to control regex search + * + * @return array + * @since 3.2.0 + **/ + public function getSearchValue(string $fieldName, int $rowId, string $tableName, + string $searchValue, ?string $replaceValue = null, int $matchCase, int $wholeWord, int $regexSearch): array + { + // check if this is a valid table and field + if ($rowId > 0 && SearchFactory::_('Table')->exist($tableName, $fieldName)) + { + try + { + // load the configurations + SearchFactory::_('Config')->table_name = $tableName; + SearchFactory::_('Config')->type_search = 1; + SearchFactory::_('Config')->search_value = $searchValue; + SearchFactory::_('Config')->replace_value = $replaceValue; + SearchFactory::_('Config')->match_case = $matchCase; + SearchFactory::_('Config')->whole_word = $wholeWord; + SearchFactory::_('Config')->regex_search = $regexSearch; + + if (($value = SearchFactory::_('Agent')->getValue($rowId, $fieldName, 0, $tableName)) !== null) + { + // load the value + return ['value' => $value]; + } + } + catch(Exception $error) + { + return ['error' => $error->getMessage()]; + } + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + /** + * Get a replaced search value from a given table and row + * + * @param string $fieldName The field key + * @param int $rowId The item ID + * @param mixed $line The line line + * @param string $tableName The table + * @param string $searchValue The value to search for + * @param string|null $replaceValue The value to replace search value + * @param int $matchCase The switch to control match case + * @param int $wholeWord The switch to control whole word + * @param int $regexSearch The switch to control regex search + * + * @return array + * @since 3.2.0 + **/ + public function getReplaceValue(string $fieldName, int $rowId, $line, string $tableName, + string $searchValue, ?string $replaceValue = null, int $matchCase, int $wholeWord, int $regexSearch): array + { + // check if this is a valid table and field + if ($rowId > 0 && SearchFactory::_('Table')->exist($tableName, $fieldName)) + { + try + { + // load the configurations + SearchFactory::_('Config')->table_name = $tableName; + SearchFactory::_('Config')->type_search = 2; + SearchFactory::_('Config')->search_value = $searchValue; + SearchFactory::_('Config')->replace_value = $replaceValue; + SearchFactory::_('Config')->match_case = $matchCase; + SearchFactory::_('Config')->whole_word = $wholeWord; + SearchFactory::_('Config')->regex_search = $regexSearch; + + // load the value + if (($value = SearchFactory::_('Agent')->getValue($rowId, $fieldName, $line, $tableName, true)) !== null) + { + return ['value' => $value]; + } + } + catch(Exception $error) + { + return ['error' => $error->getMessage()]; + } + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + /** + * Set selected search value in a given table and row + * + * @param mixed $value The field value + * @param int $rowId The item ID + * @param string $fieldName The field key + * @param string $tableName The table + * + * @return array + * @since 3.2.0 + **/ + public function setValue($value, int $rowId, string $fieldName, string $tableName): array + { + // check if this is a valid table and field + if ($rowId > 0 && SearchFactory::_('Table')->exist($tableName, $fieldName) && + SearchFactory::_('Agent')->setValue($value, $rowId, $fieldName, $tableName)) + { + return ['success' => JText::sprintf( + '%s (%s:%s) was successfully updated!', + $tableName, $rowId, $fieldName)]; + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + // Used in get_snippets public function getSnippets($libraries) { - if (ComponentbuilderHelper::checkJson($libraries)) + if (JsonHelper::check($libraries)) { $libraries = json_decode($libraries, true); } // check if we have an array - if (ComponentbuilderHelper::checkArray($libraries)) + if (UtilitiesArrayHelper::check($libraries)) { // insure we only have int values if ($libraries = $this->checkLibraries($libraries)) @@ -3647,12 +3888,12 @@ class ComponentbuilderModelAjax extends ListModel if (2 == $type && $bundled = ComponentbuilderHelper::getVar('library', (int) $id, 'id', 'libraries')) { // make sure we have an array if it was json - if (ComponentbuilderHelper::checkJson($bundled)) + if (JsonHelper::check($bundled)) { $bundled = json_decode($bundled, true); } // load in the values if we have an array - if (ComponentbuilderHelper::checkArray($bundled)) + if (UtilitiesArrayHelper::check($bundled)) { foreach ($bundled as $lib) { @@ -3670,7 +3911,7 @@ class ComponentbuilderModelAjax extends ListModel } }, $libraries); // check if we have any bundled libraries - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { foreach ($bucket as $lib) { @@ -3678,11 +3919,11 @@ class ComponentbuilderModelAjax extends ListModel } } // check that we have libraries - if (ComponentbuilderHelper::checkArray($libraries)) + if (UtilitiesArrayHelper::check($libraries)) { $libraries = array_values(array_unique(array_filter($libraries, function($id){return is_int($id);}))); // check if we have any libraries remaining - if (ComponentbuilderHelper::checkArray($libraries)) + if (UtilitiesArrayHelper::check($libraries)) { return $libraries; } @@ -3726,7 +3967,7 @@ class ComponentbuilderModelAjax extends ListModel if ($access) { // secure path - $path = ComponentbuilderHelper::safeString(str_replace('.json','',$path), 'filename', '', false).'.json'; + $path = StringHelper::safe(str_replace('.json','',$path), 'filename', '', false).'.json'; // base path $base_path = basename($path); // set url @@ -3737,7 +3978,7 @@ class ComponentbuilderModelAjax extends ListModel return $this->saveSnippet($snippet, $status, $user); } // see if we have any errors from github - if (ComponentbuilderHelper::checkArray(ComponentbuilderHelper::$githubRepoDataErrors)) + if (UtilitiesArrayHelper::check(ComponentbuilderHelper::$githubRepoDataErrors)) { return array('message' => JText::sprintf('COM_COMPONENTBUILDER_ERROR_BR_S', implode('
', ComponentbuilderHelper::$githubRepoDataErrors)), 'status' => 'danger'); } diff --git a/admin/models/class_extends.php b/admin/models/class_extends.php index ac6640a53..02043b16b 100644 --- a/admin/models/class_extends.php +++ b/admin/models/class_extends.php @@ -16,6 +16,10 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; /** * Componentbuilder Class_extends Admin Model @@ -104,7 +108,7 @@ class ComponentbuilderModelClass_extends extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'class_extends__'.$id); ComponentbuilderHelper::set('class_extends__'.$id, $this->vastDevMod); // set a return value if found @@ -112,7 +116,7 @@ class ComponentbuilderModelClass_extends extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -182,7 +186,7 @@ class ComponentbuilderModelClass_extends extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'class_extends__'.$id); ComponentbuilderHelper::set('class_extends__'.$id, $this->vastDevMod); // set a return value if found @@ -190,7 +194,7 @@ class ComponentbuilderModelClass_extends extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -316,7 +320,7 @@ class ComponentbuilderModelClass_extends extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -388,7 +392,7 @@ class ComponentbuilderModelClass_extends extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('class_extends.edit.state', 'com_componentbuilder'); } @@ -912,7 +916,7 @@ class ComponentbuilderModelClass_extends extends AdminModel } // make sure the name is safe to be used as a class name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); // Set the head string to base64 string. if (isset($data['head'])) diff --git a/admin/models/class_method.php b/admin/models/class_method.php index b1b3fd152..9fcdaeaf6 100644 --- a/admin/models/class_method.php +++ b/admin/models/class_method.php @@ -16,6 +16,12 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Class_method Admin Model @@ -107,7 +113,7 @@ class ComponentbuilderModelClass_method extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'class_method__'.$id); ComponentbuilderHelper::set('class_method__'.$id, $this->vastDevMod); // set a return value if found @@ -115,7 +121,7 @@ class ComponentbuilderModelClass_method extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -191,7 +197,7 @@ class ComponentbuilderModelClass_method extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'class_method__'.$id); ComponentbuilderHelper::set('class_method__'.$id, $this->vastDevMod); // set a return value if found @@ -199,7 +205,7 @@ class ComponentbuilderModelClass_method extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -325,7 +331,7 @@ class ComponentbuilderModelClass_method extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -340,9 +346,9 @@ class ComponentbuilderModelClass_method extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -404,7 +410,7 @@ class ComponentbuilderModelClass_method extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('class_method.edit.state', 'com_componentbuilder'); } @@ -964,21 +970,21 @@ class ComponentbuilderModelClass_method extends AdminModel } // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); // Set the GUID if empty or not valid if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('class_method', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('class_method', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "class_method", $data['id'])) + while (!GuidHelper::valid($data['guid'], "class_method", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the code string to base64 string. if (isset($data['code'])) diff --git a/admin/models/class_property.php b/admin/models/class_property.php index 8d13330e9..492f246cd 100644 --- a/admin/models/class_property.php +++ b/admin/models/class_property.php @@ -16,6 +16,12 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Class_property Admin Model @@ -104,7 +110,7 @@ class ComponentbuilderModelClass_property extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'class_property__'.$id); ComponentbuilderHelper::set('class_property__'.$id, $this->vastDevMod); // set a return value if found @@ -112,7 +118,7 @@ class ComponentbuilderModelClass_property extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -182,7 +188,7 @@ class ComponentbuilderModelClass_property extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'class_property__'.$id); ComponentbuilderHelper::set('class_property__'.$id, $this->vastDevMod); // set a return value if found @@ -190,7 +196,7 @@ class ComponentbuilderModelClass_property extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -316,7 +322,7 @@ class ComponentbuilderModelClass_property extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -331,9 +337,9 @@ class ComponentbuilderModelClass_property extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -395,7 +401,7 @@ class ComponentbuilderModelClass_property extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('class_property.edit.state', 'com_componentbuilder'); } @@ -955,21 +961,21 @@ class ComponentbuilderModelClass_property extends AdminModel } // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); // Set the GUID if empty or not valid if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('class_property', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('class_property', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "class_property", $data['id'])) + while (!GuidHelper::valid($data['guid'], "class_property", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the comment string to base64 string. if (isset($data['comment'])) diff --git a/admin/models/compiler.php b/admin/models/compiler.php index ff338e856..d3ebd8e80 100644 --- a/admin/models/compiler.php +++ b/admin/models/compiler.php @@ -14,6 +14,7 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; /** * Componentbuilder List Model for Compiler @@ -139,81 +140,10 @@ class ComponentbuilderModelCompiler extends ListModel public $compiler; - public function getComponents() + public function builder() { - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - // Order it by the ordering field. - $query->select($db->quoteName(array('id', 'system_name'),array('id', 'name'))); - $query->from($db->quoteName('#__componentbuilder_joomla_component')); - $query->where($db->quoteName('published') . ' = 1'); - $query->order('modified DESC'); - $query->order('created DESC'); - // Reset the query using our newly populated query object. - $db->setQuery($query); - // return the result - return $db->loadObjectList(); - } - - public function getCompilerAnimations(&$errorMessage) - { - // convert error message to array - $errorMessage = array(); - $searchArray = array( - // add banners (width - height) - 'banner' => array( - '728-90', - '160-600' - ), - // The build-gif by size (width - height) - 'builder-gif' => array( - '480-540' - ) - ); - // start search, and get - foreach ($searchArray as $type => $sizes) - { - // per size - foreach ($sizes as $size) - { - // get size - if (($set_size = ComponentbuilderHelper::getDynamicContentSize($type, $size)) !== 0) - { - // we loop over all type size artwork - for ($target = 1; $target <= $set_size; $target++) - { - if (!ComponentbuilderHelper::getDynamicContent($type, $size, false, 0, $target)) - { - $errorMessage[] = JText::sprintf('COM_COMPONENTBUILDER_S_S_NUMBER_BSB_COULD_NOT_BE_DOWNLOADED_SUCCESSFULLY_TO_THIS_JOOMLA_INSTALL', $type, $size, $target); - } - } - } - } - } - // check if we had any errors - if (ComponentbuilderHelper::checkArray($errorMessage)) - { - // flatten the error message array - $errorMessage = implode('
', $errorMessage); - return false; - } - return true; - } - - public function builder($version, $id, $backup, $repo, $addPlaceholders, $addPowers, $debugLinenr, $minify) - { - $set['version'] = $version; - $set['component'] = $id; - $set['backup'] = $backup; - $set['repository'] = $repo; - $set['placeholders'] = $addPlaceholders; - $set['powers'] = $addPowers; - $set['debuglinenr'] = $debugLinenr; - $set['minify'] = $minify; // run compiler - $this->compiler = new Compiler($set); + $this->compiler = new Compiler(); if($this->compiler) { return true; @@ -367,5 +297,91 @@ class ComponentbuilderModelCompiler extends ListModel $this->cleanCache('mod_menu', 1); return $result; - } + } + + /** + * Get all components in the system + * + * @return array + * @since 3.2.0 + **/ + public function getComponents(): array + { + // Get a db connection. + $db = $this->getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + + // Select only id and system name + $query->select($db->quoteName(array('id', 'system_name'),array('id', 'name'))); + $query->from($db->quoteName('#__componentbuilder_joomla_component')); + + // only the active components + $query->where($db->quoteName('published') . ' = 1'); + + // Order it by the ordering field. + $query->order('modified DESC'); + $query->order('created DESC'); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + + // return the result + return $db->loadObjectList(); + } + + + /** + * Get all dynamic content + * + * @return bool + * @since 3.2.0 + **/ + public function getDynamicContent(&$errorMessage): bool + { + // convert error message to array + $errorMessage = []; + $searchArray = [ + // add banners (width - height) + 'banner' => [ + '728-90', + '160-600' + ], + // The build-gif by size (width - height) + 'builder-gif' => [ + '480-540' + ] + ]; + // start search, and get + foreach ($searchArray as $type => $sizes) + { + // per size + foreach ($sizes as $size) + { + // get size + if (($set_size = ComponentbuilderHelper::getDynamicContentSize($type, $size)) !== 0) + { + // we loop over all type size artwork + for ($target = 1; $target <= $set_size; $target++) + { + if (!ComponentbuilderHelper::getDynamicContent($type, $size, false, 0, $target)) + { + $errorMessage[] = JText::sprintf('COM_COMPONENTBUILDER_S_S_NUMBER_BSB_COULD_NOT_BE_DOWNLOADED_SUCCESSFULLY_TO_THIS_JOOMLA_INSTALL', $type, $size, $target); + } + } + } + } + } + // check if we had any errors + if (UtilitiesArrayHelper::check($errorMessage)) + { + // flatten the error message array + $errorMessage = implode('
', $errorMessage); + + return false; + } + return true; + } + } diff --git a/admin/models/component_admin_views.php b/admin/models/component_admin_views.php index 08852550a..7a7cb336e 100644 --- a/admin/models/component_admin_views.php +++ b/admin/models/component_admin_views.php @@ -322,7 +322,7 @@ class ComponentbuilderModelComponent_admin_views extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_admin_views.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_config.php b/admin/models/component_config.php index ad96fb621..66d6cb352 100644 --- a/admin/models/component_config.php +++ b/admin/models/component_config.php @@ -318,7 +318,7 @@ class ComponentbuilderModelComponent_config extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_config.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_custom_admin_menus.php b/admin/models/component_custom_admin_menus.php index 9f76ddbec..553021ab2 100644 --- a/admin/models/component_custom_admin_menus.php +++ b/admin/models/component_custom_admin_menus.php @@ -321,7 +321,7 @@ class ComponentbuilderModelComponent_custom_admin_menus extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_custom_admin_menus.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_custom_admin_views.php b/admin/models/component_custom_admin_views.php index 7b778cd9a..b77e89734 100644 --- a/admin/models/component_custom_admin_views.php +++ b/admin/models/component_custom_admin_views.php @@ -322,7 +322,7 @@ class ComponentbuilderModelComponent_custom_admin_views extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_custom_admin_views.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_dashboard.php b/admin/models/component_dashboard.php index 098711c7d..4177f48a5 100644 --- a/admin/models/component_dashboard.php +++ b/admin/models/component_dashboard.php @@ -16,6 +16,8 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; /** * Componentbuilder Component_dashboard Admin Model @@ -108,7 +110,7 @@ class ComponentbuilderModelComponent_dashboard extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'component_dashboard__'.$id); ComponentbuilderHelper::set('component_dashboard__'.$id, $this->vastDevMod); // set a return value if found @@ -116,7 +118,7 @@ class ComponentbuilderModelComponent_dashboard extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -188,7 +190,7 @@ class ComponentbuilderModelComponent_dashboard extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'component_dashboard__'.$id); ComponentbuilderHelper::set('component_dashboard__'.$id, $this->vastDevMod); // set a return value if found @@ -196,7 +198,7 @@ class ComponentbuilderModelComponent_dashboard extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -410,7 +412,7 @@ class ComponentbuilderModelComponent_dashboard extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_dashboard.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_files_folders.php b/admin/models/component_files_folders.php index a1bff0d3e..cec189d08 100644 --- a/admin/models/component_files_folders.php +++ b/admin/models/component_files_folders.php @@ -355,7 +355,7 @@ class ComponentbuilderModelComponent_files_folders extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_files_folders.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_modules.php b/admin/models/component_modules.php index 4319154ed..e1b43ce40 100644 --- a/admin/models/component_modules.php +++ b/admin/models/component_modules.php @@ -288,7 +288,7 @@ class ComponentbuilderModelComponent_modules extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_modules.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_mysql_tweaks.php b/admin/models/component_mysql_tweaks.php index d09d6297e..dea8a142b 100644 --- a/admin/models/component_mysql_tweaks.php +++ b/admin/models/component_mysql_tweaks.php @@ -318,7 +318,7 @@ class ComponentbuilderModelComponent_mysql_tweaks extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_mysql_tweaks.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_placeholders.php b/admin/models/component_placeholders.php index a4782f3be..19bbfa4f2 100644 --- a/admin/models/component_placeholders.php +++ b/admin/models/component_placeholders.php @@ -287,7 +287,7 @@ class ComponentbuilderModelComponent_placeholders extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_placeholders.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_plugins.php b/admin/models/component_plugins.php index 9bfb37af9..b54de992a 100644 --- a/admin/models/component_plugins.php +++ b/admin/models/component_plugins.php @@ -288,7 +288,7 @@ class ComponentbuilderModelComponent_plugins extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_plugins.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_site_views.php b/admin/models/component_site_views.php index c6d6b1667..ff52b18a7 100644 --- a/admin/models/component_site_views.php +++ b/admin/models/component_site_views.php @@ -322,7 +322,7 @@ class ComponentbuilderModelComponent_site_views extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_site_views.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/component_updates.php b/admin/models/component_updates.php index 3529af608..0bdb87c25 100644 --- a/admin/models/component_updates.php +++ b/admin/models/component_updates.php @@ -321,7 +321,7 @@ class ComponentbuilderModelComponent_updates extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('component_updates.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/componentbuilder.php b/admin/models/componentbuilder.php index 32bfb2260..09523cd9f 100644 --- a/admin/models/componentbuilder.php +++ b/admin/models/componentbuilder.php @@ -15,7 +15,6 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; use Joomla\Registry\Registry; -use VDM\Gitea\Gitea; /** * Componentbuilder List Model @@ -30,12 +29,15 @@ class ComponentbuilderModelComponentbuilder extends ListModel $icons = array(); // view groups array $viewGroups = array( - 'main' => array('png.compiler', 'png.joomla_components', 'png.joomla_modules', 'png.joomla_plugins', 'png.powers', 'png||importjcbpackages||index.php?option=com_componentbuilder&view=joomla_components&task=joomla_components.smartImport', 'png.admin_view.add', 'png.admin_views', 'png.custom_admin_view.add', 'png.custom_admin_views', 'png.site_view.add', 'png.site_views', 'png.template.add', 'png.templates', 'png.layouts', 'png.dynamic_get.add', 'png.dynamic_gets', 'png.custom_codes', 'png.placeholders', 'png.libraries', 'png.snippets', 'png.get_snippets', 'png.validation_rules', 'png.field.add', 'png.fields', 'png.fields.catid_qpo0O0oqp_com_componentbuilder_po0O0oq_field', 'png.fieldtypes', 'png.fieldtypes.catid_qpo0O0oqp_com_componentbuilder_po0O0oq_fieldtype', 'png.language_translations', 'png.servers', 'png.help_documents') + 'main' => array('png.compiler', 'png.joomla_components', 'png.joomla_modules', 'png.joomla_plugins', 'png.powers', 'png.search', 'png||importjcbpackages||index.php?option=com_componentbuilder&view=joomla_components&task=joomla_components.smartImport', 'png.admin_views', 'png.custom_admin_views', 'png.site_views', 'png.template.add', 'png.templates', 'png.layouts', 'png.dynamic_get.add', 'png.dynamic_gets', 'png.custom_codes', 'png.placeholders', 'png.libraries', 'png.snippets', 'png.get_snippets', 'png.validation_rules', 'png.field.add', 'png.fields', 'png.fields.catid_qpo0O0oqp_com_componentbuilder_po0O0oq_field', 'png.fieldtypes', 'png.fieldtypes.catid_qpo0O0oqp_com_componentbuilder_po0O0oq_fieldtype', 'png.language_translations', 'png.servers', 'png.help_documents') ); // view access array - $viewAccess = array( + $viewAccess = [ 'compiler.submenu' => 'compiler.submenu', 'compiler.dashboard_list' => 'compiler.dashboard_list', + 'search.access' => 'search.access', + 'search.submenu' => 'search.submenu', + 'search.dashboard_list' => 'search.dashboard_list', 'get_snippets.submenu' => 'get_snippets.submenu', 'get_snippets.dashboard_list' => 'get_snippets.dashboard_list', 'joomla_component.create' => 'joomla_component.create', @@ -63,17 +65,14 @@ class ComponentbuilderModelComponentbuilder extends ListModel 'admin_view.access' => 'admin_view.access', 'admin_views.submenu' => 'admin_view.submenu', 'admin_views.dashboard_list' => 'admin_view.dashboard_list', - 'admin_view.dashboard_add' => 'admin_view.dashboard_add', 'custom_admin_views.access' => 'custom_admin_view.access', 'custom_admin_view.access' => 'custom_admin_view.access', 'custom_admin_views.submenu' => 'custom_admin_view.submenu', 'custom_admin_views.dashboard_list' => 'custom_admin_view.dashboard_list', - 'custom_admin_view.dashboard_add' => 'custom_admin_view.dashboard_add', 'site_views.access' => 'site_view.access', 'site_view.access' => 'site_view.access', 'site_views.submenu' => 'site_view.submenu', 'site_views.dashboard_list' => 'site_view.dashboard_list', - 'site_view.dashboard_add' => 'site_view.dashboard_add', 'templates.access' => 'template.access', 'template.access' => 'template.access', 'templates.submenu' => 'template.submenu', @@ -222,7 +221,8 @@ class ComponentbuilderModelComponentbuilder extends ListModel 'joomla_plugin_updates.access' => 'joomla_plugin_updates.access', 'joomla_plugin_files_folders_urls.create' => 'joomla_plugin_files_folders_urls.create', 'joomla_plugins_files_folders_urls.access' => 'joomla_plugin_files_folders_urls.access', - 'joomla_plugin_files_folders_urls.access' => 'joomla_plugin_files_folders_urls.access'); + 'joomla_plugin_files_folders_urls.access' => 'joomla_plugin_files_folders_urls.access', + ]; // loop over the $views foreach($viewGroups as $group => $views) { @@ -528,6 +528,12 @@ jQuery(document).ready( function($) { return '
'.JText::_('COM_COMPONENTBUILDER_THE_README_IS_LOADING').'..
'; } + /** + * get Current Version Bay adding JavaScript to the Page + * + * @return void + * @since 2.3.0 + */ public function getVersion() { // the call URL diff --git a/admin/models/custom_admin_view.php b/admin/models/custom_admin_view.php index ea3ccfe75..33e7b1269 100644 --- a/admin/models/custom_admin_view.php +++ b/admin/models/custom_admin_view.php @@ -16,6 +16,11 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Custom_admin_view Admin Model @@ -166,7 +171,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'custom_admin_view__'.$id); ComponentbuilderHelper::set('custom_admin_view__'.$id, $this->vastDevMod); // set a return value if found @@ -174,7 +179,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -336,7 +341,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'custom_admin_view__'.$id); ComponentbuilderHelper::set('custom_admin_view__'.$id, $this->vastDevMod); // set a return value if found @@ -344,7 +349,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -489,7 +494,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -504,9 +509,9 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -568,7 +573,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::canEditState($record); } @@ -838,7 +843,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('custom_admin_view'); } - if (!$this->canDo->get('core.create') || !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.create') && !$this->canDo->get('custom_admin_view.batch')) { return false; } @@ -981,7 +986,7 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('custom_admin_view'); } - if (!$this->canDo->get('core.edit') && !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.edit') && !$this->canDo->get('custom_admin_view.batch')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; @@ -1094,44 +1099,44 @@ class ComponentbuilderModelCustom_admin_view extends AdminModel // always reset the snippets $data['snippet'] = 0; // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } // if codename is empty create from name - if (empty($data['codename']) || !ComponentbuilderHelper::checkString($data['codename'])) + if (empty($data['codename']) || !UtilitiesStringHelper::check($data['codename'])) { - $data['codename'] = ComponentbuilderHelper::safeString($data['name']); + $data['codename'] = UtilitiesStringHelper::safe($data['name']); } else { // always make safe string - $data['codename'] = ComponentbuilderHelper::safeString($data['codename']); + $data['codename'] = UtilitiesStringHelper::safe($data['codename']); } // if context is empty create from codename - if (empty($data['context']) || !ComponentbuilderHelper::checkString($data['context'])) + if (empty($data['context']) || !UtilitiesStringHelper::check($data['context'])) { $data['context'] = $data['codename']; } else { // always make safe string - $data['context'] = ComponentbuilderHelper::safeString($data['context']); + $data['context'] = UtilitiesStringHelper::safe($data['context']); } // Set the GUID if empty or not valid if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('custom_admin_view', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('custom_admin_view', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "custom_admin_view", $data['id'])) + while (!GuidHelper::valid($data['guid'], "custom_admin_view", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the custom_get items to data. if (isset($data['custom_get']) && is_array($data['custom_get'])) diff --git a/admin/models/custom_admin_views.php b/admin/models/custom_admin_views.php index 59ad7188a..23313ee78 100644 --- a/admin/models/custom_admin_views.php +++ b/admin/models/custom_admin_views.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; /** * Custom_admin_views List Model @@ -68,7 +70,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND') . ' -' ); // check if we have joomla components - if (($joomla_components = ComponentbuilderHelper::getByTypeTheIdsSystemNames('joomla_component')) !== false) + if (($joomla_components = JCBFilterHelper::names('joomla_component')) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_COMPONENT') . ' -' @@ -77,7 +79,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel $options = $options + $joomla_components; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'joomla_component', 'filter', @@ -293,7 +295,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_custom_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_custom_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -498,7 +500,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_custom_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_custom_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/models/custom_code.php b/admin/models/custom_code.php index a07ef2d23..e514628f7 100644 --- a/admin/models/custom_code.php +++ b/admin/models/custom_code.php @@ -16,6 +16,10 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Custom_code Admin Model @@ -119,7 +123,7 @@ class ComponentbuilderModelCustom_code extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'custom_code__'.$id); ComponentbuilderHelper::set('custom_code__'.$id, $this->vastDevMod); // set a return value if found @@ -127,7 +131,7 @@ class ComponentbuilderModelCustom_code extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -191,7 +195,7 @@ class ComponentbuilderModelCustom_code extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'custom_code__'.$id); ComponentbuilderHelper::set('custom_code__'.$id, $this->vastDevMod); // set a return value if found @@ -199,7 +203,7 @@ class ComponentbuilderModelCustom_code extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -325,7 +329,7 @@ class ComponentbuilderModelCustom_code extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -397,7 +401,7 @@ class ComponentbuilderModelCustom_code extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('custom_code.edit.state', 'com_componentbuilder'); } @@ -957,8 +961,8 @@ class ComponentbuilderModelCustom_code extends AdminModel } // few checks with the new option of using custom code in custom code - if (isset($data['code']) && ($placeholders = ComponentbuilderHelper::getAllBetween($data['code'], '[CUSTOM' . 'CODE=', ']')) - && ComponentbuilderHelper::checkArray($placeholders)) + if (isset($data['code']) && ($placeholders = GetHelper::allBetween($data['code'], '[CUSTOM' . 'CODE=', ']')) + && UtilitiesArrayHelper::check($placeholders)) { // make sure custom code as Hash (automation) target does not have other custom code placeholders if (isset($data['target']) && 1 == $data['target']) diff --git a/admin/models/custom_codes.php b/admin/models/custom_codes.php index 2723d1153..3c89e7f11 100644 --- a/admin/models/custom_codes.php +++ b/admin/models/custom_codes.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\StringHelper; /** * Custom_codes List Model @@ -161,7 +163,7 @@ class ComponentbuilderModelCustom_codes extends ListModel } } - if (ComponentbuilderHelper::checkArray($items) && !isset($_export)) + if (UtilitiesArrayHelper::check($items) && !isset($_export)) { foreach ($items as $nr => &$item) { @@ -169,7 +171,7 @@ class ComponentbuilderModelCustom_codes extends ListModel { $item->component_system_name = $item->system_name; $item->path = '[CUSTO'.'MCODE='.$item->id.']'; // so it is not detected - if (ComponentbuilderHelper::checkString($item->function_name)) + if (StringHelper::check($item->function_name)) { $item->path = '[CUSTO'.'MCODE='.$item->function_name.']'; // so it is not detected } @@ -489,7 +491,7 @@ class ComponentbuilderModelCustom_codes extends ListModel array_unshift($items,$headers); } - if (ComponentbuilderHelper::checkArray($items) && !isset($_export)) + if (UtilitiesArrayHelper::check($items) && !isset($_export)) { foreach ($items as $nr => &$item) { @@ -497,7 +499,7 @@ class ComponentbuilderModelCustom_codes extends ListModel { $item->component_system_name = $item->system_name; $item->path = '[CUSTO'.'MCODE='.$item->id.']'; // so it is not detected - if (ComponentbuilderHelper::checkString($item->function_name)) + if (StringHelper::check($item->function_name)) { $item->path = '[CUSTO'.'MCODE='.$item->function_name.']'; // so it is not detected } diff --git a/admin/models/dynamic_get.php b/admin/models/dynamic_get.php index 7ddb2db1e..bbeddd0d7 100644 --- a/admin/models/dynamic_get.php +++ b/admin/models/dynamic_get.php @@ -16,6 +16,11 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Dynamic_get Admin Model @@ -159,7 +164,7 @@ class ComponentbuilderModelDynamic_get extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'dynamic_get__'.$id); ComponentbuilderHelper::set('dynamic_get__'.$id, $this->vastDevMod); // set a return value if found @@ -167,7 +172,7 @@ class ComponentbuilderModelDynamic_get extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -335,7 +340,7 @@ class ComponentbuilderModelDynamic_get extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'dynamic_get__'.$id); ComponentbuilderHelper::set('dynamic_get__'.$id, $this->vastDevMod); // set a return value if found @@ -343,7 +348,7 @@ class ComponentbuilderModelDynamic_get extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -503,7 +508,7 @@ class ComponentbuilderModelDynamic_get extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -518,9 +523,9 @@ class ComponentbuilderModelDynamic_get extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + // update the join_view_table (sub form) layout $form->setFieldAttribute('join_view_table', 'layout', ComponentbuilderHelper::getSubformLayout('dynamic_get', 'join_view_table')); @@ -588,7 +593,7 @@ class ComponentbuilderModelDynamic_get extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('dynamic_get.edit.state', 'com_componentbuilder'); } @@ -1152,15 +1157,15 @@ class ComponentbuilderModelDynamic_get extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('dynamic_get', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('dynamic_get', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "dynamic_get", $data['id'])) + while (!GuidHelper::valid($data['guid'], "dynamic_get", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the join_db_table items to data. if (isset($data['join_db_table']) && is_array($data['join_db_table'])) diff --git a/admin/models/field.php b/admin/models/field.php index fb00103bb..de938d9f0 100644 --- a/admin/models/field.php +++ b/admin/models/field.php @@ -16,6 +16,13 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Utilities\String\TypeHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Field Admin Model @@ -54,6 +61,8 @@ class ComponentbuilderModelField extends AdminModel 'indexes', 'null_switch', 'store', + 'medium_encryption_note', + 'basic_encryption_note', 'note_whmcs_encryption', 'note_expert_field_save_mode', 'initiator_on_save_model', @@ -66,6 +75,12 @@ class ComponentbuilderModelField extends AdminModel 'note_database_settings_needed' ) ), + 'type_info' => array( + 'fullwidth' => array( + 'helpnote', + 'xml' + ) + ), 'scripts' => array( 'left' => array( 'add_css_view', @@ -79,12 +94,6 @@ class ComponentbuilderModelField extends AdminModel 'add_javascript_views_footer', 'javascript_views_footer' ) - ), - 'type_info' => array( - 'fullwidth' => array( - 'helpnote', - 'xml' - ) ) ); @@ -150,7 +159,7 @@ class ComponentbuilderModelField extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'field__'.$id); ComponentbuilderHelper::set('field__'.$id, $this->vastDevMod); // set a return value if found @@ -158,7 +167,7 @@ class ComponentbuilderModelField extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -199,12 +208,6 @@ class ComponentbuilderModelField extends AdminModel $item->metadata = $registry->toArray(); } - if (!empty($item->on_get_model_field)) - { - // base64 Decode on_get_model_field. - $item->on_get_model_field = base64_decode($item->on_get_model_field); - } - if (!empty($item->on_save_model_field)) { // base64 Decode on_save_model_field. @@ -217,16 +220,10 @@ class ComponentbuilderModelField extends AdminModel $item->initiator_on_get_model = base64_decode($item->initiator_on_get_model); } - if (!empty($item->css_view)) + if (!empty($item->initiator_on_save_model)) { - // base64 Decode css_view. - $item->css_view = base64_decode($item->css_view); - } - - if (!empty($item->javascript_view_footer)) - { - // base64 Decode javascript_view_footer. - $item->javascript_view_footer = base64_decode($item->javascript_view_footer); + // base64 Decode initiator_on_save_model. + $item->initiator_on_save_model = base64_decode($item->initiator_on_save_model); } if (!empty($item->css_views)) @@ -235,18 +232,30 @@ class ComponentbuilderModelField extends AdminModel $item->css_views = base64_decode($item->css_views); } + if (!empty($item->css_view)) + { + // base64 Decode css_view. + $item->css_view = base64_decode($item->css_view); + } + + if (!empty($item->on_get_model_field)) + { + // base64 Decode on_get_model_field. + $item->on_get_model_field = base64_decode($item->on_get_model_field); + } + + if (!empty($item->javascript_view_footer)) + { + // base64 Decode javascript_view_footer. + $item->javascript_view_footer = base64_decode($item->javascript_view_footer); + } + if (!empty($item->javascript_views_footer)) { // base64 Decode javascript_views_footer. $item->javascript_views_footer = base64_decode($item->javascript_views_footer); } - if (!empty($item->initiator_on_save_model)) - { - // base64 Decode initiator_on_save_model. - $item->initiator_on_save_model = base64_decode($item->initiator_on_save_model); - } - if (!empty($item->xml)) { // JSON Decode xml. @@ -270,7 +279,7 @@ class ComponentbuilderModelField extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'field__'.$id); ComponentbuilderHelper::set('field__'.$id, $this->vastDevMod); // set a return value if found @@ -278,7 +287,7 @@ class ComponentbuilderModelField extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -402,7 +411,7 @@ class ComponentbuilderModelField extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -417,7 +426,7 @@ class ComponentbuilderModelField extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } return $form; @@ -481,7 +490,7 @@ class ComponentbuilderModelField extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('field.edit.state', 'com_componentbuilder'); } @@ -1076,14 +1085,14 @@ class ComponentbuilderModelField extends AdminModel $typephp[$x] = $input->get('property_type_php' . $x, null, 'RAW'); } // make sure we have an array - if (ComponentbuilderHelper::checkArray($properties)) + if (UtilitiesArrayHelper::check($properties)) { // set the bucket $bucket = array(); foreach($properties as $property) { // make sure we have the correct values - if (ComponentbuilderHelper::checkArray($property) && isset($property['name']) && ComponentbuilderHelper::checkString($property['name']) && (isset($property['value']) || 'default' === $property['name'])) + if (UtilitiesArrayHelper::check($property) && isset($property['name']) && UtilitiesStringHelper::check($property['name']) && (isset($property['value']) || 'default' === $property['name'])) { // some fixes, just in case (more can be added) switch ($property['name']) @@ -1097,11 +1106,11 @@ class ComponentbuilderModelField extends AdminModel } else { - $property['value'] = ComponentbuilderHelper::safeFieldName($property['value']); + $property['value'] = FieldHelper::safe($property['value']); } break; case 'type': - $property['value'] = ComponentbuilderHelper::safeTypeName($property['value']); + $property['value'] = TypeHelper::safe($property['value']); break; } // load the property @@ -1109,15 +1118,15 @@ class ComponentbuilderModelField extends AdminModel } } // make sure we have an array - if (ComponentbuilderHelper::checkArray($extraproperties)) + if (UtilitiesArrayHelper::check($extraproperties)) { foreach($extraproperties as $xproperty) { // make sure we have the correct values - if (ComponentbuilderHelper::checkArray($xproperty) && isset($xproperty['name']) && ComponentbuilderHelper::checkString($xproperty['name']) && isset($xproperty['value'])) + if (UtilitiesArrayHelper::check($xproperty) && isset($xproperty['name']) && UtilitiesStringHelper::check($xproperty['name']) && isset($xproperty['value'])) { // load the extra property - $bucket[] = "\t" . ComponentbuilderHelper::safeString($xproperty['name']) . '="' . str_replace('"', """, $xproperty['value']) . '"'; + $bucket[] = "\t" . UtilitiesStringHelper::safe($xproperty['name']) . '="' . str_replace('"', """, $xproperty['value']) . '"'; } } } @@ -1125,14 +1134,14 @@ class ComponentbuilderModelField extends AdminModel foreach ($typephp as $x => $phpvalue) { // make sure we have a string - if (ComponentbuilderHelper::checkString($phpvalue)) + if (UtilitiesStringHelper::check($phpvalue)) { // load the type_php property $bucket[] = "\t" . 'type_php' . $x . '_1="__.o0=base64=Oo.__' . base64_encode($phpvalue) . '"'; } } // if the bucket has been loaded - if (ComponentbuilderHelper::checkArray($bucket)) + if (UtilitiesArrayHelper::check($bucket)) { $data['xml'] = ""; } @@ -1142,15 +1151,15 @@ class ComponentbuilderModelField extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('field', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('field', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "field", $data['id'])) + while (!GuidHelper::valid($data['guid'], "field", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the xml string to JSON string. if (isset($data['xml'])) @@ -1158,12 +1167,6 @@ class ComponentbuilderModelField extends AdminModel $data['xml'] = (string) json_encode($data['xml']); } - // Set the on_get_model_field string to base64 string. - if (isset($data['on_get_model_field'])) - { - $data['on_get_model_field'] = base64_encode($data['on_get_model_field']); - } - // Set the on_save_model_field string to base64 string. if (isset($data['on_save_model_field'])) { @@ -1176,16 +1179,10 @@ class ComponentbuilderModelField extends AdminModel $data['initiator_on_get_model'] = base64_encode($data['initiator_on_get_model']); } - // Set the css_view string to base64 string. - if (isset($data['css_view'])) + // Set the initiator_on_save_model string to base64 string. + if (isset($data['initiator_on_save_model'])) { - $data['css_view'] = base64_encode($data['css_view']); - } - - // Set the javascript_view_footer string to base64 string. - if (isset($data['javascript_view_footer'])) - { - $data['javascript_view_footer'] = base64_encode($data['javascript_view_footer']); + $data['initiator_on_save_model'] = base64_encode($data['initiator_on_save_model']); } // Set the css_views string to base64 string. @@ -1194,17 +1191,29 @@ class ComponentbuilderModelField extends AdminModel $data['css_views'] = base64_encode($data['css_views']); } + // Set the css_view string to base64 string. + if (isset($data['css_view'])) + { + $data['css_view'] = base64_encode($data['css_view']); + } + + // Set the on_get_model_field string to base64 string. + if (isset($data['on_get_model_field'])) + { + $data['on_get_model_field'] = base64_encode($data['on_get_model_field']); + } + + // Set the javascript_view_footer string to base64 string. + if (isset($data['javascript_view_footer'])) + { + $data['javascript_view_footer'] = base64_encode($data['javascript_view_footer']); + } + // Set the javascript_views_footer string to base64 string. if (isset($data['javascript_views_footer'])) { $data['javascript_views_footer'] = base64_encode($data['javascript_views_footer']); } - - // Set the initiator_on_save_model string to base64 string. - if (isset($data['initiator_on_save_model'])) - { - $data['initiator_on_save_model'] = base64_encode($data['initiator_on_save_model']); - } // Set the Params Items to data if (isset($data['params']) && is_array($data['params'])) diff --git a/admin/models/fields.php b/admin/models/fields.php index 36c670a60..c65e79af5 100644 --- a/admin/models/fields.php +++ b/admin/models/fields.php @@ -14,6 +14,9 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; /** * Fields List Model @@ -63,7 +66,7 @@ class ComponentbuilderModelFields extends ListModel // Create the "extension" filter $form->setField(new SimpleXMLElement( - ComponentbuilderHelper::getExtensionGroupedListXml() + JCBFilterHelper::extensions() ),'filter'); $form->setValue( 'extension', @@ -82,7 +85,7 @@ class ComponentbuilderModelFields extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_ADMIN_VIEWS_FOUND') . ' -' ); // check if we have admin views (and limit to an extension if it is set) - if (($admin_views = ComponentbuilderHelper::getByTypeTheIdsSystemNames('admin_view', $this->state->get("filter.extension"))) !== false) + if (($admin_views = JCBFilterHelper::names('admin_view', $this->state->get("filter.extension"))) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_ADMIN_VIEW') . ' -' @@ -91,7 +94,7 @@ class ComponentbuilderModelFields extends ListModel $options = $options + $admin_views; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'admin_view', 'filter', @@ -100,7 +103,8 @@ class ComponentbuilderModelFields extends ListModel array_push($this->filter_fields, 'admin_view'); return $form; - } + } + /** * Method to auto-populate the model state. @@ -379,7 +383,7 @@ class ComponentbuilderModelFields extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::linked((int) $type_extension[1], (string) $type_extension[0])) !== null) { $field_ids = $ids; } @@ -395,7 +399,7 @@ class ComponentbuilderModelFields extends ListModel $filter_admin_view = $this->state->get("filter.admin_view"); if ($get_ids && $filter_admin_view !== null && !empty($filter_admin_view)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_admin_view, 'admin_view')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_admin_view, 'admin_view')) !== null) { // view will return less fields, so we ignore the component $field_ids = $ids; @@ -408,7 +412,7 @@ class ComponentbuilderModelFields extends ListModel } } // now check if we have IDs - if ($get_ids && ComponentbuilderHelper::checkArray($field_ids)) + if ($get_ids && UtilitiesArrayHelper::check($field_ids)) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $field_ids) . ')'); } @@ -644,7 +648,7 @@ class ComponentbuilderModelFields extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::linked((int) $type_extension[1], (string) $type_extension[0])) !== null) { $field_ids = $ids; } @@ -660,7 +664,7 @@ class ComponentbuilderModelFields extends ListModel $filter_admin_view = $this->state->get("filter.admin_view"); if ($get_ids && $filter_admin_view !== null && !empty($filter_admin_view)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_admin_view, 'admin_view')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_admin_view, 'admin_view')) !== null) { // view will return less fields, so we ignore the component $field_ids = $ids; @@ -673,7 +677,7 @@ class ComponentbuilderModelFields extends ListModel } } // now check if we have IDs - if ($get_ids && ComponentbuilderHelper::checkArray($field_ids)) + if ($get_ids && UtilitiesArrayHelper::check($field_ids)) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $field_ids) . ')'); } @@ -708,22 +712,22 @@ class ComponentbuilderModelFields extends ListModel continue; } - // decode on_get_model_field - $item->on_get_model_field = base64_decode($item->on_get_model_field); // decode on_save_model_field $item->on_save_model_field = base64_decode($item->on_save_model_field); // decode initiator_on_get_model $item->initiator_on_get_model = base64_decode($item->initiator_on_get_model); - // decode css_view - $item->css_view = base64_decode($item->css_view); - // decode javascript_view_footer - $item->javascript_view_footer = base64_decode($item->javascript_view_footer); - // decode css_views - $item->css_views = base64_decode($item->css_views); - // decode javascript_views_footer - $item->javascript_views_footer = base64_decode($item->javascript_views_footer); // decode initiator_on_save_model $item->initiator_on_save_model = base64_decode($item->initiator_on_save_model); + // decode css_views + $item->css_views = base64_decode($item->css_views); + // decode css_view + $item->css_view = base64_decode($item->css_view); + // decode on_get_model_field + $item->on_get_model_field = base64_decode($item->on_get_model_field); + // decode javascript_view_footer + $item->javascript_view_footer = base64_decode($item->javascript_view_footer); + // decode javascript_views_footer + $item->javascript_views_footer = base64_decode($item->javascript_views_footer); // unset the values we don't want exported. unset($item->asset_id); unset($item->checked_out); diff --git a/admin/models/fields/adminlistvieworderfields.php b/admin/models/fields/adminlistvieworderfields.php index c8618cd71..8dc7f43f1 100644 --- a/admin/models/fields/adminlistvieworderfields.php +++ b/admin/models/fields/adminlistvieworderfields.php @@ -120,8 +120,17 @@ class JFormFieldAdminlistvieworderfields extends JFormFieldList foreach($items as $item) { // get the field name (TODO this could slow down the system so we will need to improve on this) - $field_name = ComponentbuilderHelper::safeFieldName(ComponentbuilderHelper::getBetween(json_decode($item->xml),'name="','"')); - $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + if (isset($item->xml) && ComponentbuilderHelper::checkJson($item->xml)) + { + $field_xml = json_decode($item->xml); + $field_name = ComponentbuilderHelper::getBetween($field_xml,'name="','"'); + $field_name = ComponentbuilderHelper::safeFieldName($field_name); + $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + } + else + { + $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ empty - ' . $item->type . ' ]'); + } } } return $options; diff --git a/admin/models/fields/adminviewsfilteraddcustombutton.php b/admin/models/fields/adminviewsfilteraddcustombutton.php index 7f226d74d..641ab9c6a 100644 --- a/admin/models/fields/adminviewsfilteraddcustombutton.php +++ b/admin/models/fields/adminviewsfilteraddcustombutton.php @@ -49,21 +49,21 @@ class JFormFieldAdminviewsfilteraddcustombutton extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_CUSTOM_BUTTONS') . ' -'); - if ($results) + if ($_results) { // get admin_viewsmodel - $model = ComponentbuilderHelper::getModel('admin_views'); - $results = array_unique($results); - foreach ($results as $add_custom_button) + $_model = ComponentbuilderHelper::getModel('admin_views'); + $_results = array_unique($_results); + foreach ($_results as $add_custom_button) { // Translate the add_custom_button selection - $text = $model->selectionTranslation($add_custom_button,'add_custom_button'); + $_text = $_model->selectionTranslation($add_custom_button,'add_custom_button'); // Now add the add_custom_button and its text to the options array - $_filter[] = JHtml::_('select.option', $add_custom_button, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_custom_button, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/adminviewsfilteraddcustomimport.php b/admin/models/fields/adminviewsfilteraddcustomimport.php index d3deaa8b1..30a7adfa1 100644 --- a/admin/models/fields/adminviewsfilteraddcustomimport.php +++ b/admin/models/fields/adminviewsfilteraddcustomimport.php @@ -49,21 +49,21 @@ class JFormFieldAdminviewsfilteraddcustomimport extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_CUSTOM_IMPORT') . ' -'); - if ($results) + if ($_results) { // get admin_viewsmodel - $model = ComponentbuilderHelper::getModel('admin_views'); - $results = array_unique($results); - foreach ($results as $add_custom_import) + $_model = ComponentbuilderHelper::getModel('admin_views'); + $_results = array_unique($_results); + foreach ($_results as $add_custom_import) { // Translate the add_custom_import selection - $text = $model->selectionTranslation($add_custom_import,'add_custom_import'); + $_text = $_model->selectionTranslation($add_custom_import,'add_custom_import'); // Now add the add_custom_import and its text to the options array - $_filter[] = JHtml::_('select.option', $add_custom_import, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_custom_import, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/adminviewsfilteraddfadein.php b/admin/models/fields/adminviewsfilteraddfadein.php index 61dd5f4d0..5e1e42671 100644 --- a/admin/models/fields/adminviewsfilteraddfadein.php +++ b/admin/models/fields/adminviewsfilteraddfadein.php @@ -49,21 +49,21 @@ class JFormFieldAdminviewsfilteraddfadein extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_FADE_IN_AFFECT') . ' -'); - if ($results) + if ($_results) { // get admin_viewsmodel - $model = ComponentbuilderHelper::getModel('admin_views'); - $results = array_unique($results); - foreach ($results as $add_fadein) + $_model = ComponentbuilderHelper::getModel('admin_views'); + $_results = array_unique($_results); + foreach ($_results as $add_fadein) { // Translate the add_fadein selection - $text = $model->selectionTranslation($add_fadein,'add_fadein'); + $_text = $_model->selectionTranslation($add_fadein,'add_fadein'); // Now add the add_fadein and its text to the options array - $_filter[] = JHtml::_('select.option', $add_fadein, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_fadein, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/adminviewsfilteraddphpajax.php b/admin/models/fields/adminviewsfilteraddphpajax.php index 62eb83995..ab57b2afa 100644 --- a/admin/models/fields/adminviewsfilteraddphpajax.php +++ b/admin/models/fields/adminviewsfilteraddphpajax.php @@ -49,21 +49,21 @@ class JFormFieldAdminviewsfilteraddphpajax extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_PHP_AJAX') . ' -'); - if ($results) + if ($_results) { // get admin_viewsmodel - $model = ComponentbuilderHelper::getModel('admin_views'); - $results = array_unique($results); - foreach ($results as $add_php_ajax) + $_model = ComponentbuilderHelper::getModel('admin_views'); + $_results = array_unique($_results); + foreach ($_results as $add_php_ajax) { // Translate the add_php_ajax selection - $text = $model->selectionTranslation($add_php_ajax,'add_php_ajax'); + $_text = $_model->selectionTranslation($add_php_ajax,'add_php_ajax'); // Now add the add_php_ajax and its text to the options array - $_filter[] = JHtml::_('select.option', $add_php_ajax, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_php_ajax, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/adminviewsfiltertype.php b/admin/models/fields/adminviewsfiltertype.php index b2dc7cba7..4fc3390b4 100644 --- a/admin/models/fields/adminviewsfiltertype.php +++ b/admin/models/fields/adminviewsfiltertype.php @@ -49,20 +49,20 @@ class JFormFieldAdminviewsfiltertype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); - if ($results) + if ($_results) { // get admin_viewsmodel - $model = ComponentbuilderHelper::getModel('admin_views'); - $results = array_unique($results); - foreach ($results as $type) + $_model = ComponentbuilderHelper::getModel('admin_views'); + $_results = array_unique($_results); + foreach ($_results as $type) { // Translate the type selection - $text = $model->selectionTranslation($type,'type'); + $_text = $_model->selectionTranslation($type,'type'); // Now add the type and its text to the options array - $_filter[] = JHtml::_('select.option', $type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/classextendingsfilterextensiontype.php b/admin/models/fields/classextendingsfilterextensiontype.php index 11d98adab..b1b5ee8a3 100644 --- a/admin/models/fields/classextendingsfilterextensiontype.php +++ b/admin/models/fields/classextendingsfilterextensiontype.php @@ -49,21 +49,21 @@ class JFormFieldClassextendingsfilterextensiontype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TYPE') . ' -'); - if ($results) + if ($_results) { // get class_extendingsmodel - $model = ComponentbuilderHelper::getModel('class_extendings'); - $results = array_unique($results); - foreach ($results as $extension_type) + $_model = ComponentbuilderHelper::getModel('class_extendings'); + $_results = array_unique($_results); + foreach ($_results as $extension_type) { // Translate the extension_type selection - $text = $model->selectionTranslation($extension_type,'extension_type'); + $_text = $_model->selectionTranslation($extension_type,'extension_type'); // Now add the extension_type and its text to the options array - $_filter[] = JHtml::_('select.option', $extension_type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $extension_type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/classmethodsfilterextensiontype.php b/admin/models/fields/classmethodsfilterextensiontype.php index ebc580b3a..dee3ff2e7 100644 --- a/admin/models/fields/classmethodsfilterextensiontype.php +++ b/admin/models/fields/classmethodsfilterextensiontype.php @@ -49,21 +49,21 @@ class JFormFieldClassmethodsfilterextensiontype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TYPE') . ' -'); - if ($results) + if ($_results) { // get class_methodsmodel - $model = ComponentbuilderHelper::getModel('class_methods'); - $results = array_unique($results); - foreach ($results as $extension_type) + $_model = ComponentbuilderHelper::getModel('class_methods'); + $_results = array_unique($_results); + foreach ($_results as $extension_type) { // Translate the extension_type selection - $text = $model->selectionTranslation($extension_type,'extension_type'); + $_text = $_model->selectionTranslation($extension_type,'extension_type'); // Now add the extension_type and its text to the options array - $_filter[] = JHtml::_('select.option', $extension_type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $extension_type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/classmethodsfiltervisibility.php b/admin/models/fields/classmethodsfiltervisibility.php index ee4297369..34e3f4377 100644 --- a/admin/models/fields/classmethodsfiltervisibility.php +++ b/admin/models/fields/classmethodsfiltervisibility.php @@ -49,21 +49,21 @@ class JFormFieldClassmethodsfiltervisibility extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_VISIBILITY') . ' -'); - if ($results) + if ($_results) { // get class_methodsmodel - $model = ComponentbuilderHelper::getModel('class_methods'); - $results = array_unique($results); - foreach ($results as $visibility) + $_model = ComponentbuilderHelper::getModel('class_methods'); + $_results = array_unique($_results); + foreach ($_results as $visibility) { // Translate the visibility selection - $text = $model->selectionTranslation($visibility,'visibility'); + $_text = $_model->selectionTranslation($visibility,'visibility'); // Now add the visibility and its text to the options array - $_filter[] = JHtml::_('select.option', $visibility, JText::_($text)); + $_filter[] = JHtml::_('select.option', $visibility, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/classpropertiesfilterextensiontype.php b/admin/models/fields/classpropertiesfilterextensiontype.php index 5acb6d3e1..f06d37be2 100644 --- a/admin/models/fields/classpropertiesfilterextensiontype.php +++ b/admin/models/fields/classpropertiesfilterextensiontype.php @@ -49,21 +49,21 @@ class JFormFieldClasspropertiesfilterextensiontype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TYPE') . ' -'); - if ($results) + if ($_results) { // get class_propertiesmodel - $model = ComponentbuilderHelper::getModel('class_properties'); - $results = array_unique($results); - foreach ($results as $extension_type) + $_model = ComponentbuilderHelper::getModel('class_properties'); + $_results = array_unique($_results); + foreach ($_results as $extension_type) { // Translate the extension_type selection - $text = $model->selectionTranslation($extension_type,'extension_type'); + $_text = $_model->selectionTranslation($extension_type,'extension_type'); // Now add the extension_type and its text to the options array - $_filter[] = JHtml::_('select.option', $extension_type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $extension_type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/classpropertiesfiltervisibility.php b/admin/models/fields/classpropertiesfiltervisibility.php index 927d33413..ef1f4d5af 100644 --- a/admin/models/fields/classpropertiesfiltervisibility.php +++ b/admin/models/fields/classpropertiesfiltervisibility.php @@ -49,21 +49,21 @@ class JFormFieldClasspropertiesfiltervisibility extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_VISIBILITY') . ' -'); - if ($results) + if ($_results) { // get class_propertiesmodel - $model = ComponentbuilderHelper::getModel('class_properties'); - $results = array_unique($results); - foreach ($results as $visibility) + $_model = ComponentbuilderHelper::getModel('class_properties'); + $_results = array_unique($_results); + foreach ($_results as $visibility) { // Translate the visibility selection - $text = $model->selectionTranslation($visibility,'visibility'); + $_text = $_model->selectionTranslation($visibility,'visibility'); // Now add the visibility and its text to the options array - $_filter[] = JHtml::_('select.option', $visibility, JText::_($text)); + $_filter[] = JHtml::_('select.option', $visibility, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/customadminviewsfilteraddcustombutton.php b/admin/models/fields/customadminviewsfilteraddcustombutton.php index 13a94b21e..d784bae20 100644 --- a/admin/models/fields/customadminviewsfilteraddcustombutton.php +++ b/admin/models/fields/customadminviewsfilteraddcustombutton.php @@ -49,21 +49,21 @@ class JFormFieldCustomadminviewsfilteraddcustombutton extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_CUSTOM_BUTTONS') . ' -'); - if ($results) + if ($_results) { // get custom_admin_viewsmodel - $model = ComponentbuilderHelper::getModel('custom_admin_views'); - $results = array_unique($results); - foreach ($results as $add_custom_button) + $_model = ComponentbuilderHelper::getModel('custom_admin_views'); + $_results = array_unique($_results); + foreach ($_results as $add_custom_button) { // Translate the add_custom_button selection - $text = $model->selectionTranslation($add_custom_button,'add_custom_button'); + $_text = $_model->selectionTranslation($add_custom_button,'add_custom_button'); // Now add the add_custom_button and its text to the options array - $_filter[] = JHtml::_('select.option', $add_custom_button, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_custom_button, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/customadminviewsfilteraddphpajax.php b/admin/models/fields/customadminviewsfilteraddphpajax.php index 0756975bd..2ed8d2607 100644 --- a/admin/models/fields/customadminviewsfilteraddphpajax.php +++ b/admin/models/fields/customadminviewsfilteraddphpajax.php @@ -49,21 +49,21 @@ class JFormFieldCustomadminviewsfilteraddphpajax extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_PHP_AJAX') . ' -'); - if ($results) + if ($_results) { // get custom_admin_viewsmodel - $model = ComponentbuilderHelper::getModel('custom_admin_views'); - $results = array_unique($results); - foreach ($results as $add_php_ajax) + $_model = ComponentbuilderHelper::getModel('custom_admin_views'); + $_results = array_unique($_results); + foreach ($_results as $add_php_ajax) { // Translate the add_php_ajax selection - $text = $model->selectionTranslation($add_php_ajax,'add_php_ajax'); + $_text = $_model->selectionTranslation($add_php_ajax,'add_php_ajax'); // Now add the add_php_ajax and its text to the options array - $_filter[] = JHtml::_('select.option', $add_php_ajax, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_php_ajax, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/customcodesfiltercommenttype.php b/admin/models/fields/customcodesfiltercommenttype.php index d56f38e99..a184601d5 100644 --- a/admin/models/fields/customcodesfiltercommenttype.php +++ b/admin/models/fields/customcodesfiltercommenttype.php @@ -49,21 +49,21 @@ class JFormFieldCustomcodesfiltercommenttype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_COMMENT_TYPE_USED_IN_PLACEHOLDER') . ' -'); - if ($results) + if ($_results) { // get custom_codesmodel - $model = ComponentbuilderHelper::getModel('custom_codes'); - $results = array_unique($results); - foreach ($results as $comment_type) + $_model = ComponentbuilderHelper::getModel('custom_codes'); + $_results = array_unique($_results); + foreach ($_results as $comment_type) { // Translate the comment_type selection - $text = $model->selectionTranslation($comment_type,'comment_type'); + $_text = $_model->selectionTranslation($comment_type,'comment_type'); // Now add the comment_type and its text to the options array - $_filter[] = JHtml::_('select.option', $comment_type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $comment_type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/customcodesfiltertarget.php b/admin/models/fields/customcodesfiltertarget.php index 2789fe560..6d0b300b1 100644 --- a/admin/models/fields/customcodesfiltertarget.php +++ b/admin/models/fields/customcodesfiltertarget.php @@ -49,21 +49,21 @@ class JFormFieldCustomcodesfiltertarget extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TARGET') . ' -'); - if ($results) + if ($_results) { // get custom_codesmodel - $model = ComponentbuilderHelper::getModel('custom_codes'); - $results = array_unique($results); - foreach ($results as $target) + $_model = ComponentbuilderHelper::getModel('custom_codes'); + $_results = array_unique($_results); + foreach ($_results as $target) { // Translate the target selection - $text = $model->selectionTranslation($target,'target'); + $_text = $_model->selectionTranslation($target,'target'); // Now add the target and its text to the options array - $_filter[] = JHtml::_('select.option', $target, JText::_($text)); + $_filter[] = JHtml::_('select.option', $target, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/customcodesfiltertype.php b/admin/models/fields/customcodesfiltertype.php index 205711ea0..6706346d0 100644 --- a/admin/models/fields/customcodesfiltertype.php +++ b/admin/models/fields/customcodesfiltertype.php @@ -49,21 +49,21 @@ class JFormFieldCustomcodesfiltertype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_TYPE') . ' -'); - if ($results) + if ($_results) { // get custom_codesmodel - $model = ComponentbuilderHelper::getModel('custom_codes'); - $results = array_unique($results); - foreach ($results as $type) + $_model = ComponentbuilderHelper::getModel('custom_codes'); + $_results = array_unique($_results); + foreach ($_results as $type) { // Translate the type selection - $text = $model->selectionTranslation($type,'type'); + $_text = $_model->selectionTranslation($type,'type'); // Now add the type and its text to the options array - $_filter[] = JHtml::_('select.option', $type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/dynamicgetsfiltergettype.php b/admin/models/fields/dynamicgetsfiltergettype.php index 77ddc0e71..2173564cd 100644 --- a/admin/models/fields/dynamicgetsfiltergettype.php +++ b/admin/models/fields/dynamicgetsfiltergettype.php @@ -49,21 +49,21 @@ class JFormFieldDynamicgetsfiltergettype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_GETTYPE') . ' -'); - if ($results) + if ($_results) { // get dynamic_getsmodel - $model = ComponentbuilderHelper::getModel('dynamic_gets'); - $results = array_unique($results); - foreach ($results as $gettype) + $_model = ComponentbuilderHelper::getModel('dynamic_gets'); + $_results = array_unique($_results); + foreach ($_results as $gettype) { // Translate the gettype selection - $text = $model->selectionTranslation($gettype,'gettype'); + $_text = $_model->selectionTranslation($gettype,'gettype'); // Now add the gettype and its text to the options array - $_filter[] = JHtml::_('select.option', $gettype, JText::_($text)); + $_filter[] = JHtml::_('select.option', $gettype, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/dynamicgetsfiltermainsource.php b/admin/models/fields/dynamicgetsfiltermainsource.php index 97f27ae89..621b8db5a 100644 --- a/admin/models/fields/dynamicgetsfiltermainsource.php +++ b/admin/models/fields/dynamicgetsfiltermainsource.php @@ -49,21 +49,21 @@ class JFormFieldDynamicgetsfiltermainsource extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_MAIN_SOURCE') . ' -'); - if ($results) + if ($_results) { // get dynamic_getsmodel - $model = ComponentbuilderHelper::getModel('dynamic_gets'); - $results = array_unique($results); - foreach ($results as $main_source) + $_model = ComponentbuilderHelper::getModel('dynamic_gets'); + $_results = array_unique($_results); + foreach ($_results as $main_source) { // Translate the main_source selection - $text = $model->selectionTranslation($main_source,'main_source'); + $_text = $_model->selectionTranslation($main_source,'main_source'); // Now add the main_source and its text to the options array - $_filter[] = JHtml::_('select.option', $main_source, JText::_($text)); + $_filter[] = JHtml::_('select.option', $main_source, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/fields.php b/admin/models/fields/fields.php index 95ce61061..17d8b5ca6 100644 --- a/admin/models/fields/fields.php +++ b/admin/models/fields/fields.php @@ -51,8 +51,17 @@ class JFormFieldFields extends JFormFieldList foreach($items as $item) { // get the field name (TODO this could slow down the system so we will need to improve on this) - $field_name = ComponentbuilderHelper::safeFieldName(ComponentbuilderHelper::getBetween(json_decode($item->xml),'name="','"')); - $options[] = JHtml::_('select.option', $item->id, $item->field_name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + if (isset($item->xml) && ComponentbuilderHelper::checkJson($item->xml)) + { + $field_xml = json_decode($item->xml); + $field_name = ComponentbuilderHelper::getBetween($field_xml,'name="','"'); + $field_name = ComponentbuilderHelper::safeFieldName($field_name); + $options[] = JHtml::_('select.option', $item->id, $item->field_name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + } + else + { + $options[] = JHtml::_('select.option', $item->id, $item->field_name . ' [ empty - ' . $item->type . ' ]'); + } } } diff --git a/admin/models/fields/fieldsfilterdatatype.php b/admin/models/fields/fieldsfilterdatatype.php index ad7adc9fb..cd4192e54 100644 --- a/admin/models/fields/fieldsfilterdatatype.php +++ b/admin/models/fields/fieldsfilterdatatype.php @@ -49,21 +49,21 @@ class JFormFieldFieldsfilterdatatype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_DATA_TYPE') . ' -'); - if ($results) + if ($_results) { // get fieldsmodel - $model = ComponentbuilderHelper::getModel('fields'); - $results = array_unique($results); - foreach ($results as $datatype) + $_model = ComponentbuilderHelper::getModel('fields'); + $_results = array_unique($_results); + foreach ($_results as $datatype) { // Translate the datatype selection - $text = $model->selectionTranslation($datatype,'datatype'); + $_text = $_model->selectionTranslation($datatype,'datatype'); // Now add the datatype and its text to the options array - $_filter[] = JHtml::_('select.option', $datatype, JText::_($text)); + $_filter[] = JHtml::_('select.option', $datatype, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/fieldsfilterindexes.php b/admin/models/fields/fieldsfilterindexes.php index e5ea7543f..fc84a5a62 100644 --- a/admin/models/fields/fieldsfilterindexes.php +++ b/admin/models/fields/fieldsfilterindexes.php @@ -49,21 +49,21 @@ class JFormFieldFieldsfilterindexes extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_INDEXES_TYPE') . ' -'); - if ($results) + if ($_results) { // get fieldsmodel - $model = ComponentbuilderHelper::getModel('fields'); - $results = array_unique($results); - foreach ($results as $indexes) + $_model = ComponentbuilderHelper::getModel('fields'); + $_results = array_unique($_results); + foreach ($_results as $indexes) { // Translate the indexes selection - $text = $model->selectionTranslation($indexes,'indexes'); + $_text = $_model->selectionTranslation($indexes,'indexes'); // Now add the indexes and its text to the options array - $_filter[] = JHtml::_('select.option', $indexes, JText::_($text)); + $_filter[] = JHtml::_('select.option', $indexes, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/fieldsfilternullswitch.php b/admin/models/fields/fieldsfilternullswitch.php index 34eaa5fe5..6444ec9bc 100644 --- a/admin/models/fields/fieldsfilternullswitch.php +++ b/admin/models/fields/fieldsfilternullswitch.php @@ -49,21 +49,21 @@ class JFormFieldFieldsfilternullswitch extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_NULL_SWITCH') . ' -'); - if ($results) + if ($_results) { // get fieldsmodel - $model = ComponentbuilderHelper::getModel('fields'); - $results = array_unique($results); - foreach ($results as $null_switch) + $_model = ComponentbuilderHelper::getModel('fields'); + $_results = array_unique($_results); + foreach ($_results as $null_switch) { // Translate the null_switch selection - $text = $model->selectionTranslation($null_switch,'null_switch'); + $_text = $_model->selectionTranslation($null_switch,'null_switch'); // Now add the null_switch and its text to the options array - $_filter[] = JHtml::_('select.option', $null_switch, JText::_($text)); + $_filter[] = JHtml::_('select.option', $null_switch, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/fieldsfilterstore.php b/admin/models/fields/fieldsfilterstore.php index 41b975d50..1946f185e 100644 --- a/admin/models/fields/fieldsfilterstore.php +++ b/admin/models/fields/fieldsfilterstore.php @@ -49,21 +49,21 @@ class JFormFieldFieldsfilterstore extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); - $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_MODELING_METHOD') . ' -'); + $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_MODELLING_METHOD') . ' -'); - if ($results) + if ($_results) { // get fieldsmodel - $model = ComponentbuilderHelper::getModel('fields'); - $results = array_unique($results); - foreach ($results as $store) + $_model = ComponentbuilderHelper::getModel('fields'); + $_results = array_unique($_results); + foreach ($_results as $store) { // Translate the store selection - $text = $model->selectionTranslation($store,'store'); + $_text = $_model->selectionTranslation($store,'store'); // Now add the store and its text to the options array - $_filter[] = JHtml::_('select.option', $store, JText::_($text)); + $_filter[] = JHtml::_('select.option', $store, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/helpdocumentsfilterlocation.php b/admin/models/fields/helpdocumentsfilterlocation.php index 57acba003..a9f317ff1 100644 --- a/admin/models/fields/helpdocumentsfilterlocation.php +++ b/admin/models/fields/helpdocumentsfilterlocation.php @@ -49,21 +49,21 @@ class JFormFieldHelpdocumentsfilterlocation extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_LOCATION') . ' -'); - if ($results) + if ($_results) { // get help_documentsmodel - $model = ComponentbuilderHelper::getModel('help_documents'); - $results = array_unique($results); - foreach ($results as $location) + $_model = ComponentbuilderHelper::getModel('help_documents'); + $_results = array_unique($_results); + foreach ($_results as $location) { // Translate the location selection - $text = $model->selectionTranslation($location,'location'); + $_text = $_model->selectionTranslation($location,'location'); // Now add the location and its text to the options array - $_filter[] = JHtml::_('select.option', $location, JText::_($text)); + $_filter[] = JHtml::_('select.option', $location, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/helpdocumentsfiltertype.php b/admin/models/fields/helpdocumentsfiltertype.php index 7e9f5b9ea..0650900b7 100644 --- a/admin/models/fields/helpdocumentsfiltertype.php +++ b/admin/models/fields/helpdocumentsfiltertype.php @@ -49,21 +49,21 @@ class JFormFieldHelpdocumentsfiltertype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TYPE') . ' -'); - if ($results) + if ($_results) { // get help_documentsmodel - $model = ComponentbuilderHelper::getModel('help_documents'); - $results = array_unique($results); - foreach ($results as $type) + $_model = ComponentbuilderHelper::getModel('help_documents'); + $_results = array_unique($_results); + foreach ($_results as $type) { // Translate the type selection - $text = $model->selectionTranslation($type,'type'); + $_text = $_model->selectionTranslation($type,'type'); // Now add the type and its text to the options array - $_filter[] = JHtml::_('select.option', $type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/joomlacomponentsfilterauthor.php b/admin/models/fields/joomlacomponentsfilterauthor.php index 6931bc349..5dcc3c6f0 100644 --- a/admin/models/fields/joomlacomponentsfilterauthor.php +++ b/admin/models/fields/joomlacomponentsfilterauthor.php @@ -49,13 +49,13 @@ class JFormFieldJoomlacomponentsfilterauthor extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); - if ($results) + if ($_results) { - $results = array_unique($results); - foreach ($results as $author) + $_results = array_unique($_results); + foreach ($_results as $author) { // Now add the author and its text to the options array $_filter[] = JHtml::_('select.option', $author, $author); diff --git a/admin/models/fields/joomlacomponentsfiltercompanyname.php b/admin/models/fields/joomlacomponentsfiltercompanyname.php index 1b7c3feef..40fc78601 100644 --- a/admin/models/fields/joomlacomponentsfiltercompanyname.php +++ b/admin/models/fields/joomlacomponentsfiltercompanyname.php @@ -49,13 +49,13 @@ class JFormFieldJoomlacomponentsfiltercompanyname extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); - if ($results) + if ($_results) { - $results = array_unique($results); - foreach ($results as $companyname) + $_results = array_unique($_results); + foreach ($_results as $companyname) { // Now add the companyname and its text to the options array $_filter[] = JHtml::_('select.option', $companyname, $companyname); diff --git a/admin/models/fields/joomlamodulesfiltertarget.php b/admin/models/fields/joomlamodulesfiltertarget.php index b6c2167ae..b59d4bad4 100644 --- a/admin/models/fields/joomlamodulesfiltertarget.php +++ b/admin/models/fields/joomlamodulesfiltertarget.php @@ -49,21 +49,21 @@ class JFormFieldJoomlamodulesfiltertarget extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TARGET_AREA') . ' -'); - if ($results) + if ($_results) { // get joomla_modulesmodel - $model = ComponentbuilderHelper::getModel('joomla_modules'); - $results = array_unique($results); - foreach ($results as $target) + $_model = ComponentbuilderHelper::getModel('joomla_modules'); + $_results = array_unique($_results); + foreach ($_results as $target) { // Translate the target selection - $text = $model->selectionTranslation($target,'target'); + $_text = $_model->selectionTranslation($target,'target'); // Now add the target and its text to the options array - $_filter[] = JHtml::_('select.option', $target, JText::_($text)); + $_filter[] = JHtml::_('select.option', $target, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/layoutsfilteraddphpview.php b/admin/models/fields/layoutsfilteraddphpview.php index ce34d99c1..6e2a6c52d 100644 --- a/admin/models/fields/layoutsfilteraddphpview.php +++ b/admin/models/fields/layoutsfilteraddphpview.php @@ -49,21 +49,21 @@ class JFormFieldLayoutsfilteraddphpview extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_PHP_CUSTOM_VIEW_SCRIPT') . ' -'); - if ($results) + if ($_results) { // get layoutsmodel - $model = ComponentbuilderHelper::getModel('layouts'); - $results = array_unique($results); - foreach ($results as $add_php_view) + $_model = ComponentbuilderHelper::getModel('layouts'); + $_results = array_unique($_results); + foreach ($_results as $add_php_view) { // Translate the add_php_view selection - $text = $model->selectionTranslation($add_php_view,'add_php_view'); + $_text = $_model->selectionTranslation($add_php_view,'add_php_view'); // Now add the add_php_view and its text to the options array - $_filter[] = JHtml::_('select.option', $add_php_view, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_php_view, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/librariesfiltertarget.php b/admin/models/fields/librariesfiltertarget.php index 81483e192..952247dd1 100644 --- a/admin/models/fields/librariesfiltertarget.php +++ b/admin/models/fields/librariesfiltertarget.php @@ -49,21 +49,21 @@ class JFormFieldLibrariesfiltertarget extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TARGET_FOLDER') . ' -'); - if ($results) + if ($_results) { // get librariesmodel - $model = ComponentbuilderHelper::getModel('libraries'); - $results = array_unique($results); - foreach ($results as $target) + $_model = ComponentbuilderHelper::getModel('libraries'); + $_results = array_unique($_results); + foreach ($_results as $target) { // Translate the target selection - $text = $model->selectionTranslation($target,'target'); + $_text = $_model->selectionTranslation($target,'target'); // Now add the target and its text to the options array - $_filter[] = JHtml::_('select.option', $target, JText::_($text)); + $_filter[] = JHtml::_('select.option', $target, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/librariesfiltertype.php b/admin/models/fields/librariesfiltertype.php index d522a9ce5..f7f09b10d 100644 --- a/admin/models/fields/librariesfiltertype.php +++ b/admin/models/fields/librariesfiltertype.php @@ -49,21 +49,21 @@ class JFormFieldLibrariesfiltertype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_TYPE_BEHAVIOR') . ' -'); - if ($results) + if ($_results) { // get librariesmodel - $model = ComponentbuilderHelper::getModel('libraries'); - $results = array_unique($results); - foreach ($results as $type) + $_model = ComponentbuilderHelper::getModel('libraries'); + $_results = array_unique($_results); + foreach ($_results as $type) { // Translate the type selection - $text = $model->selectionTranslation($type,'type'); + $_text = $_model->selectionTranslation($type,'type'); // Now add the type and its text to the options array - $_filter[] = JHtml::_('select.option', $type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/linkedviewsorderfields.php b/admin/models/fields/linkedviewsorderfields.php index 7cfaaa593..c4281adef 100644 --- a/admin/models/fields/linkedviewsorderfields.php +++ b/admin/models/fields/linkedviewsorderfields.php @@ -87,8 +87,17 @@ class JFormFieldLinkedviewsorderfields extends JFormFieldList foreach($items as $item) { // get the field name (TODO this could slow down the system so we will need to improve on this) - $field_name = ComponentbuilderHelper::safeFieldName(ComponentbuilderHelper::getBetween(json_decode($item->xml),'name="','"')); - $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + if (isset($item->xml) && ComponentbuilderHelper::checkJson($item->xml)) + { + $field_xml = json_decode($item->xml); + $field_name = ComponentbuilderHelper::getBetween($field_xml,'name="','"'); + $field_name = ComponentbuilderHelper::safeFieldName($field_name); + $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + } + else + { + $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ empty - ' . $item->type . ' ]'); + } } } return $options; diff --git a/admin/models/fields/listfields.php b/admin/models/fields/listfields.php index 6ae8b010b..1af1206f6 100644 --- a/admin/models/fields/listfields.php +++ b/admin/models/fields/listfields.php @@ -94,8 +94,17 @@ class JFormFieldListfields extends JFormFieldList foreach($items as $item) { // get the field name (TODO this could slow down the system so we will need to improve on this) - $field_name = ComponentbuilderHelper::safeFieldName(ComponentbuilderHelper::getBetween(json_decode($item->xml),'name="','"')); - $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + if (isset($item->xml) && ComponentbuilderHelper::checkJson($item->xml)) + { + $field_xml = json_decode($item->xml); + $field_name = ComponentbuilderHelper::getBetween($field_xml,'name="','"'); + $field_name = ComponentbuilderHelper::safeFieldName($field_name); + $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ ' . $field_name . ' - ' . $item->type . ' ]'); + } + else + { + $options[] = JHtml::_('select.option', $item->id, $item->name . ' [ empty - ' . $item->type . ' ]'); + } } } return $options; diff --git a/admin/models/fields/powersclassmethods.php b/admin/models/fields/powersclassmethods.php new file mode 100644 index 000000000..7c53806e4 --- /dev/null +++ b/admin/models/fields/powersclassmethods.php @@ -0,0 +1,81 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// import the list field type +jimport('joomla.form.helper'); +JFormHelper::loadFieldClass('list'); + +/** + * Powersclassmethods Form Field class for the Componentbuilder component + */ +class JFormFieldPowersclassmethods extends JFormFieldList +{ + /** + * The powersclassmethods field type. + * + * @var string + */ + public $type = 'powersclassmethods'; + + /** + * Method to get a list of options for a list input. + * + * @return array An array of JHtml options. + */ + protected function getOptions() + { + +// Get the user object. + $user = JFactory::getUser(); + // Get the databse object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + $query->select($db->quoteName(array('a.id','a.name','a.visibility'),array('id','method_name','visibility'))); + $query->from($db->quoteName('#__componentbuilder_class_method', 'a')); + $query->where($db->quoteName('a.published') . ' >= 1'); + $query->where($db->quoteName('a.extension_type') . ' = ' . $db->quote('powers')); + $query->order('a.name ASC'); + // Implement View Level Access (if set in table) + if (!$user->authorise('core.options', 'com_componentbuilder')) + { + $columns = $db->getTableColumns('#__componentbuilder_class_method'); + if(isset($columns['access'])) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + } + $db->setQuery((string)$query); + $items = $db->loadObjectList(); + $options = array(); + if ($items) + { + $options[] = JHtml::_('select.option', '', 'Select a method'); + foreach($items as $item) + { + // we are using this code in more then one field JCB custom_code + if ('method' === 'method') + { + $select = $item->visibility . ' function ' . $item->method_name . '()'; + } + else + { + $select = $item->visibility . ' $' . $item->method_name; + } + $options[] = JHtml::_('select.option', $item->id, $select); + } + } + return $options; + } +} diff --git a/admin/models/fields/powersclassproperties.php b/admin/models/fields/powersclassproperties.php new file mode 100644 index 000000000..501aad52b --- /dev/null +++ b/admin/models/fields/powersclassproperties.php @@ -0,0 +1,81 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// import the list field type +jimport('joomla.form.helper'); +JFormHelper::loadFieldClass('list'); + +/** + * Powersclassproperties Form Field class for the Componentbuilder component + */ +class JFormFieldPowersclassproperties extends JFormFieldList +{ + /** + * The powersclassproperties field type. + * + * @var string + */ + public $type = 'powersclassproperties'; + + /** + * Method to get a list of options for a list input. + * + * @return array An array of JHtml options. + */ + protected function getOptions() + { + +// Get the user object. + $user = JFactory::getUser(); + // Get the databse object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + $query->select($db->quoteName(array('a.id','a.name','a.visibility'),array('id','property_name','visibility'))); + $query->from($db->quoteName('#__componentbuilder_class_property', 'a')); + $query->where($db->quoteName('a.published') . ' >= 1'); + $query->where($db->quoteName('a.extension_type') . ' = ' . $db->quote('powers')); + $query->order('a.name ASC'); + // Implement View Level Access (if set in table) + if (!$user->authorise('core.options', 'com_componentbuilder')) + { + $columns = $db->getTableColumns('#__componentbuilder_class_property'); + if(isset($columns['access'])) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + } + $db->setQuery((string)$query); + $items = $db->loadObjectList(); + $options = array(); + if ($items) + { + $options[] = JHtml::_('select.option', '', 'Select a property'); + foreach($items as $item) + { + // we are using this code in more then one field JCB custom_code + if ('method' === 'property') + { + $select = $item->visibility . ' function ' . $item->property_name . '()'; + } + else + { + $select = $item->visibility . ' $' . $item->property_name; + } + $options[] = JHtml::_('select.option', $item->id, $select); + } + } + return $options; + } +} diff --git a/admin/models/fields/powersfilterpowerversion.php b/admin/models/fields/powersfilterapproved.php similarity index 59% rename from admin/models/fields/powersfilterpowerversion.php rename to admin/models/fields/powersfilterapproved.php index e594e102d..cbf3c6d18 100644 --- a/admin/models/fields/powersfilterpowerversion.php +++ b/admin/models/fields/powersfilterapproved.php @@ -17,16 +17,16 @@ jimport('joomla.form.helper'); JFormHelper::loadFieldClass('list'); /** - * Powersfilterpowerversion Form Field class for the Componentbuilder component + * Powersfilterapproved Form Field class for the Componentbuilder component */ -class JFormFieldPowersfilterpowerversion extends JFormFieldList +class JFormFieldPowersfilterapproved extends JFormFieldList { /** - * The powersfilterpowerversion field type. + * The powersfilterapproved field type. * * @var string */ - public $type = 'powersfilterpowerversion'; + public $type = 'powersfilterapproved'; /** * Method to get a list of options for a list input. @@ -42,24 +42,28 @@ class JFormFieldPowersfilterpowerversion extends JFormFieldList $query = $db->getQuery(true); // Select the text. - $query->select($db->quoteName('power_version')); + $query->select($db->quoteName('approved')); $query->from($db->quoteName('#__componentbuilder_power')); - $query->order($db->quoteName('power_version') . ' ASC'); + $query->order($db->quoteName('approved') . ' ASC'); // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); - $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_VERSION') . ' -'); + $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_SUPER_POWER') . ' -'); - if ($results) + if ($_results) { - $results = array_unique($results); - foreach ($results as $power_version) + // get powersmodel + $_model = ComponentbuilderHelper::getModel('powers'); + $_results = array_unique($_results); + foreach ($_results as $approved) { - // Now add the power_version and its text to the options array - $_filter[] = JHtml::_('select.option', $power_version, $power_version); + // Translate the approved selection + $_text = $_model->selectionTranslation($approved,'approved'); + // Now add the approved and its text to the options array + $_filter[] = JHtml::_('select.option', $approved, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/powersfiltertype.php b/admin/models/fields/powersfiltertype.php index 5fa45b714..f39d87d64 100644 --- a/admin/models/fields/powersfiltertype.php +++ b/admin/models/fields/powersfiltertype.php @@ -49,20 +49,20 @@ class JFormFieldPowersfiltertype extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); - if ($results) + if ($_results) { // get powersmodel - $model = ComponentbuilderHelper::getModel('powers'); - $results = array_unique($results); - foreach ($results as $type) + $_model = ComponentbuilderHelper::getModel('powers'); + $_results = array_unique($_results); + foreach ($_results as $type) { // Translate the type selection - $text = $model->selectionTranslation($type,'type'); + $_text = $_model->selectionTranslation($type,'type'); // Now add the type and its text to the options array - $_filter[] = JHtml::_('select.option', $type, JText::_($text)); + $_filter[] = JHtml::_('select.option', $type, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/serversfiltername.php b/admin/models/fields/serversfiltername.php index 5626732d4..d84776551 100644 --- a/admin/models/fields/serversfiltername.php +++ b/admin/models/fields/serversfiltername.php @@ -49,14 +49,14 @@ class JFormFieldServersfiltername extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_NAME') . ' -'); - if ($results) + if ($_results) { - $results = array_unique($results); - foreach ($results as $name) + $_results = array_unique($_results); + foreach ($_results as $name) { // Now add the name and its text to the options array $_filter[] = JHtml::_('select.option', $name, $name); diff --git a/admin/models/fields/serversfilterprotocol.php b/admin/models/fields/serversfilterprotocol.php index 01fce0c8e..8aa22f5b6 100644 --- a/admin/models/fields/serversfilterprotocol.php +++ b/admin/models/fields/serversfilterprotocol.php @@ -49,21 +49,21 @@ class JFormFieldServersfilterprotocol extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_PROTOCOL') . ' -'); - if ($results) + if ($_results) { // get serversmodel - $model = ComponentbuilderHelper::getModel('servers'); - $results = array_unique($results); - foreach ($results as $protocol) + $_model = ComponentbuilderHelper::getModel('servers'); + $_results = array_unique($_results); + foreach ($_results as $protocol) { // Translate the protocol selection - $text = $model->selectionTranslation($protocol,'protocol'); + $_text = $_model->selectionTranslation($protocol,'protocol'); // Now add the protocol and its text to the options array - $_filter[] = JHtml::_('select.option', $protocol, JText::_($text)); + $_filter[] = JHtml::_('select.option', $protocol, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/siteviewsfilteraddcustombutton.php b/admin/models/fields/siteviewsfilteraddcustombutton.php index 20551f03b..f16ad9ab4 100644 --- a/admin/models/fields/siteviewsfilteraddcustombutton.php +++ b/admin/models/fields/siteviewsfilteraddcustombutton.php @@ -49,21 +49,21 @@ class JFormFieldSiteviewsfilteraddcustombutton extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_CUSTOM_BUTTONS') . ' -'); - if ($results) + if ($_results) { // get site_viewsmodel - $model = ComponentbuilderHelper::getModel('site_views'); - $results = array_unique($results); - foreach ($results as $add_custom_button) + $_model = ComponentbuilderHelper::getModel('site_views'); + $_results = array_unique($_results); + foreach ($_results as $add_custom_button) { // Translate the add_custom_button selection - $text = $model->selectionTranslation($add_custom_button,'add_custom_button'); + $_text = $_model->selectionTranslation($add_custom_button,'add_custom_button'); // Now add the add_custom_button and its text to the options array - $_filter[] = JHtml::_('select.option', $add_custom_button, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_custom_button, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/siteviewsfilteraddphpajax.php b/admin/models/fields/siteviewsfilteraddphpajax.php index c8f17b499..75cb59eb3 100644 --- a/admin/models/fields/siteviewsfilteraddphpajax.php +++ b/admin/models/fields/siteviewsfilteraddphpajax.php @@ -49,21 +49,21 @@ class JFormFieldSiteviewsfilteraddphpajax extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_PHP_AJAX') . ' -'); - if ($results) + if ($_results) { // get site_viewsmodel - $model = ComponentbuilderHelper::getModel('site_views'); - $results = array_unique($results); - foreach ($results as $add_php_ajax) + $_model = ComponentbuilderHelper::getModel('site_views'); + $_results = array_unique($_results); + foreach ($_results as $add_php_ajax) { // Translate the add_php_ajax selection - $text = $model->selectionTranslation($add_php_ajax,'add_php_ajax'); + $_text = $_model->selectionTranslation($add_php_ajax,'add_php_ajax'); // Now add the add_php_ajax and its text to the options array - $_filter[] = JHtml::_('select.option', $add_php_ajax, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_php_ajax, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fields/superpowerpaths.php b/admin/models/fields/superpowerpaths.php new file mode 100644 index 000000000..4f44dfe94 --- /dev/null +++ b/admin/models/fields/superpowerpaths.php @@ -0,0 +1,100 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// Import the checkboxes field type classes needed + +JFormHelper::loadFieldClass('checkboxes'); +use VDM\Joomla\Utilities\Component\Helper; + +/** + * Superpowerpaths Form Field class for the Componentbuilder component + */ +class JFormFieldSuperpowerpaths extends JFormFieldCheckboxes +{ + /** + * The superpowerpaths field type. + * + * @var string + */ + public $type = 'superpowerpaths'; + + // A DynamicCheckboxes@ Field + + /** + * Method to get the data to be passed to the layout for rendering. + * + * @return array + * + * @since 3.5 + */ + protected function getLayoutData() + { + $data = parent::getLayoutData(); + + // True if the field has 'value' set. In other words, it has been stored, don't use the default values. + $hasValue = (isset($this->value) && !empty($this->value)); + + // If a value has been stored, use it. Otherwise, use the defaults. + $checkedOptions = $hasValue ? $this->value : $this->checkedOptions; + + // get the form options + $options = []; + + // get the component params + $params = Helper::getParams(); + $activate = $params->get('super_powers_repositories', 0); + + // set the default + $default = $params->get('super_powers_core', 'joomla/super-powers'); + + // must have one / in the path + if (strpos($default, '/') !== false) + { + $tmp = new stdClass; + $tmp->text = $tmp->value = trim($default); + $tmp->checked = false; + $options[$tmp->value] = $tmp; + } + + if ($activate == 1) + { + $subform = $params->get($this->fieldname); + + // add the paths found in global settings + if (is_object($subform)) + { + foreach ($subform as $value) + { + if (isset($value->owner) && strlen($value->owner) > 1 && + isset($value->repo) && strlen($value->repo) > 1) + { + $tmp = new stdClass; + $tmp->text = $tmp->value = trim($value->owner) . '/' . trim($value->repo); + $tmp->checked = false; + + $options[$tmp->value] = $tmp; + } + } + } + } + + $extraData = array( + 'checkedOptions' => is_array($checkedOptions) ? $checkedOptions : explode(',', (string) $checkedOptions), + 'hasValue' => $hasValue, + 'options' => array_values($options) + ); + + return array_merge($data, $extraData); + } +} diff --git a/admin/models/fields/templatesfilteraddphpview.php b/admin/models/fields/templatesfilteraddphpview.php index 717e81443..fc38e1507 100644 --- a/admin/models/fields/templatesfilteraddphpview.php +++ b/admin/models/fields/templatesfilteraddphpview.php @@ -49,21 +49,21 @@ class JFormFieldTemplatesfilteraddphpview extends JFormFieldList // Reset the query using our newly populated query object. $db->setQuery($query); - $results = $db->loadColumn(); + $_results = $db->loadColumn(); $_filter = array(); $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_ADD_PHP_CUSTOM_VIEW_SCRIPT') . ' -'); - if ($results) + if ($_results) { // get templatesmodel - $model = ComponentbuilderHelper::getModel('templates'); - $results = array_unique($results); - foreach ($results as $add_php_view) + $_model = ComponentbuilderHelper::getModel('templates'); + $_results = array_unique($_results); + foreach ($_results as $add_php_view) { // Translate the add_php_view selection - $text = $model->selectionTranslation($add_php_view,'add_php_view'); + $_text = $_model->selectionTranslation($add_php_view,'add_php_view'); // Now add the add_php_view and its text to the options array - $_filter[] = JHtml::_('select.option', $add_php_view, JText::_($text)); + $_filter[] = JHtml::_('select.option', $add_php_view, JText::_($_text)); } } return $_filter; diff --git a/admin/models/fieldtype.php b/admin/models/fieldtype.php index e10d23415..23e450a86 100644 --- a/admin/models/fieldtype.php +++ b/admin/models/fieldtype.php @@ -16,6 +16,11 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Fieldtype Admin Model @@ -58,6 +63,8 @@ class ComponentbuilderModelFieldtype extends AdminModel 'indexes', 'null_switch', 'store', + 'basic_encryption_note', + 'medium_encryption_note', 'note_whmcs_encryption' ) ) @@ -125,7 +132,7 @@ class ComponentbuilderModelFieldtype extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'fieldtype__'.$id); ComponentbuilderHelper::set('fieldtype__'.$id, $this->vastDevMod); // set a return value if found @@ -133,7 +140,7 @@ class ComponentbuilderModelFieldtype extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -199,7 +206,7 @@ class ComponentbuilderModelFieldtype extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'fieldtype__'.$id); ComponentbuilderHelper::set('fieldtype__'.$id, $this->vastDevMod); // set a return value if found @@ -207,7 +214,7 @@ class ComponentbuilderModelFieldtype extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -271,7 +278,7 @@ class ComponentbuilderModelFieldtype extends AdminModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::linked((int) $type_extension[1], (string) $type_extension[0])) !== null) { $field_ids = $ids; } @@ -287,7 +294,7 @@ class ComponentbuilderModelFieldtype extends AdminModel $filter_admin_view = $this->state->get("filter.admin_view"); if ($get_ids && $filter_admin_view !== null && !empty($filter_admin_view)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_admin_view, 'admin_view')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_admin_view, 'admin_view')) !== null) { // view will return less fields, so we ignore the component $field_ids = $ids; @@ -300,7 +307,7 @@ class ComponentbuilderModelFieldtype extends AdminModel } } // now check if we have IDs - if ($get_ids && ComponentbuilderHelper::checkArray($field_ids)) + if ($get_ids && UtilitiesArrayHelper::check($field_ids)) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $field_ids) . ')'); } @@ -599,7 +606,7 @@ class ComponentbuilderModelFieldtype extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } return $form; @@ -663,7 +670,7 @@ class ComponentbuilderModelFieldtype extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('fieldtype.edit.state', 'com_componentbuilder'); } @@ -1252,15 +1259,15 @@ class ComponentbuilderModelFieldtype extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('fieldtype', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('fieldtype', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "fieldtype", $data['id'])) + while (!GuidHelper::valid($data['guid'], "fieldtype", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the properties items to data. if (isset($data['properties']) && is_array($data['properties'])) diff --git a/admin/models/forms/admin_custom_tabs.xml b/admin/models/forms/admin_custom_tabs.xml index bf05ddcf6..4733e880a 100644 --- a/admin/models/forms/admin_custom_tabs.xml +++ b/admin/models/forms/admin_custom_tabs.xml @@ -153,6 +153,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_ADMIN_CUSTOM_TABS_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_ADMIN_CUSTOM_TABS_NAME_MESSAGE" diff --git a/admin/models/forms/admin_view.xml b/admin/models/forms/admin_view.xml index 294612635..3b448cbcf 100644 --- a/admin/models/forms/admin_view.xml +++ b/admin/models/forms/admin_view.xml @@ -608,6 +608,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_MESSAGE" @@ -729,7 +731,7 @@ readonly="false" disabled="false" required="true" - filter="WORD" + filter="STRING" message="COM_COMPONENTBUILDER_ADMIN_VIEW_PARENTKEY_MESSAGE" hint="COM_COMPONENTBUILDER_ADMIN_VIEW_PARENTKEY_HINT" /> @@ -1786,6 +1788,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_MESSAGE" diff --git a/admin/models/forms/class_extends.xml b/admin/models/forms/class_extends.xml index 8861f9e1d..9811a2e0c 100644 --- a/admin/models/forms/class_extends.xml +++ b/admin/models/forms/class_extends.xml @@ -102,6 +102,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_CLASS_EXTENDS_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_CLASS_EXTENDS_NAME_MESSAGE" diff --git a/admin/models/forms/class_method.xml b/admin/models/forms/class_method.xml index e1c210b54..0852532f8 100644 --- a/admin/models/forms/class_method.xml +++ b/admin/models/forms/class_method.xml @@ -102,6 +102,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_CLASS_METHOD_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_CLASS_METHOD_NAME_MESSAGE" diff --git a/admin/models/forms/class_property.xml b/admin/models/forms/class_property.xml index 1d95e9cfb..7fdc145e7 100644 --- a/admin/models/forms/class_property.xml +++ b/admin/models/forms/class_property.xml @@ -102,6 +102,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_CLASS_PROPERTY_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_CLASS_PROPERTY_NAME_MESSAGE" diff --git a/admin/models/forms/component_custom_admin_menus.xml b/admin/models/forms/component_custom_admin_menus.xml index fb7ad3a56..547f5fd7b 100644 --- a/admin/models/forms/component_custom_admin_menus.xml +++ b/admin/models/forms/component_custom_admin_menus.xml @@ -137,6 +137,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_NAME_MESSAGE" diff --git a/admin/models/forms/component_dashboard.xml b/admin/models/forms/component_dashboard.xml index 78160c848..2b33f5025 100644 --- a/admin/models/forms/component_dashboard.xml +++ b/admin/models/forms/component_dashboard.xml @@ -138,6 +138,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_NAME_MESSAGE" diff --git a/admin/models/forms/custom_admin_view.xml b/admin/models/forms/custom_admin_view.xml index 0576f7735..d8029fd5b 100644 --- a/admin/models/forms/custom_admin_view.xml +++ b/admin/models/forms/custom_admin_view.xml @@ -116,6 +116,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NAME_MESSAGE" @@ -1118,6 +1120,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NAME_MESSAGE" diff --git a/admin/models/forms/dynamic_get.xml b/admin/models/forms/dynamic_get.xml index bf0b67278..32af1c69c 100644 --- a/admin/models/forms/dynamic_get.xml +++ b/admin/models/forms/dynamic_get.xml @@ -102,6 +102,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_DYNAMIC_GET_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_DYNAMIC_GET_NAME_MESSAGE" diff --git a/admin/models/forms/field.xml b/admin/models/forms/field.xml index 21fc3b1c4..a8a6eea36 100644 --- a/admin/models/forms/field.xml +++ b/admin/models/forms/field.xml @@ -102,6 +102,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_FIELD_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_FIELD_NAME_MESSAGE" @@ -237,21 +239,6 @@ description="COM_COMPONENTBUILDER_FIELD_CATID_DESCRIPTION" class="inputbox" /> - - - - + + + + COM_COMPONENTBUILDER_FIELD_OTHER - + + + - + - - - - + + + + + + COM_COMPONENTBUILDER_FIELD_NO - + COM_COMPONENTBUILDER_FIELD_NO - - + + COM_COMPONENTBUILDER_FIELD_NO - - + + COM_COMPONENTBUILDER_FIELD_NO - - + + - - + + COM_COMPONENTBUILDER_FIELDTYPE_OTHER - - + + - - + + COM_COMPONENTBUILDER_FIELDTYPE_OTHER + + + + JSTATUS_DESC - - + + diff --git a/admin/models/forms/filter_fields.xml b/admin/models/forms/filter_fields.xml index b626e5592..cbeda70c9 100644 --- a/admin/models/forms/filter_fields.xml +++ b/admin/models/forms/filter_fields.xml @@ -104,8 +104,8 @@ - - + + diff --git a/admin/models/forms/filter_joomla_components.xml b/admin/models/forms/filter_joomla_components.xml index 74fd0fc2d..e1d29ea4b 100644 --- a/admin/models/forms/filter_joomla_components.xml +++ b/admin/models/forms/filter_joomla_components.xml @@ -66,8 +66,8 @@ - - + + diff --git a/admin/models/forms/filter_powers.xml b/admin/models/forms/filter_powers.xml index 6571e0783..173808595 100644 --- a/admin/models/forms/filter_powers.xml +++ b/admin/models/forms/filter_powers.xml @@ -39,16 +39,9 @@ onchange="this.form.submit();" /> - diff --git a/admin/models/forms/joomla_component.xml b/admin/models/forms/joomla_component.xml index 17abef7d8..9aa8b76dc 100644 --- a/admin/models/forms/joomla_component.xml +++ b/admin/models/forms/joomla_component.xml @@ -156,81 +156,6 @@ message="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPANYNAME_MESSAGE" hint="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPANYNAME_HINT" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + type="list" + name="translation_tool" + label="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_TRANSLATION_TOOL_LABEL" + class="list_class" + multiple="false" + default="0"> + + + + - + - - - - + type="textarea" + name="buildcompsql" + label="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMPSQL_LABEL" + rows="30" + cols="15" + description="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMPSQL_DESCRIPTION" + class="text_area span12" + filter="raw" + hint="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMPSQL_HINT" + required="true" + /> COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NO - - + + COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CUSTOM_USED_IN_CUSTOM_CODE - - - - - - - - - + + + + + - + - - + + - + - - - - - - - - - + - - + + COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NO - + - - - - + type="textarea" + name="copyright" + label="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COPYRIGHT_LABEL" + rows="7" + cols="10" + default="Copyright (C) 2015. All Rights Reserved" + description="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COPYRIGHT_DESCRIPTION" + class="text_area span12" + filter="SAFEHTML" + hint="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COPYRIGHT_HINT" + required="true" + /> - - - - COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NO - - - - - - + + - + + + + + + + + + + + + + - - - - - - + + - + - - - - + type="calendar" + name="created" + label="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CREATED_LABEL" + description="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CREATED_DESCRIPTION" + format="%Y-%m-%d %H:%M:%S" + filter="user_utc" + size="22" + /> @@ -1217,6 +1206,8 @@ maxlength="150" description="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_DESCRIPTION" class="text_area" + readonly="false" + disabled="false" required="true" filter="STRING" message="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_MESSAGE" @@ -1406,10 +1397,78 @@ /> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + - + @@ -1469,23 +1545,19 @@ - + + default="0" + required="true"> - - - + COM_COMPONENTBUILDER_JOOMLA_COMPONENT_YES + - + - - - - - + type="editor" + name="php_helper_both" + label="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_HELPER_BOTH_LABEL" + description="COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_HELPER_BOTH_DESCRIPTION" + width="100%" + height="550px" + cols="15" + rows="80" + buttons="no" + syntax="php" + editor="codemirror|none" + filter="raw" + validate="code" + /> + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + max="100" + min="0"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + authorise('help_document.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/import.php b/admin/models/import.php index 659065710..457bf8f3e 100644 --- a/admin/models/import.php +++ b/admin/models/import.php @@ -18,7 +18,7 @@ use Joomla\CMS\Filesystem\Folder; use Joomla\Utilities\ArrayHelper; use PhpOffice\PhpSpreadsheet\IOFactory; -/** +/*** * Componentbuilder Import Base Database Model */ class ComponentbuilderModelImport extends BaseDatabaseModel diff --git a/admin/models/import_joomla_components.php b/admin/models/import_joomla_components.php index 3751471da..702cf0106 100644 --- a/admin/models/import_joomla_components.php +++ b/admin/models/import_joomla_components.php @@ -17,6 +17,15 @@ use Joomla\CMS\Filesystem\File; use Joomla\CMS\Filesystem\Folder; use Joomla\Utilities\ArrayHelper; use PhpOffice\PhpSpreadsheet\IOFactory; +use VDM\Joomla\Componentbuilder\Package\Factory as PackageFactory; +use VDM\Joomla\Utilities\ArrayHelper as JCBArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\GuidHelper; +use Joomla\CMS\Language\Text; /** * Componentbuilder Import_joomla_components Base Database Model @@ -163,7 +172,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // now clear it $session->clear('smart_package_info'); // convert to an array if found - if ($packageInfo && ComponentbuilderHelper::checkJson($packageInfo)) + if ($packageInfo && JsonHelper::check($packageInfo)) { $this->packageInfo = json_decode($packageInfo, true); } @@ -171,7 +180,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel default: $package = $session->get('package', null); - if (ComponentbuilderHelper::checkJson($package)) + if (JsonHelper::check($package)) { // get package $package = json_decode($package, true); @@ -215,7 +224,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $this->remove($package['packagename']); } - $this->app->setUserState('com_componentbuilder.message', JText::_('COM_COMPONENTBUILDER_IMPORT_UNABLE_TO_FIND_IMPORT_PACKAGE')); + $this->app->setUserState('com_componentbuilder.message', Text::_('COM_COMPONENTBUILDER_IMPORT_UNABLE_TO_FIND_IMPORT_PACKAGE')); return false; } @@ -225,7 +234,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // check if this a smart package, if true then get info if ($this->dataType !== 'smart_package' || !$this->getInfo($package, $session)) { - $this->app->setUserState('com_componentbuilder.message', JText::_('COM_COMPONENTBUILDER_THERE_WAS_AN_ERROR_GETTING_THE_PACKAGE_INFO')); + $this->app->setUserState('com_componentbuilder.message', Text::_('COM_COMPONENTBUILDER_THERE_WAS_AN_ERROR_GETTING_THE_PACKAGE_INFO')); return false; } // set package to session @@ -251,7 +260,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel if (!$this->setData($package)) { // There was an error importing the package - $msg = JText::_('COM_COMPONENTBUILDER_IMPORT_ERROR'); + $msg = Text::_('COM_COMPONENTBUILDER_IMPORT_ERROR'); $msgType = 'error'; $back = $session->get('backto_VDM_IMPORT', NULL); if ($back) @@ -297,13 +306,13 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // does this package pass a checksum $checksum = false; $checksumStatus = 'warning'; - $checksumMessage = JText::_('COM_COMPONENTBUILDER_PLEASE_NOTE_THAT_THIS_PACKAGE_BHAS_NOB_CHECKSUM_VALIDATION'); + $checksumMessage = Text::_('COM_COMPONENTBUILDER_PLEASE_NOTE_THAT_THIS_PACKAGE_BHAS_NOB_CHECKSUM_VALIDATION'); // do hash validation here for git repos - if (ComponentbuilderHelper::checkString($this->checksum) && isset($this->checksumURLs[$this->checksum])) + if (StringHelper::check($this->checksum) && isset($this->checksumURLs[$this->checksum])) { // get packages checksums - $checksums = ComponentbuilderHelper::getFileContents($this->checksumURLs[$this->checksum].'checksum.json'); - if (ComponentbuilderHelper::checkJson($checksums)) + $checksums = FileHelper::getContent($this->checksumURLs[$this->checksum].'checksum.json'); + if (JsonHelper::check($checksums)) { // convert to array $checksums = json_decode($checksums, true); @@ -324,14 +333,14 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // set error if (!$checksum) { - $checksumMessage = JText::_('COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_YOU_CAN_REFRESH_AND_TRY_AGAINBR_BUT_NOTE_THAT_THIS_PACKAGE_BFAILEDB_CHECKSUM_VALIDATION_THIS_COULD_BE_A_SERIOUS_SECURITY_BREACH_DO_NOT_CONTINUE'); + $checksumMessage = Text::_('COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_YOU_CAN_REFRESH_AND_TRY_AGAINBR_BUT_NOTE_THAT_THIS_PACKAGE_BFAILEDB_CHECKSUM_VALIDATION_THIS_COULD_BE_A_SERIOUS_SECURITY_BREACH_DO_NOT_CONTINUE'); $checksumStatus = 'error'; } } // set error else { - $checksumMessage = JText::_('COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_WE_COULD_NOT_LOAD_THE_CHECKSUM_FOR_THIS_PACKAGE_AND_SO_NO_VALIDATION_WAS_POSSIBLE_THIS_MAY_BE_DUE_TO_YOUR_NETWORK_OR_A_CHANGE_TO_THAT_PACKAGE_NAME'); + $checksumMessage = Text::_('COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_WE_COULD_NOT_LOAD_THE_CHECKSUM_FOR_THIS_PACKAGE_AND_SO_NO_VALIDATION_WAS_POSSIBLE_THIS_MAY_BE_DUE_TO_YOUR_NETWORK_OR_A_CHANGE_TO_THAT_PACKAGE_NAME'); $checksumStatus = 'error'; } } @@ -348,20 +357,19 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel if (JFile::exists($infoFile)) { // load the data - if ($info = @file_get_contents($infoFile)) + if ($info = FileHelper::getContent($infoFile)) { - // Get the password. - $db = 'COM_COMPONENTBUILDER_SZDEQZDMVSMHBTRWFIFTYTSQFLVVXJTMTHREEJTWOIXM'; - $password = base64_decode(JText::sprintf($db, 'VjR', 'WV0aE9k')); // unlock the info data - if (($info = $this->decrypt($info, $password, true)) !== false && ComponentbuilderHelper::checkJson($info)) + if ((($info_ = PackageFactory::_('Crypt')->decrypt($info, 'local')) !== null && JsonHelper::check($info_)) || + (($info_ = PackageFactory::_('Crypt')->decrypt($info, 'local.legacy')) !== null && JsonHelper::check($info_)) || + (($info_ = PackageFactory::_('Crypt')->decrypt($info, 'local.fof')) !== null && JsonHelper::check($info_))) { // we only continue if info could be opened - $session->set('smart_package_info', $info); + $session->set('smart_package_info', $info_); return true; } // do not have check sum validation - $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_PACKAGEHTWOTHIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLA_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEZEROELEVENPRO_OR_VTWOONETWOSEVENTEENPUBLIC_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB'), 'error'); + $this->app->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_PACKAGEHTWOTHIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLA_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEZEROELEVENPRO_OR_VTWOONETWOSEVENTEENPUBLIC_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB'), 'error'); } } ComponentbuilderHelper::removeFolder($this->dir); @@ -636,12 +644,12 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel if (JFile::exists($dbFile)) { // load the data - if ($data = @file_get_contents($dbFile)) + if ($data = FileHelper::getContent($dbFile)) { // prep the data if ($this->extractData($data)) { - if (isset($this->data['joomla_component']) && ComponentbuilderHelper::checkArray($this->data['joomla_component'])) + if (isset($this->data['joomla_component']) && JCBArrayHelper::check($this->data['joomla_component'])) { // save the smart data if ($this->saveSmartComponents()) @@ -671,20 +679,20 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel protected function extractData($data) { // remove all line breaks - if (($data = $this->decrypt($data, $this->sleutle)) !== false) + if (($data = $this->decrypt($data, $this->sleutle)) !== null) { // final check if we have success $data = @unserialize($data); - if (ComponentbuilderHelper::checkArray($data)) + if (JCBArrayHelper::check($data)) { // set the data global $this->data = $data; return true; } - $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BKEY_ERRORB_OR_BROKEN_PACKAGE'), 'error'); + $this->app->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BKEY_ERRORB_OR_BROKEN_PACKAGE'), 'error'); return false; } - $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BROKEN_PACKAGE'), 'error'); + $this->app->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BROKEN_PACKAGE'), 'error'); return false; } @@ -704,7 +712,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel if (!$this->canmerge) { // set some postfix - $this->postfix = ' ('.ComponentbuilderHelper::randomkey(2).')'; + $this->postfix = ' ('.StringHelper::random(2).')'; } // the array of tables to store $tables = array( @@ -738,11 +746,11 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // check if it is the power table if ($table === 'power') { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_THE_WHOLE_POWERS_FEATURE_IS_ONLY_AVAILABLE_TO_A_HREFSPRO_MEMBERSA_AT_THIS_TIME', '#__componentbuilder_' . $table, '"https://vdm.bz/get-jcb-pro-membership" target="_blank" title="Join PRO Membership today!"'), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_THE_WHOLE_POWERS_FEATURE_IS_ONLY_AVAILABLE_TO_A_HREFSPRO_MEMBERSA_AT_THIS_TIME', '#__componentbuilder_' . $table, '"https://vdm.bz/get-jcb-pro-membership" target="_blank" title="Join PRO Membership today!"'), 'warning'); } else { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN', '#__componentbuilder_' . $table), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN', '#__componentbuilder_' . $table), 'warning'); } } } @@ -768,7 +776,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel **/ public function saveSmartItems($table) { - if (isset($this->data[$table]) && ComponentbuilderHelper::checkArray($this->data[$table])) + if (isset($this->data[$table]) && JCBArrayHelper::check($this->data[$table])) { // add pre import event $this->preImportEvent($table); @@ -793,7 +801,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // display more import info if ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BSB_WAS_FOUND', $table.' id:'.$oldID . '->' . $local->id), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BSB_WAS_FOUND', $table.' id:'.$oldID . '->' . $local->id), 'success'); } $dbDate = strtotime($item->modified); $localDate = strtotime($local->modified); @@ -818,7 +826,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // display more import info if ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BSB_HAS_BEEN_UPDATED', $table.' id:'.$oldID . '->' . $id), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BSB_HAS_BEEN_UPDATED', $table.' id:'.$oldID . '->' . $id), 'success'); } } else @@ -826,9 +834,9 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $notice = '!'; if (!$canEdit) { - $notice = JText::sprintf("COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_EDIT_S", $table); + $notice = Text::sprintf("COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_EDIT_S", $table); } - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BSB_COULD_NOT_BE_IMPORTEDS', $table.' id:'.$oldID, $notice), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BSB_COULD_NOT_BE_IMPORTEDS', $table.' id:'.$oldID, $notice), 'error'); } } // insure to load the local ID to link imported values with it @@ -844,7 +852,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // display more import info if ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BSB_HAS_BEEN_IMPORTED', $table.' id:'.$oldID . '->' . $id), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BSB_HAS_BEEN_IMPORTED', $table.' id:'.$oldID . '->' . $id), 'success'); } } else @@ -852,9 +860,9 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $notice = '!'; if (!$canCreate) { - $notice = JText::sprintf("COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_CREATE_S", $table); + $notice = Text::sprintf("COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_CREATE_S", $table); } - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BSB_COULD_NOT_BE_IMPORTEDS', $table.' id:'.$oldID, $notice), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BSB_COULD_NOT_BE_IMPORTEDS', $table.' id:'.$oldID, $notice), 'error'); } } } @@ -873,7 +881,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove all custom code linked to these components // since some code may have been removed and changed // best unpublish all and let the import publish those still active - if ('custom_code' === $table && isset($this->newID['joomla_component']) && ComponentbuilderHelper::checkArray($this->newID['joomla_component'])) + if ('custom_code' === $table && isset($this->newID['joomla_component']) && JCBArrayHelper::check($this->newID['joomla_component'])) { $query = $this->_db->getQuery(true); // Field to update. @@ -937,7 +945,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // display more import info elseif ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_SOME_BCUSTOM_FILESB_WERE_MOVED_TO_BSB', $customPath), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_SOME_BCUSTOM_FILESB_WERE_MOVED_TO_BSB', $customPath), 'success'); } } // check if we have images @@ -953,7 +961,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // display more import info elseif ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_SOME_BIMAGESB_WERE_MOVED_TO_BSB', $imagesPath), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_SOME_BIMAGESB_WERE_MOVED_TO_BSB', $imagesPath), 'success'); } } // now move the dynamic files if found @@ -963,7 +971,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // get a list of folders $folders = JFolder::folders($dynamicDir); // check if we have files - if(ComponentbuilderHelper::checkArray($folders)) + if(JCBArrayHelper::check($folders)) { foreach ($folders as $folder) { @@ -971,20 +979,20 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $fullPath = str_replace('//', '/', $dynamicDir . '/' . $folder); if (!JFolder::exists($fullPath) || !JFolder::copy($fullPath, $destination,'',true)) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVED_TO_BSB', $folder, $destination), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVED_TO_BSB', $folder, $destination), 'error'); $success = false; } // display more import info elseif ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_MOVED_TO_BSB', $folder, $destination), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_MOVED_TO_BSB', $folder, $destination), 'success'); } } } // get a list of files $files = JFolder::files($dynamicDir); // check if we have files - if(ComponentbuilderHelper::checkArray($files)) + if(JCBArrayHelper::check($files)) { foreach ($files as $file) { @@ -992,13 +1000,13 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $fullPath = str_replace('//', '/', $dynamicDir . '/' . $file); if (!JFile::exists($fullPath) || !JFile::copy($fullPath, $destination)) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVED_TO_BSB', $file, $destination), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVED_TO_BSB', $file, $destination), 'error'); $success = false; } // display more import info elseif ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_MOVED_TO_BSB', $file, $destination), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_MOVED_TO_BSB', $file, $destination), 'success'); } } } @@ -1014,7 +1022,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel protected function unLockFiles() { // lock the data if set - if(ComponentbuilderHelper::checkString($this->sleutle) && strlen($this->sleutle) == 32) + if(StringHelper::check($this->sleutle) && strlen($this->sleutle) == 32) { // we must first store the current working directory $joomla = getcwd(); @@ -1050,24 +1058,24 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel foreach ($files as $file) { // open the file content - if (($data = $this->decrypt(file_get_contents($file), $this->sleutle)) !== false) + if (($data = $this->decrypt(file_get_contents($file), $this->sleutle)) !== null) { // write the decrypted data back to file - if (!ComponentbuilderHelper::writeFile($file, $data)) + if (!FileHelper::write($file, $data)) { // in case file could not be unlocked - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_COULD_NOT_BE_UNLOCKED', $file), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FILE_BSB_COULD_NOT_BE_UNLOCKED', $file), 'error'); } // display more import info elseif ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_SUCCESSFULLY_UNLOCKED', $file), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_SUCCESSFULLY_UNLOCKED', $file), 'success'); } } else { // in case file could not be unlocked - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_COULD_NOT_BE_UNLOCKED', $file), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FILE_BSB_COULD_NOT_BE_UNLOCKED', $file), 'error'); } } } @@ -1075,9 +1083,9 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel /** * decrypt data * - * @param string $data The data string - * @param string $password The key to unlock - * @param bool $force Should we force phpseclib decryption + * @param string $data The data string + * @param string $password The key to unlock + * @param bool $force Should we force phpseclib decryption * * @return mixed the data, or false * @@ -1086,57 +1094,155 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel protected function decrypt(string $data, string $password, bool $force = false) { // remove all line breaks - $data = str_replace("\n", '', $data); + $data = $this->removeLineBreaks($data); + // make sure we have base64 - if ($data === base64_encode(base64_decode($data, true))) + if ($this->isBase64Encoded($data)) { // open the data - if(ComponentbuilderHelper::checkString($password) && strlen($password) == 32) + if($this->isValidPassword($password)) { - // check if we should use the phpseclib decryption - $phpseclip = (isset($this->packageInfo['phpseclib']) && $this->packageInfo['phpseclib']) ? true : $force; - // load phpseclib - if($phpseclip && ComponentbuilderHelper::crypt('AES', 'CBC') instanceof \phpseclib\Crypt\Rijndael) + // try phpseclib version 3 + if(($this->isPhpseclib3Enabled() || $force) && + ($data_ = $this->decryptWithPhpseclib3($data, $password)) !== null) { - // load the system password - ComponentbuilderHelper::crypt('AES', 'CBC')->setPassword($password, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); - // open the data block - $data = ComponentbuilderHelper::crypt('AES', 'CBC')->decrypt(base64_decode($data)); - // check if we had success - if ($data !== false) - { - return $data; - } + return $data_; } - // check if we had success - if (class_exists('FOFEncryptAes')) + + // try phpseclib version 2 + if(($this->isPhpseclib2Enabled() || $force) && + ($data_ = $this->decryptWithPhpseclib2($data, $password)) !== null) { - // Get the encryption object. - if (!$this->noopmaker instanceof FOFEncryptAes) - { - $this->noopmaker = new FOFEncryptAes($password, 128); - } - // open the data block - $data = $this->noopmaker->decryptString($data); - // check if we had success - if ($data !== false) - { - return $data; - } - else - { - $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEZEROELEVENPRO_OR_VTWOONETWOSEVENTEENPUBLIC_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB'), 'error'); - } + return $data_; } + + // try FOF the outdated method + if (($data_ = $this->decryptWithFof($data, $password)) !== null) + { + return $data_; + } + + $this->app->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEONEONEEIGHT_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB'), 'error'); } else { return base64_decode($data); } } + return false; } + /** + * Removes all line breaks from a string + * + * @param string $data + * + * @return string + */ + private function removeLineBreaks(string $data): string + { + return str_replace("\n", '', $data); + } + + /** + * Check if the data is base64 encoded + * + * @param string $data + * + * @return bool + */ + private function isBase64Encoded(string $data): bool + { + return $data === base64_encode(base64_decode($data, true)); + } + + /** + * Check if a password is set and has a length of 32 characters + * + * @param string $password + * + * @return bool + */ + private function isValidPassword(string $password): bool + { + return StringHelper::check($password) && strlen($password) == 32; + } + + /** + * Check if we can use phpseclib library version 2 + * + * @return bool + */ + private function isPhpseclib2Enabled(): bool + { + return (bool) isset($this->packageInfo['phpseclib']) && $this->packageInfo['phpseclib']; + } + + /** + * Decrypts data using the phpseclib library version 2 + * + * @param string $data + * @param string $password + * + * @return string|null + */ + private function decryptWithPhpseclib2(string $data, string $password): ?string + { + $data_ = PackageFactory::_('Crypt')->decrypt($data, 'legacy', $password); + if ($data_ !== null) + { + return strcmp($data, $data_) !== 0 ? $data_ : null; + } + return null; + } + + /** + * Check if we can use phpseclib library version 3 + * + * @return bool + */ + private function isPhpseclib3Enabled(): bool + { + return (bool) isset($this->packageInfo['phpseclib3']) && $this->packageInfo['phpseclib3']; + } + + /** + * Decrypts data using the phpseclib library version 3 + * + * @param string $data + * @param string $password + * + * @return string|null + */ + private function decryptWithPhpseclib3(string $data, string $password): ?string + { + $data_ = PackageFactory::_('Crypt')->decrypt($data, 'aes', $password); + if ($data_ !== null) + { + return strcmp($data, $data_) !== 0 ? $data_ : null; + } + return null; + } + + /** + * Decrypts data using the FOF library (outdated method) + * + * @param string $data + * @param string $password + * + * @return string|null + */ + private function decryptWithFof(string $data, string $password): ?string + { + $data_ = PackageFactory::_('Crypt')->decrypt($data, 'fof', $password); + if ($data_ !== null) + { + return strcmp($data, $data_) !== 0 ? $data_ : null; + } + return null; + } + /** * Update some items after all * @@ -1146,7 +1252,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel public function updateAfterAll() { // update the fields - if (isset($this->updateAfter['field']) && ComponentbuilderHelper::checkArray($this->updateAfter['field'])) + if (isset($this->updateAfter['field']) && JCBArrayHelper::check($this->updateAfter['field'])) { // update repeatable foreach ($this->updateAfter['field'] as $field => $action) @@ -1157,12 +1263,12 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $field = $this->newID['field'][$field]; } // get the field from db - if ($xml = ComponentbuilderHelper::getVar('field', $field, 'id', 'xml')) + if ($xml = GetHelper::var('field', $field, 'id', 'xml')) { - if (ComponentbuilderHelper::checkJson($xml)) + if (JsonHelper::check($xml)) { $xml = json_decode($xml); - $fields = ComponentbuilderHelper::getBetween($xml, 'fields="', '"'); + $fields = GetHelper::between($xml, 'fields="', '"'); $fieldsSets = array(); if (strpos($fields, ',') !== false) { @@ -1175,7 +1281,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $fieldsSets[] = (int) $fields; } // update the fields - if (ComponentbuilderHelper::checkArray($fieldsSets)) + if (JCBArrayHelper::check($fieldsSets)) { $bucket = array(); foreach ($fieldsSets as $id) @@ -1186,10 +1292,10 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } else { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BMULTIPLE_FIELD_REPEATABLE_MODEB_IDS_MISMATCH_IN_BFIELDSB_AND_WAS_EMREMOVEDEM_FROM_THE_FIELD', $id, $field), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BMULTIPLE_FIELD_REPEATABLE_MODEB_IDS_MISMATCH_IN_BFIELDSB_AND_WAS_EMREMOVEDEM_FROM_THE_FIELD', $id, $field), 'warning'); } } - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { $string = implode(',', $bucket); $xml = json_encode(str_replace('fields="' . $fields . '"', 'fields="' . $string . '"', $xml)); @@ -1209,7 +1315,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // do a after all run on admin views that need it - if (isset($this->updateAfter['adminview']) && ComponentbuilderHelper::checkArray($this->updateAfter['adminview'])) + if (isset($this->updateAfter['adminview']) && JCBArrayHelper::check($this->updateAfter['adminview'])) { // update the addlinked_views foreach ($this->updateAfter['adminview'] as $adminview => $action) @@ -1220,18 +1326,18 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $adminview = $this->newID['admin_view'][(int) $adminview]; } // get the field from db - if ($addlinked_views = ComponentbuilderHelper::getVar('admin_view', $adminview, 'id', 'addlinked_views')) + if ($addlinked_views = GetHelper::var('admin_view', $adminview, 'id', 'addlinked_views')) { - if (ComponentbuilderHelper::checkJson($addlinked_views)) + if (JsonHelper::check($addlinked_views)) { $addlinked_views = json_decode($addlinked_views, true); // convert Repeatable Fields - if (ComponentbuilderHelper::checkArray($addlinked_views) && isset($addlinked_views['adminview'])) + if (JCBArrayHelper::check($addlinked_views) && isset($addlinked_views['adminview'])) { $addlinked_views = ComponentbuilderHelper::convertRepeatable($addlinked_views, 'addlinked_views'); } // update the view IDs - if (ComponentbuilderHelper::checkArray($addlinked_views)) + if (JCBArrayHelper::check($addlinked_views)) { // only update the view IDs $addlinked_views = $this->updateIDs($addlinked_views, 'admin_view', array('adminview' => 'admin_view')); @@ -1247,7 +1353,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // update the joomla_component dashboard - if (isset($this->updateAfter['joomla_component']) && ComponentbuilderHelper::checkArray($this->updateAfter['joomla_component'])) + if (isset($this->updateAfter['joomla_component']) && JCBArrayHelper::check($this->updateAfter['joomla_component'])) { // update dashboard of the components foreach ($this->updateAfter['joomla_component'] as $component => $action) @@ -1258,9 +1364,9 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $component = $this->newID['joomla_component'][(int) $component]; } // get the dashboard from db - if ($dashboard = ComponentbuilderHelper::getVar('joomla_component', $component, 'id', 'dashboard')) + if ($dashboard = GetHelper::var('joomla_component', $component, 'id', 'dashboard')) { - if (ComponentbuilderHelper::checkString($dashboard)) + if (StringHelper::check($dashboard)) { // get id $id = (int) preg_replace("/[^0-9]/", "", $dashboard); @@ -1297,7 +1403,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // update the admin_fields_relations - if (isset($this->updateAfter['relations']) && ComponentbuilderHelper::checkArray($this->updateAfter['relations'])) + if (isset($this->updateAfter['relations']) && JCBArrayHelper::check($this->updateAfter['relations'])) { // update repeatable foreach ($this->updateAfter['relations'] as $relation => $action) @@ -1310,38 +1416,38 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $relation = $this->newID['admin_fields_relations'][$relation]; } // get the set relation from db - if ($addrelations = ComponentbuilderHelper::getVar('admin_fields_relations', $relation, 'id', 'addrelations')) + if ($addrelations = GetHelper::var('admin_fields_relations', $relation, 'id', 'addrelations')) { - if (ComponentbuilderHelper::checkJson($addrelations)) + if (JsonHelper::check($addrelations)) { $addrelations = json_decode($addrelations, true); - if (ComponentbuilderHelper::checkArray($addrelations)) + if (JCBArrayHelper::check($addrelations)) { foreach ($addrelations as $nr => &$value) { // reset the buckets $bucket = array(); // get fields - $found = ComponentbuilderHelper::getAllBetween($value['set'], '[field=', ']'); + $found = GetHelper::allBetween($value['set'], '[field=', ']'); // if found - if (ComponentbuilderHelper::checkArray($found)) + if (JCBArrayHelper::check($found)) { $bucket[] = $found; } // get fields - $found = ComponentbuilderHelper::getAllBetween($value['set'], '$item->{', '}'); + $found = GetHelper::allBetween($value['set'], '$item->{', '}'); // if found - if (ComponentbuilderHelper::checkArray($found)) + if (JCBArrayHelper::check($found)) { $bucket[] = $found; } // check if we have values - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { - $fields = ComponentbuilderHelper::mergeArrays($bucket); + $fields = JCBArrayHelper::merge($bucket); // reset the buckets $bucket = array(); - if (ComponentbuilderHelper::checkArray($fields)) + if (JCBArrayHelper::check($fields)) { foreach ($fields as $field) { @@ -1352,11 +1458,11 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } else { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BADMIN_FIELDS_RELATIONSB_IDS_MISMATCH_IN_BFIELDSB_AND_WAS_NOT_UPDATED_IN_THE_CUSTOM_CODE', $relation, $field), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BADMIN_FIELDS_RELATIONSB_IDS_MISMATCH_IN_BFIELDSB_AND_WAS_NOT_UPDATED_IN_THE_CUSTOM_CODE', $relation, $field), 'warning'); } } // check if we have a bucket of values to update - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { $value['set'] = str_replace(array_keys($bucket), array_values($bucket), $value['set']); $update = true; @@ -1379,7 +1485,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // update the verious power linked to these powers - if (isset($this->updateAfter['power']) && ComponentbuilderHelper::checkArray($this->updateAfter['power'])) + if (isset($this->updateAfter['power']) && JCBArrayHelper::check($this->updateAfter['power'])) { // update repeatable foreach ($this->updateAfter['power'] as $power => $action) @@ -1426,7 +1532,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel public function moveDivergedData() { // check if there is data to move - if (ComponentbuilderHelper::checkArray($this->divergedDataMover)) + if (JCBArrayHelper::check($this->divergedDataMover)) { foreach($this->divergedDataMover as $table => $values) { @@ -1452,13 +1558,13 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * * @return void */ - protected function updateParamIDs(&$item, $table, $targets) + private function updateParamIDs(&$item, $table, $targets) { // update the params fields if exist - if (isset($item->params) && ComponentbuilderHelper::checkJson($item->params)) + if (isset($item->params) && JsonHelper::check($item->params)) { $paramsArray = json_decode($item->params, true); - if (ComponentbuilderHelper::checkArray($paramsArray)) + if (JCBArrayHelper::check($paramsArray)) { foreach ($targets as $field => $targetArray) { @@ -1481,7 +1587,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // check if we had some subforms - if (ComponentbuilderHelper::checkArray($target_array)) + if (JCBArrayHelper::check($target_array)) { $paramsArray[$field] = $this->updateIDs($paramsArray[$field], $table, $target_array); } @@ -1502,15 +1608,15 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * * @return void */ - protected function updateSubformsIDs(&$item, $table, $targets) + private function updateSubformsIDs(&$item, $table, $targets) { // update the repeatable fields foreach ($targets as $field => $targetArray) { - if (isset($item->{$field}) && ComponentbuilderHelper::checkJson($item->{$field})) + if (isset($item->{$field}) && JsonHelper::check($item->{$field})) { $updateArray = json_decode($item->{$field}, true); - if (ComponentbuilderHelper::checkArray($updateArray)) + if (JCBArrayHelper::check($updateArray)) { // load it back $item->{$field} = json_encode($this->updateIDs($updateArray, $table, $targetArray), JSON_FORCE_OBJECT); @@ -1522,22 +1628,22 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel /** * Update IDs * - * @param array $values The values to update the IDs in - * @param string $table The table these values belong to - * @param array $targets The target to update and its type + * @param array $values The values to update the IDs in + * @param string $table The table these values belong to + * @param array $targets The target to update and its type * * @return void */ - protected function updateIDs($values, $table, $targets) + private function updateIDs($values, $table, $targets) { $isJson = false; - if (ComponentbuilderHelper::checkJson($values)) + if (JsonHelper::check($values)) { $values = json_decode($values, true); $isJson = true; } // now update the fields - if (ComponentbuilderHelper::checkArray($values)) + if (JCBArrayHelper::check($values)) { foreach ($values as $nr => &$value) { @@ -1568,27 +1674,27 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * @return boolean True on success * */ - protected function setNewID($item, $target, $type, $table) + private function setNewID($item, $target, $type, $table) { $isJson = false; - if (ComponentbuilderHelper::checkJson($item)) + if (JsonHelper::check($item)) { $item = json_decode($item, true); $isJson = true; } - if (ComponentbuilderHelper::checkArray($item) && isset($item[$target])) + if (JCBArrayHelper::check($item) && isset($item[$target])) { // set item ID $itemId = (isset($item['id'])) ? $item['id'] : 'id_unknow'; // check if it is json $isJsonTarget = false; - if (ComponentbuilderHelper::checkJson($item[$target])) + if (JsonHelper::check($item[$target])) { $item[$target] = json_decode($item[$target], true); $isJsonTarget = true; } // update the target - if (ComponentbuilderHelper::checkString($item[$target]) || is_numeric($item[$target])) + if (StringHelper::check($item[$target]) || is_numeric($item[$target])) { if ($item[$target] <= 0) { @@ -1607,7 +1713,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $item[$target] = ''; } } - elseif (ComponentbuilderHelper::checkArray($item[$target])) + elseif (JCBArrayHelper::check($item[$target])) { // the bucket to load the items back $bucket = array(); @@ -1622,7 +1728,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // we add negative numbers back $bucket[] = $id; } - elseif ((ComponentbuilderHelper::checkString($id) || is_numeric($id)) && isset($this->newID[$type][(int) $id])) + elseif ((StringHelper::check($id) || is_numeric($id)) && isset($this->newID[$type][(int) $id])) { $bucket[] = $this->newID[$type][(int) $id]; } @@ -1632,7 +1738,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // set ids back - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { $item[$target] = $bucket; } @@ -1643,19 +1749,19 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $item[$target] = json_encode($item[$target], JSON_FORCE_OBJECT); } } - elseif (ComponentbuilderHelper::checkObject($item) && isset($item->{$target})) + elseif (ObjectHelper::check($item) && isset($item->{$target})) { // set item ID $itemId = (isset($item->id)) ? $item->id : 'id_unknow'; // check if it is json $isJsonTarget = false; - if (ComponentbuilderHelper::checkJson($item->{$target})) + if (JsonHelper::check($item->{$target})) { $item->{$target} = json_decode($item->{$target}, true); $isJsonTarget = true; } // update the target - if (ComponentbuilderHelper::checkString($item->{$target}) || is_numeric($item->{$target})) + if (StringHelper::check($item->{$target}) || is_numeric($item->{$target})) { if ($item->{$target} <= 0) { @@ -1674,7 +1780,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel $item->{$target} = ''; } } - elseif (ComponentbuilderHelper::checkArray($item->{$target})) + elseif (JCBArrayHelper::check($item->{$target})) { // the bucket to load the items back $bucket = array(); @@ -1689,7 +1795,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // we add negative numbers back $bucket[] = $id; } - elseif ((ComponentbuilderHelper::checkString($id) || is_numeric($id)) && isset($this->newID[$type][(int) $id])) + elseif ((StringHelper::check($id) || is_numeric($id)) && isset($this->newID[$type][(int) $id])) { $bucket[] = $this->newID[$type][(int) $id]; } @@ -1700,7 +1806,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // set ids back - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { $item->{$target} = $bucket; } @@ -1731,9 +1837,9 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * @return void * */ - protected function enqueueIdMismatchMessage($id, $itemId, $target, $type, $table) + private function enqueueIdMismatchMessage($id, $itemId, $target, $type, $table) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BSBS_IN_BSB_HAS_ID_MISMATCH_SO_THE_BSB_WAS_REMOVED', ComponentbuilderHelper::safeString($type, 'Ww'), ComponentbuilderHelper::safeString($target, 'Ww') , ComponentbuilderHelper::safeString($table, 'w').':'.$itemId, $type . ':' . $id), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BSBS_IN_BSB_HAS_ID_MISMATCH_SO_THE_BSB_WAS_REMOVED', StringHelper::safe($type, 'Ww'), StringHelper::safe($target, 'Ww') , StringHelper::safe($table, 'w').':'.$itemId, $type . ':' . $id), 'warning'); } /** @@ -1748,7 +1854,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * object on success * **/ - protected function prepItem($item, $type, $action, $diverged = false) + private function prepItem($item, $type, $action, $diverged = false) { // remove access if (isset($item->access)) @@ -1813,12 +1919,12 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } elseif (!is_numeric($item->fieldtype) || $item->fieldtype == 0) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BFIELD_TYPEB_NOT_SET_FOR_BSB', ComponentbuilderHelper::safeString($type, 'w').':'.$item->id), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BFIELD_TYPEB_NOT_SET_FOR_BSB', StringHelper::safe($type, 'w').':'.$item->id), 'warning'); unset($item->fieldtype); } else { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BFIELD_TYPEB_IDS_MISMATCH_IN_BSB', $item->fieldtype, ComponentbuilderHelper::safeString($type, 'w').':'.$item->id), 'error'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_BFIELD_TYPEB_IDS_MISMATCH_IN_BSB', $item->fieldtype, StringHelper::safe($type, 'w').':'.$item->id), 'error'); return false; } // if we can't merge add postfix to name @@ -1906,7 +2012,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel unset($item->addtables); } // update the addfields (old dataset) - if (isset($item->addfields) && ComponentbuilderHelper::checkJson($item->addfields)) + if (isset($item->addfields) && JsonHelper::check($item->addfields)) { // move the old data $this->setDivergedDataMover($item->addfields, 'admin_fields', 'addfields', $getter); @@ -1914,7 +2020,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addfields); // update the addlinked_views - if (isset($item->addlinked_views) && ComponentbuilderHelper::checkJson($item->addlinked_views)) + if (isset($item->addlinked_views) && JsonHelper::check($item->addlinked_views)) { $this->updateAfter['adminview'][(int) $item->id] = $action; // addlinked_views } @@ -1923,7 +2029,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel unset($item->addlinked_views); } // update the addconditions (old dataset) - if (isset($item->addconditions) && ComponentbuilderHelper::checkJson($item->addconditions)) + if (isset($item->addconditions) && JsonHelper::check($item->addconditions)) { // move the old data $this->setDivergedDataMover($item->addconditions, 'admin_fields_conditions', 'addconditions', $getter); @@ -1972,7 +2078,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // set the anchors getters $getter = array('joomla_component' => $item->id); // update the addconfig - if (isset($item->addconfig) && ComponentbuilderHelper::checkJson($item->addconfig)) + if (isset($item->addconfig) && JsonHelper::check($item->addconfig)) { // move the old data $this->setDivergedDataMover($item->addconfig, 'component_config', 'addconfig', $getter); @@ -1980,7 +2086,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addconfig); // update the addadmin_views - if (isset($item->addadmin_views) && ComponentbuilderHelper::checkJson($item->addadmin_views)) + if (isset($item->addadmin_views) && JsonHelper::check($item->addadmin_views)) { // move the old data $this->setDivergedDataMover($item->addadmin_views, 'component_admin_views', 'addadmin_views', $getter); @@ -1988,7 +2094,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addadmin_views); // update the addcustom_admin_views - if (isset($item->addcustom_admin_views) && ComponentbuilderHelper::checkJson($item->addcustom_admin_views)) + if (isset($item->addcustom_admin_views) && JsonHelper::check($item->addcustom_admin_views)) { // move the old data $this->setDivergedDataMover($item->addcustom_admin_views, 'component_custom_admin_views', 'addcustom_admin_views', $getter); @@ -1996,7 +2102,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addcustom_admin_views); // update the addsite_views - if (isset($item->addsite_views) && ComponentbuilderHelper::checkJson($item->addsite_views)) + if (isset($item->addsite_views) && JsonHelper::check($item->addsite_views)) { // move the old data $this->setDivergedDataMover($item->addsite_views, 'component_site_views', 'addsite_views', $getter); @@ -2004,7 +2110,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addsite_views); // update the version_update - if (isset($item->version_update) && ComponentbuilderHelper::checkJson($item->version_update)) + if (isset($item->version_update) && JsonHelper::check($item->version_update)) { // move the old data $this->setDivergedDataMover($item->version_update, 'component_updates', 'version_update', $getter); @@ -2012,7 +2118,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->version_update); // update the sql_tweak - if (isset($item->sql_tweak) && ComponentbuilderHelper::checkJson($item->sql_tweak)) + if (isset($item->sql_tweak) && JsonHelper::check($item->sql_tweak)) { // move the old data $this->setDivergedDataMover($item->sql_tweak, 'component_mysql_tweaks', 'sql_tweak', $getter); @@ -2020,7 +2126,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->sql_tweak); // update the addcustommenus - if (isset($item->addcustommenus) && ComponentbuilderHelper::checkJson($item->addcustommenus)) + if (isset($item->addcustommenus) && JsonHelper::check($item->addcustommenus)) { // move the old data $this->setDivergedDataMover($item->addcustommenus, 'component_custom_admin_menus', 'addcustommenus', $getter); @@ -2028,7 +2134,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addcustommenus); // update the dashboard_tab - if (isset($item->dashboard_tab) && ComponentbuilderHelper::checkJson($item->dashboard_tab)) + if (isset($item->dashboard_tab) && JsonHelper::check($item->dashboard_tab)) { // move the old data $this->setDivergedDataMover($item->dashboard_tab, 'component_dashboard', 'dashboard_tab', $getter); @@ -2045,7 +2151,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel unset($item->php_dashboard_methods); unset($item->add_php_dashboard_methods); // update the addfiles - if (isset($item->addfiles) && ComponentbuilderHelper::checkJson($item->addfiles)) + if (isset($item->addfiles) && JsonHelper::check($item->addfiles)) { // move the old data $this->setDivergedDataMover($item->addfiles, 'component_files_folders', 'addfiles', $getter); @@ -2053,7 +2159,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->addfiles); // update the addfolders - if (isset($item->addfolders) && ComponentbuilderHelper::checkJson($item->addfolders)) + if (isset($item->addfolders) && JsonHelper::check($item->addfolders)) { // move the old data $this->setDivergedDataMover($item->addfolders, 'component_files_folders', 'addfolders', $getter); @@ -2068,7 +2174,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // remove from this dataset unset($item->add_css); // update the css - if (isset($item->css) && ComponentbuilderHelper::checkString($item->css)) + if (isset($item->css) && StringHelper::check($item->css)) { $item->css_admin = $item->css; } @@ -2416,10 +2522,10 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // update the target ID where needed $item = $this->setNewID($item, $lang['target'], 'joomla_component', $type); // load the local targets if found - if (isset($item->{$lang['local']}) && ComponentbuilderHelper::checkJson($item->{$lang['local']})) + if (isset($item->{$lang['local']}) && JsonHelper::check($item->{$lang['local']})) { $targets = array(); - if (isset($item->{$lang['target']}) && ComponentbuilderHelper::checkJson($item->{$lang['target']})) + if (isset($item->{$lang['target']}) && JsonHelper::check($item->{$lang['target']})) { $targets = json_decode($item->{$lang['target']}, true); } @@ -2443,7 +2549,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel unset($item->{$lang['local']}); } // load it back - if (isset($targets) && ComponentbuilderHelper::checkArray($targets)) + if (isset($targets) && JCBArrayHelper::check($targets)) { // load it back $item->{$lang['target']} = json_encode(array_values($targets), JSON_FORCE_OBJECT); @@ -2451,8 +2557,8 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } // merge the translations where needed if (isset($item->translation) && isset($item->localTranslation) - && ComponentbuilderHelper::checkJson($item->translation) - && ComponentbuilderHelper::checkJson($item->localTranslation)) + && JsonHelper::check($item->translation) + && JsonHelper::check($item->localTranslation)) { $newTranslations = json_decode($item->translation, true); $localTranslations = json_decode($item->localTranslation, true); // always the new format @@ -2479,7 +2585,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // okay this is the new format lets merge on that basis - elseif (ComponentbuilderHelper::checkArray($newTranslations)) + elseif (JCBArrayHelper::check($newTranslations)) { $translations = $newTranslations; $pointer = count($translations); @@ -2502,17 +2608,17 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // okay seem to only have local translations - elseif (ComponentbuilderHelper::checkArray($localTranslations)) + elseif (JCBArrayHelper::check($localTranslations)) { $translations = $localTranslations; } // only update if we have translations - if (ComponentbuilderHelper::checkArray($translations)) + if (JCBArrayHelper::check($translations)) { $item->translation = json_encode($translations, JSON_FORCE_OBJECT); } } - elseif (isset($item->localTranslation) && ComponentbuilderHelper::checkJson($item->localTranslation)) + elseif (isset($item->localTranslation) && JsonHelper::check($item->localTranslation)) { $item->translation = $item->localTranslation; } @@ -2584,12 +2690,12 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } // update the repeatable fields - if (isset($updaterR) && ComponentbuilderHelper::checkArray($updaterR)) + if (isset($updaterR) && JCBArrayHelper::check($updaterR)) { $item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR); } // update the subform ids - if (isset($updaterT) && ComponentbuilderHelper::checkArray($updaterT)) + if (isset($updaterT) && JCBArrayHelper::check($updaterT)) { $this->updateSubformsIDs($item, $type, $updaterT); } @@ -2636,11 +2742,11 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * * @return viod */ - protected function removingFields($type, &$item) + private function removingFields($type, &$item) { // get the columns $columns = $this->getTableColumns("#__componentbuilder_" . $type); - if (ComponentbuilderHelper::checkArray($columns)) + if (JCBArrayHelper::check($columns)) { foreach ($item as $name => $value) { @@ -2649,7 +2755,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // we must show a warning that this field was not imported (but just once) if (!isset($this->fieldImportErrors[$type.$name])) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FIELD_BSB_NOT_FOUND_IN_LOCAL_DATABASE_TABLE_S_SO_IMPORTED_OF_ITS_VALUES_FAILED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN', $name, '#__componentbuilder_' . $type), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_FIELD_BSB_NOT_FOUND_IN_LOCAL_DATABASE_TABLE_S_SO_IMPORTED_OF_ITS_VALUES_FAILED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN', $name, '#__componentbuilder_' . $type), 'warning'); // make sure the message is not loaded again $this->fieldImportErrors[$type.$name] = true; } @@ -2667,7 +2773,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * * @return array */ - protected function getTableColumns($table) + private function getTableColumns($table) { // check if the columns are in memory if (!isset($this->tableColumns[$table])) @@ -2688,10 +2794,10 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * * @return bool */ - protected function setDivergedDataMover($values, $table, $type, $getters) + private function setDivergedDataMover($values, $table, $type, $getters) { // we need to move this to the new $table based on anchors - if (ComponentbuilderHelper::checkArray($getters)) + if (JCBArrayHelper::check($getters)) { if (!isset($this->divergedDataMover[$table])) { @@ -2712,12 +2818,12 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // display more import info if ($this->moreInfo) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_WE_SUCCESSFULLY_MOVED_BSB', ComponentbuilderHelper::safeString($type, 'Ww') . ' to ('.ComponentbuilderHelper::safeString($table, 'w').')'), 'success'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_WE_SUCCESSFULLY_MOVED_BSB', StringHelper::safe($type, 'Ww') . ' to ('.StringHelper::safe($table, 'w').')'), 'success'); } // success return true; } - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_WE_FAILED_TO_MOVE_BSB', ComponentbuilderHelper::safeString($type, 'Ww') . ' to ('.ComponentbuilderHelper::safeString($table, 'w').')'), 'warning'); + $this->app->enqueueMessage(Text::sprintf('COM_COMPONENTBUILDER_WE_FAILED_TO_MOVE_BSB', StringHelper::safe($type, 'Ww') . ' to ('.StringHelper::safe($table, 'w').')'), 'warning'); // failure return false; } @@ -2730,7 +2836,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * @return bool true on success * */ - protected function checkMultiFields($typeID) + private function checkMultiFields($typeID) { if(isset($this->isMultiple[$typeID])) { @@ -2759,12 +2865,12 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * @return string field type * */ - protected function getFieldType($id) + private function getFieldType($id) { if (!isset($this->fieldTypes[$id])) { - $properties = ComponentbuilderHelper::getVar('fieldtype', $id, 'id', 'properties'); - if (ComponentbuilderHelper::checkJson($properties)) + $properties = GetHelper::var('fieldtype', $id, 'id', 'properties'); + if (JsonHelper::check($properties)) { $properties = json_decode($properties, true); // check if this is old values for repeatable fields @@ -2777,7 +2883,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel { if ('type' === $property['name']) { - if (isset($property['example']) && ComponentbuilderHelper::checkString($property['example'])) + if (isset($property['example']) && StringHelper::check($property['example'])) { $this->fieldTypes[$id] = $property['example']; break; @@ -2786,9 +2892,9 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel } } // if not found - if (!isset($this->fieldTypes[$id]) && $name = ComponentbuilderHelper::getVar('fieldtype', $id, 'id', 'name')) + if (!isset($this->fieldTypes[$id]) && $name = GetHelper::var('fieldtype', $id, 'id', 'name')) { - $this->fieldTypes[$id] = ComponentbuilderHelper::safeString($name); + $this->fieldTypes[$id] = StringHelper::safe($name); } } // return the type @@ -2810,7 +2916,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * ID int on success * **/ - protected function updateLocalItem(&$item, $type, &$canState) + private function updateLocalItem(&$item, $type, &$canState) { // prep the item if ($update = $this->prepItem($item, $type, 'update')) @@ -2841,7 +2947,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * ID int on success * **/ - protected function addLocalItem(&$item, $type, $diverged = false) + private function addLocalItem(&$item, $type, $diverged = false) { // prep the item if ($add = $this->prepItem($item, $type, 'add', $diverged)) @@ -2872,7 +2978,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * ID int on success * **/ - protected function getLocalItem($item, $type, $retry = false, $get = 1, $diverged = false) + private function getLocalItem($item, $type, $retry = false, $get = 1, $diverged = false) { $query = $this->_db->getQuery(true); $query->select('a.*'); @@ -2882,7 +2988,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // we first try to get the item by GUID if ($get == 1 && isset($item->guid)) { - if (($item = ComponentbuilderHelper::getGUID($item->guid, $type, 'a.*')) !== false) + if (($item = GuidHelper::item($item->guid, $type, 'a.*')) !== false) { return $item; } @@ -2912,7 +3018,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // set to run query $runQuery = true; } - elseif (componentbuilderHelper::checkArray($get)) + elseif (JCBArrayHelper::check($get)) { foreach ($get as $field) { @@ -2923,7 +3029,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // set the value $value = $item->{$field}; // check if we have special value - if ($this->specialValue && ComponentbuilderHelper::checkArray($this->specialValue) && isset($this->specialValue[$field])) + if ($this->specialValue && JCBArrayHelper::check($this->specialValue) && isset($this->specialValue[$field])) { $value = $this->specialValue[$field]; } @@ -2936,7 +3042,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel { $query->where($this->_db->quoteName('a.' . $field) . ' = '. (float) $value); } - elseif(componentbuilderHelper::checkString($value)) // do not allow empty strings (since it could be major mis match) + elseif(StringHelper::check($value)) // do not allow empty strings (since it could be major mis match) { $query->where($this->_db->quoteName('a.' . $field) . ' = '. $this->_db->quote($value)); } @@ -2960,7 +3066,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // set the value $value = $item->{$get}; // check if we have special value - if ($this->specialValue && ComponentbuilderHelper::checkArray($this->specialValue) && isset($this->specialValue[$get])) + if ($this->specialValue && JCBArrayHelper::check($this->specialValue) && isset($this->specialValue[$get])) { $value = $this->specialValue[$get]; } @@ -2973,7 +3079,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel { $query->where($this->_db->quoteName('a.' . $get) . ' = '. (float) $value); } - elseif(componentbuilderHelper::checkString($value)) // do not allow empty strings (since it could be major mis match) + elseif(StringHelper::check($value)) // do not allow empty strings (since it could be major mis match) { $query->where($this->_db->quoteName('a.' . $get) . ' = '. $this->_db->quote($value)); } @@ -3137,20 +3243,20 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel // get by name ... $getter = array('name', 'gettype', 'main_source'); // risky will look at this again // add some more advanced search - if (isset($item->main_source) && $item->main_source == 1 && isset($item->view_selection) && ComponentbuilderHelper::checkString($item->view_selection)) + if (isset($item->main_source) && $item->main_source == 1 && isset($item->view_selection) && StringHelper::check($item->view_selection)) { $getter[] = 'view_selection'; } - elseif (isset($item->main_source) && $item->main_source == 2 && isset($item->db_selection) && ComponentbuilderHelper::checkString($item->db_selection)) + elseif (isset($item->main_source) && $item->main_source == 2 && isset($item->db_selection) && StringHelper::check($item->db_selection)) { $getter[] = 'db_selection'; } - elseif (isset($item->main_source) && $item->main_source == 3 && isset($item->php_custom_get) && ComponentbuilderHelper::checkString($item->php_custom_get)) + elseif (isset($item->main_source) && $item->main_source == 3 && isset($item->php_custom_get) && StringHelper::check($item->php_custom_get)) { $getter[] = 'php_custom_get'; } // add some extra - if (isset($item->getcustom) && ComponentbuilderHelper::checkString($item->getcustom)) + if (isset($item->getcustom) && StringHelper::check($item->getcustom)) { $getter[] = 'getcustom'; } @@ -3396,7 +3502,7 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * @return string The updated path * */ - protected function setFullPath($path) + private function setFullPath($path) { return str_replace(array_keys(ComponentbuilderHelper::$constantPaths), array_values(ComponentbuilderHelper::$constantPaths), $path); } @@ -3408,13 +3514,14 @@ class ComponentbuilderModelImport_joomla_components extends BaseDatabaseModel * * @return string The full path * */ - protected function setDynamicPath($path) + private function setDynamicPath($path) { // now convert to path $path = str_replace('__v_d_m__', '/', $path); // add the full path if possible return str_replace('//', '/', $this->setFullPath($path)); - } + } + protected function getAlias($name,$type = false) { diff --git a/admin/models/import_language_translations.php b/admin/models/import_language_translations.php index 7c85a0328..32548bcd2 100644 --- a/admin/models/import_language_translations.php +++ b/admin/models/import_language_translations.php @@ -17,6 +17,8 @@ use Joomla\CMS\Filesystem\File; use Joomla\CMS\Filesystem\Folder; use Joomla\Utilities\ArrayHelper; use PhpOffice\PhpSpreadsheet\IOFactory; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\StringHelper; /** * Componentbuilder Import_language_translations Base Database Model @@ -419,7 +421,7 @@ class ComponentbuilderModelImport_language_translations extends BaseDatabaseMode **/ protected function setData($package,$table,$target_headers) { - if (ComponentbuilderHelper::checkArray($target_headers)) + if (UtilitiesArrayHelper::check($target_headers)) { // make sure the file is loaded ComponentbuilderHelper::composerAutoload('phpspreadsheet'); @@ -510,7 +512,7 @@ class ComponentbuilderModelImport_language_translations extends BaseDatabaseMode $found = false; $has_id = false; // check that we have a string or a number<-(which is weird... but happens at times) - if ($canEdit && isset($row[$source_key]) && (ComponentbuilderHelper::checkString($row[$source_key]) || is_numeric($row[$source_key]))) + if ($canEdit && isset($row[$source_key]) && (StringHelper::check($row[$source_key]) || is_numeric($row[$source_key]))) { // raw items import & update! $query = $db->getQuery(true); diff --git a/admin/models/joomla_component.php b/admin/models/joomla_component.php index 087ddc912..8c1387b5c 100644 --- a/admin/models/joomla_component.php +++ b/admin/models/joomla_component.php @@ -16,6 +16,12 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\FOF\Encrypt\AES; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Joomla_component Admin Model @@ -101,7 +107,13 @@ class ComponentbuilderModelJoomla_component extends AdminModel 'note_update_server_note_other', 'update_server', 'add_sales_server', - 'sales_server' + 'sales_server', + 'add_backup_folder_path', + 'note_backup_folder_path', + 'backup_folder_path', + 'add_git_folder_path', + 'note_git_folder_path', + 'git_folder_path' ), 'right' => array( 'translation_tool', @@ -112,15 +124,6 @@ class ComponentbuilderModelJoomla_component extends AdminModel 'crowdin_account_api_key' ) ), - 'readme' => array( - 'left' => array( - 'addreadme', - 'readme' - ), - 'right' => array( - 'note_readme' - ) - ), 'dash_install' => array( 'left' => array( 'dashboard_type' @@ -152,6 +155,15 @@ class ComponentbuilderModelJoomla_component extends AdminModel 'assets_table_fix' ) ), + 'readme' => array( + 'left' => array( + 'addreadme', + 'readme' + ), + 'right' => array( + 'note_readme' + ) + ), 'dynamic_build_beta' => array( 'fullwidth' => array( 'note_buildcomp_dynamic_mysql', @@ -273,7 +285,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'joomla_component__'.$id); ComponentbuilderHelper::set('joomla_component__'.$id, $this->vastDevMod); // set a return value if found @@ -281,7 +293,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -342,24 +354,6 @@ class ComponentbuilderModelJoomla_component extends AdminModel $item->metadata = $registry->toArray(); } - if (!empty($item->php_helper_both)) - { - // base64 Decode php_helper_both. - $item->php_helper_both = base64_decode($item->php_helper_both); - } - - if (!empty($item->php_method_uninstall)) - { - // base64 Decode php_method_uninstall. - $item->php_method_uninstall = base64_decode($item->php_method_uninstall); - } - - if (!empty($item->php_preflight_install)) - { - // base64 Decode php_preflight_install. - $item->php_preflight_install = base64_decode($item->php_preflight_install); - } - if (!empty($item->css_admin)) { // base64 Decode css_admin. @@ -390,6 +384,24 @@ class ComponentbuilderModelJoomla_component extends AdminModel $item->sql_uninstall = base64_decode($item->sql_uninstall); } + if (!empty($item->php_preflight_install)) + { + // base64 Decode php_preflight_install. + $item->php_preflight_install = base64_decode($item->php_preflight_install); + } + + if (!empty($item->php_method_uninstall)) + { + // base64 Decode php_method_uninstall. + $item->php_method_uninstall = base64_decode($item->php_method_uninstall); + } + + if (!empty($item->buildcompsql)) + { + // base64 Decode buildcompsql. + $item->buildcompsql = base64_decode($item->buildcompsql); + } + if (!empty($item->php_helper_admin)) { // base64 Decode php_helper_admin. @@ -432,28 +444,22 @@ class ComponentbuilderModelJoomla_component extends AdminModel $item->sql = base64_decode($item->sql); } - if (!empty($item->buildcompsql)) - { - // base64 Decode buildcompsql. - $item->buildcompsql = base64_decode($item->buildcompsql); - } - if (!empty($item->readme)) { // base64 Decode readme. $item->readme = base64_decode($item->readme); } + if (!empty($item->php_helper_both)) + { + // base64 Decode php_helper_both. + $item->php_helper_both = base64_decode($item->php_helper_both); + } + // Get the basic encryption. $basickey = ComponentbuilderHelper::getCryptKey('basic'); // Get the encryption object. - $basic = new FOFEncryptAes($basickey); - - if (!empty($item->whmcs_key) && $basickey && !is_numeric($item->whmcs_key) && $item->whmcs_key === base64_encode(base64_decode($item->whmcs_key, true))) - { - // basic decrypt data whmcs_key. - $item->whmcs_key = rtrim($basic->decryptString($item->whmcs_key), "\0"); - } + $basic = new AES($basickey); if (!empty($item->crowdin_username) && $basickey && !is_numeric($item->crowdin_username) && $item->crowdin_username === base64_encode(base64_decode($item->crowdin_username, true))) { @@ -461,6 +467,12 @@ class ComponentbuilderModelJoomla_component extends AdminModel $item->crowdin_username = rtrim($basic->decryptString($item->crowdin_username), "\0"); } + if (!empty($item->whmcs_key) && $basickey && !is_numeric($item->whmcs_key) && $item->whmcs_key === base64_encode(base64_decode($item->whmcs_key, true))) + { + // basic decrypt data whmcs_key. + $item->whmcs_key = rtrim($basic->decryptString($item->whmcs_key), "\0"); + } + if (!empty($item->export_key) && $basickey && !is_numeric($item->export_key) && $item->export_key === base64_encode(base64_decode($item->export_key, true))) { // basic decrypt data export_key. @@ -504,7 +516,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'joomla_component__'.$id); ComponentbuilderHelper::set('joomla_component__'.$id, $this->vastDevMod); // set a return value if found @@ -512,7 +524,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -680,7 +692,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -695,7 +707,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } return $form; @@ -759,7 +771,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_component.edit.state', 'com_componentbuilder'); } @@ -925,7 +937,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel } // we must also delete the linked tables found - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { $_tablesArray = array( 'component_admin_views' => 'joomla_component', @@ -974,7 +986,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel } // we must also update all linked tables - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { $_tablesArray = array( 'component_admin_views' => 'joomla_component', @@ -1377,7 +1389,7 @@ class ComponentbuilderModelJoomla_component extends AdminModel } // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } @@ -1386,15 +1398,15 @@ class ComponentbuilderModelJoomla_component extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('joomla_component', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('joomla_component', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "joomla_component", $data['id'])) + while (!GuidHelper::valid($data['guid'], "joomla_component", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the addcontributors items to data. if (isset($data['addcontributors']) && is_array($data['addcontributors'])) @@ -1409,24 +1421,6 @@ class ComponentbuilderModelJoomla_component extends AdminModel $data['addcontributors'] = ''; } - // Set the php_helper_both string to base64 string. - if (isset($data['php_helper_both'])) - { - $data['php_helper_both'] = base64_encode($data['php_helper_both']); - } - - // Set the php_method_uninstall string to base64 string. - if (isset($data['php_method_uninstall'])) - { - $data['php_method_uninstall'] = base64_encode($data['php_method_uninstall']); - } - - // Set the php_preflight_install string to base64 string. - if (isset($data['php_preflight_install'])) - { - $data['php_preflight_install'] = base64_encode($data['php_preflight_install']); - } - // Set the css_admin string to base64 string. if (isset($data['css_admin'])) { @@ -1457,6 +1451,24 @@ class ComponentbuilderModelJoomla_component extends AdminModel $data['sql_uninstall'] = base64_encode($data['sql_uninstall']); } + // Set the php_preflight_install string to base64 string. + if (isset($data['php_preflight_install'])) + { + $data['php_preflight_install'] = base64_encode($data['php_preflight_install']); + } + + // Set the php_method_uninstall string to base64 string. + if (isset($data['php_method_uninstall'])) + { + $data['php_method_uninstall'] = base64_encode($data['php_method_uninstall']); + } + + // Set the buildcompsql string to base64 string. + if (isset($data['buildcompsql'])) + { + $data['buildcompsql'] = base64_encode($data['buildcompsql']); + } + // Set the php_helper_admin string to base64 string. if (isset($data['php_helper_admin'])) { @@ -1499,28 +1511,22 @@ class ComponentbuilderModelJoomla_component extends AdminModel $data['sql'] = base64_encode($data['sql']); } - // Set the buildcompsql string to base64 string. - if (isset($data['buildcompsql'])) - { - $data['buildcompsql'] = base64_encode($data['buildcompsql']); - } - // Set the readme string to base64 string. if (isset($data['readme'])) { $data['readme'] = base64_encode($data['readme']); } + // Set the php_helper_both string to base64 string. + if (isset($data['php_helper_both'])) + { + $data['php_helper_both'] = base64_encode($data['php_helper_both']); + } + // Get the basic encryption key. $basickey = ComponentbuilderHelper::getCryptKey('basic'); // Get the encryption object - $basic = new FOFEncryptAes($basickey); - - // Encrypt data whmcs_key. - if (isset($data['whmcs_key']) && $basickey) - { - $data['whmcs_key'] = $basic->encryptString($data['whmcs_key']); - } + $basic = new AES($basickey); // Encrypt data crowdin_username. if (isset($data['crowdin_username']) && $basickey) @@ -1528,6 +1534,12 @@ class ComponentbuilderModelJoomla_component extends AdminModel $data['crowdin_username'] = $basic->encryptString($data['crowdin_username']); } + // Encrypt data whmcs_key. + if (isset($data['whmcs_key']) && $basickey) + { + $data['whmcs_key'] = $basic->encryptString($data['whmcs_key']); + } + // Encrypt data export_key. if (isset($data['export_key']) && $basickey) { diff --git a/admin/models/joomla_components.php b/admin/models/joomla_components.php index 64d70fde8..926557775 100644 --- a/admin/models/joomla_components.php +++ b/admin/models/joomla_components.php @@ -14,6 +14,15 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Package\Factory as PackageFactory; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\ArrayHelper as JCBArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\Base64Helper; +use VDM\Joomla\FOF\Encrypt\AES; /** * Joomla_components List Model @@ -111,14 +120,14 @@ class ComponentbuilderModelJoomla_components extends ListModel } // has any data been set for this component - if (ComponentbuilderHelper::checkArray($pks)) + if (JCBArrayHelper::check($pks)) { // load the linked stuff $this->getLinkedToComponents($pks); } // has any data been set for this component - if (isset($this->smartBox['joomla_component']) && ComponentbuilderHelper::checkArray($this->smartBox['joomla_component'])) + if (isset($this->smartBox['joomla_component']) && JCBArrayHelper::check($this->smartBox['joomla_component'])) { // set the folder and move the files of each component to the folder return $this->smartCloner(); @@ -180,25 +189,22 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->packageName = 'JCB_smartPackage'; } } + // set the package path $this->packagePath = rtrim($this->backupPath, '/') . '/' . $this->packageName; $this->zipPath = rtrim($this->zipPath, '/') . '/' . $this->packageName .'.zip'; - if (JFolder::exists($this->packagePath)) + if (FileHelper::exists($this->packagePath)) { // remove if old folder is found ComponentbuilderHelper::removeFolder($this->packagePath); } + // create the folders JFolder::create($this->packagePath); - // Get the basic encryption. - $basickey = ComponentbuilderHelper::getCryptKey('basic'); - // Get the encryption object. - if ($basickey) - { - $basic = new FOFEncryptAes($basickey, 128); - } + // update $pks with returned IDs $pks = array(); + // start loading the components $this->smartBox['joomla_component'] = array(); foreach ($items as $nr => &$item) @@ -210,8 +216,10 @@ class ComponentbuilderModelJoomla_components extends ListModel unset($items[$nr]); continue; } + // make sure old fields are not exported any more $this->removeOldComponentValues($item); + // build information data set $this->info['name'][$item->id] = $item->name; $this->info['short_description'][$item->id] = $item->short_description; @@ -222,14 +230,15 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->info['website'][$item->id] = $item->website; $this->info['license'][$item->id] = $item->license; $this->info['copyright'][$item->id] = $item->copyright; + // set the keys - if (isset($item->export_key) && ComponentbuilderHelper::checkString($item->export_key)) + if (isset($item->export_key) && StringHelper::check($item->export_key)) { // keep the key locked for exported data set $export_key = $item->export_key; - if ($basickey && !is_numeric($item->export_key) && $item->export_key === base64_encode(base64_decode($item->export_key, true))) + if (!is_numeric($item->export_key) && $item->export_key === base64_encode(base64_decode($item->export_key, true))) { - $export_key = rtrim($basic->decryptString($item->export_key), "\0"); + $export_key = PackageFactory::_('Crypt')->decrypt($item->export_key, 'basic'); } // make sure we have a string if (strlen($export_key) > 4 ) @@ -237,27 +246,31 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->key[$item->id] = $export_key; } } + // get name of this item key_name if (isset($item->system_name)) { - $keyName = ComponentbuilderHelper::safeString($item->system_name, 'cAmel'); + $keyName = StringHelper::safe($item->system_name, 'cAmel'); } else { - $keyName = ComponentbuilderHelper::safeString($item->name_code); + $keyName = StringHelper::safe($item->name_code); } + // set the export buy links - if (isset($item->export_buy_link) && ComponentbuilderHelper::checkString($item->export_buy_link)) + if (isset($item->export_buy_link) && StringHelper::check($item->export_buy_link)) { // set the export buy link $this->info['export_buy_link'][$item->id] = $item->export_buy_link; } + // set the export buy links - if (isset($item->joomla_source_link) && ComponentbuilderHelper::checkString($item->joomla_source_link)) + if (isset($item->joomla_source_link) && StringHelper::check($item->joomla_source_link)) { // set the source link $this->info['joomla_source_link'][$item->id] = $item->joomla_source_link; } + // component image $this->moveIt(array($item->image), 'image'); // set the custom code ID's @@ -275,14 +288,14 @@ class ComponentbuilderModelJoomla_components extends ListModel } // has any data been set for this component - if (ComponentbuilderHelper::checkArray($pks)) + if (JCBArrayHelper::check($pks)) { // load the linked stuff $this->getLinkedToComponents($pks); } // has any data been set for this component - if (isset($this->smartBox['joomla_component']) && ComponentbuilderHelper::checkArray($this->smartBox['joomla_component'])) + if (isset($this->smartBox['joomla_component']) && JCBArrayHelper::check($this->smartBox['joomla_component'])) { // set the folder and move the files of each component to the folder return $this->smartExportBuilder(); @@ -319,7 +332,7 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->setData($table, $pks, $field); } // add fields conditions and relations - if (isset($this->smartIDs['admin_view']) && ComponentbuilderHelper::checkArray($this->smartIDs['admin_view'])) + if (isset($this->smartIDs['admin_view']) && JCBArrayHelper::check($this->smartIDs['admin_view'])) { $this->setData('admin_fields', array_values($this->smartIDs['admin_view']), 'admin_view'); $this->setData('admin_fields_conditions', array_values($this->smartIDs['admin_view']), 'admin_view'); @@ -327,41 +340,41 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->setData('admin_custom_tabs', array_values($this->smartIDs['admin_view']), 'admin_view'); } // add joomla module - if (isset($this->smartIDs['joomla_module']) && ComponentbuilderHelper::checkArray($this->smartIDs['joomla_module'])) + if (isset($this->smartIDs['joomla_module']) && JCBArrayHelper::check($this->smartIDs['joomla_module'])) { $this->setData('joomla_module', array_values($this->smartIDs['joomla_module']), 'id'); $this->setData('joomla_module_updates', array_values($this->smartIDs['joomla_module']), 'joomla_module'); $this->setData('joomla_module_files_folders_urls', array_values($this->smartIDs['joomla_module']), 'joomla_module'); } // add joomla plugin - if (isset($this->smartIDs['joomla_plugin']) && ComponentbuilderHelper::checkArray($this->smartIDs['joomla_plugin'])) + if (isset($this->smartIDs['joomla_plugin']) && JCBArrayHelper::check($this->smartIDs['joomla_plugin'])) { $this->setData('joomla_plugin', array_values($this->smartIDs['joomla_plugin']), 'id'); $this->setData('joomla_plugin_updates', array_values($this->smartIDs['joomla_plugin']), 'joomla_plugin'); $this->setData('joomla_plugin_files_folders_urls', array_values($this->smartIDs['joomla_plugin']), 'joomla_plugin'); } // add validation rules - if (isset($this->smartIDs['validation_rule']) && ComponentbuilderHelper::checkArray($this->smartIDs['validation_rule'])) + if (isset($this->smartIDs['validation_rule']) && JCBArrayHelper::check($this->smartIDs['validation_rule'])) { $this->setData('validation_rule', array_values($this->smartIDs['validation_rule']), 'name'); } // add field types - if (isset($this->smartIDs['fieldtype']) && ComponentbuilderHelper::checkArray($this->smartIDs['fieldtype'])) + if (isset($this->smartIDs['fieldtype']) && JCBArrayHelper::check($this->smartIDs['fieldtype'])) { $this->setData('fieldtype', array_values($this->smartIDs['fieldtype']), 'id'); } // add templates - if (isset($this->smartIDs['template']) && ComponentbuilderHelper::checkArray($this->smartIDs['template'])) + if (isset($this->smartIDs['template']) && JCBArrayHelper::check($this->smartIDs['template'])) { $this->setData('template', array_values($this->smartIDs['template']), 'id'); } // add layouts - if (isset($this->smartIDs['layout']) && ComponentbuilderHelper::checkArray($this->smartIDs['layout'])) + if (isset($this->smartIDs['layout']) && JCBArrayHelper::check($this->smartIDs['layout'])) { $this->setData('layout', array_values($this->smartIDs['layout']), 'id'); } // add dynamic get - if (isset($this->smartIDs['dynamic_get']) && ComponentbuilderHelper::checkArray($this->smartIDs['dynamic_get'])) + if (isset($this->smartIDs['dynamic_get']) && JCBArrayHelper::check($this->smartIDs['dynamic_get'])) { $this->setData('dynamic_get', array_values($this->smartIDs['dynamic_get']), 'id'); } @@ -369,49 +382,49 @@ class ComponentbuilderModelJoomla_components extends ListModel if ('clone' !== $this->activeType) { // add class_property - if (isset($this->smartIDs['class_property']) && ComponentbuilderHelper::checkArray($this->smartIDs['class_property'])) + if (isset($this->smartIDs['class_property']) && JCBArrayHelper::check($this->smartIDs['class_property'])) { $this->setData('class_property', array_values($this->smartIDs['class_property']), 'id'); } // add class_method - if (isset($this->smartIDs['class_method']) && ComponentbuilderHelper::checkArray($this->smartIDs['class_method'])) + if (isset($this->smartIDs['class_method']) && JCBArrayHelper::check($this->smartIDs['class_method'])) { $this->setData('class_method', array_values($this->smartIDs['class_method']), 'id'); } // add joomla_plugin_group - if (isset($this->smartIDs['joomla_plugin_group']) && ComponentbuilderHelper::checkArray($this->smartIDs['joomla_plugin_group'])) + if (isset($this->smartIDs['joomla_plugin_group']) && JCBArrayHelper::check($this->smartIDs['joomla_plugin_group'])) { $this->setData('joomla_plugin_group', array_values($this->smartIDs['joomla_plugin_group']), 'id'); } // add class_extends - if (isset($this->smartIDs['class_extends']) && ComponentbuilderHelper::checkArray($this->smartIDs['class_extends'])) + if (isset($this->smartIDs['class_extends']) && JCBArrayHelper::check($this->smartIDs['class_extends'])) { $this->setData('class_extends', array_values($this->smartIDs['class_extends']), 'id'); } // add snippets - if (isset($this->smartIDs['snippet']) && ComponentbuilderHelper::checkArray($this->smartIDs['snippet'])) + if (isset($this->smartIDs['snippet']) && JCBArrayHelper::check($this->smartIDs['snippet'])) { $this->setData('snippet', array_values($this->smartIDs['snippet']), 'id'); } // add custom code - if (isset($this->smartIDs['custom_code']) && ComponentbuilderHelper::checkArray($this->smartIDs['custom_code'])) + if (isset($this->smartIDs['custom_code']) && JCBArrayHelper::check($this->smartIDs['custom_code'])) { $this->setData('custom_code', array_values($this->smartIDs['custom_code']), 'id'); } // add placeholder - if (isset($this->smartIDs['placeholder']) && ComponentbuilderHelper::checkArray($this->smartIDs['placeholder'])) + if (isset($this->smartIDs['placeholder']) && JCBArrayHelper::check($this->smartIDs['placeholder'])) { $this->setData('placeholder', array_values($this->smartIDs['placeholder']), 'id'); } // add powers - if (isset($this->smartIDs['power']) && ComponentbuilderHelper::checkArray($this->smartIDs['power'])) + if (isset($this->smartIDs['power']) && JCBArrayHelper::check($this->smartIDs['power'])) { $this->setData('power', array_values($this->smartIDs['power']), 'guid'); } // set limiter $limit = 0; // and add those custom codes found in custom codes - while (isset($this->smartIDs['custom_code']) && ComponentbuilderHelper::checkArray($this->smartIDs['custom_code']) && $limit < 100) + while (isset($this->smartIDs['custom_code']) && JCBArrayHelper::check($this->smartIDs['custom_code']) && $limit < 100) { $this->setData('custom_code', array_values($this->smartIDs['custom_code']), 'id'); // make sure we break @@ -428,15 +441,15 @@ class ComponentbuilderModelJoomla_components extends ListModel protected function getComponents($pks) { // setup the query - if (ComponentbuilderHelper::checkArray($pks)) + if (JCBArrayHelper::check($pks)) { // Get the user object. - if (!ComponentbuilderHelper::checkObject($this->user)) + if (!ObjectHelper::check($this->user)) { $this->user = JFactory::getUser(); } // Create a new query object. - if (!ComponentbuilderHelper::checkObject($this->_db)) + if (!ObjectHelper::check($this->_db)) { $this->_db = JFactory::getDBO(); } @@ -467,10 +480,10 @@ class ComponentbuilderModelJoomla_components extends ListModel // load the items from db $items = $this->_db->loadObjectList(); // check if we have items - if (ComponentbuilderHelper::checkArray($items)) + if (JCBArrayHelper::check($items)) { // set params - if (!ComponentbuilderHelper::checkObject($this->params)) + if (!ObjectHelper::check($this->params)) { $this->params = JComponentHelper::getParams('com_componentbuilder'); } @@ -515,30 +528,30 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->smartIDs[$table] = array(); } // convert if value is in json - if (ComponentbuilderHelper::checkJson($value)) + if (JsonHelper::check($value)) { $value = json_decode($value, true); } // now update the fields - if (ComponentbuilderHelper::checkArray($value)) + if (JCBArrayHelper::check($value)) { foreach ($value as $id) { - if ($int && (ComponentbuilderHelper::checkString($id) || is_numeric($id)) && 0 !== (int) $id) + if ($int && (StringHelper::check($id) || is_numeric($id)) && 0 !== (int) $id) { $this->smartIDs[$table][(int) $id] = (int) $id; } - elseif (!$int && ComponentbuilderHelper::checkString($id)) + elseif (!$int && StringHelper::check($id)) { $this->smartIDs[$table][$id] = $this->_db->quote($id); } } } - elseif ($int && (ComponentbuilderHelper::checkString($value) || is_numeric($value)) && 0 !== (int) $value) + elseif ($int && (StringHelper::check($value) || is_numeric($value)) && 0 !== (int) $value) { $this->smartIDs[$table][(int) $value] = (int) $value; } - elseif (!$int && ComponentbuilderHelper::checkString($value)) + elseif (!$int && StringHelper::check($value)) { $this->smartIDs[$table][$value] = $this->_db->quote($value); } @@ -554,12 +567,12 @@ class ComponentbuilderModelJoomla_components extends ListModel // the ids bucket $bucket = array(); // if json convert to array - if (ComponentbuilderHelper::checkJson($values)) + if (JsonHelper::check($values)) { $values = json_decode($values, true); } // check that the array has values - if (ComponentbuilderHelper::checkArray($values)) + if (JCBArrayHelper::check($values)) { // check if the key is an array (targeting subform) if ('subform' === $type && $key) @@ -572,7 +585,7 @@ class ComponentbuilderModelJoomla_components extends ListModel { $bucket[] = $value[$key]; } - elseif (ComponentbuilderHelper::checkString($value[$key])) + elseif (StringHelper::check($value[$key])) { if ('table' === $prep) { @@ -586,7 +599,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } } // only return if we set the ids - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { // now set the values back return array_unique($bucket); @@ -598,7 +611,7 @@ class ComponentbuilderModelJoomla_components extends ListModel $_key = explode('.', $key); foreach ($values as $value) { - if (isset($value[$_key[0]]) && ComponentbuilderHelper::checkArray($value[$_key[0]])) + if (isset($value[$_key[0]]) && JCBArrayHelper::check($value[$_key[0]])) { foreach ($value[$_key[0]] as $_value) { @@ -606,7 +619,7 @@ class ComponentbuilderModelJoomla_components extends ListModel { $bucket[] = $_value[$_key[1]]; } - elseif (ComponentbuilderHelper::checkString($_value[$_key[1]])) + elseif (StringHelper::check($_value[$_key[1]])) { if ('table' === $prep) { @@ -621,7 +634,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } } // only return if we set the ids - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { // now set the values back return array_unique($bucket); @@ -637,7 +650,7 @@ class ComponentbuilderModelJoomla_components extends ListModel { return $value; } - elseif (ComponentbuilderHelper::checkString($value)) + elseif (StringHelper::check($value)) { if ('table' === $prep) { @@ -658,11 +671,11 @@ class ComponentbuilderModelJoomla_components extends ListModel { foreach ($values[$key] as $k => $val) { - if (strpos($k, 'power_') !== false && ComponentbuilderHelper::checkArray($val)) + if (strpos($k, 'power_') !== false && JCBArrayHelper::check($val)) { foreach ($val as $v) { - if (ComponentbuilderHelper::checkArray($v) && isset($v['power'])) + if (JCBArrayHelper::check($v) && isset($v['power'])) { $bucket[$v['power']] = $v['power']; } @@ -670,7 +683,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } } // only return if we set the ids - if (ComponentbuilderHelper::checkArray($bucket)) + if (JCBArrayHelper::check($bucket)) { // now return the values back return array_values($bucket); @@ -689,21 +702,30 @@ class ComponentbuilderModelJoomla_components extends ListModel protected function setData($table, $values, $key, $string = false) { // lets check for json strings - if (ComponentbuilderHelper::checkJson($values)) + if (JsonHelper::check($values)) { $values = json_decode($values, true); } + // let's check for just a string or int + elseif (is_string($values) || (is_numeric($values) && $values > 0)) + { + $values = [$values]; + } + // make sure we have an array of values - if (!ComponentbuilderHelper::checkArray($values, true) || !ComponentbuilderHelper::checkString($table) || !ComponentbuilderHelper::checkString($key)) + if (!JCBArrayHelper::check($values, true) || !StringHelper::check($table) || !StringHelper::check($key)) { return false; } + // start the query $query = $this->_db->getQuery(true); // Select some fields $query->select(array('a.*')); + // From the componentbuilder_ANY table $query->from($this->_db->quoteName('#__componentbuilder_'. $table, 'a')); + // check if this is an array of integers if ($this->is_numeric($values)) { @@ -722,12 +744,14 @@ class ComponentbuilderModelJoomla_components extends ListModel return $this->_db->quote($var); }, $values)) . ')'); } + // Implement View Level Access if (!$this->user->authorise('core.options', 'com_componentbuilder')) { $groups = implode(',', $this->user->getAuthorisedViewLevels()); $query->where('a.access IN (' . $groups . ')'); } + // Order the results by ordering $query->order('a.ordering ASC'); // Load the items @@ -740,7 +764,7 @@ class ComponentbuilderModelJoomla_components extends ListModel // reset the search array (only search for template/layouts) $searchTLArray = array(); // check if we have items - if (ComponentbuilderHelper::checkArray($items)) + if (JCBArrayHelper::check($items)) { // set search array if site/custom admin view if ('site_view' === $table || 'custom_admin_view' === $table) @@ -892,7 +916,7 @@ class ComponentbuilderModelJoomla_components extends ListModel if ('component_modules' === $table) { // we remove those modules not part of the export - if (isset($item->addjoomla_modules) && ComponentbuilderHelper::checkJson($item->addjoomla_modules)) + if (isset($item->addjoomla_modules) && JsonHelper::check($item->addjoomla_modules)) { $item->addjoomla_modules = array_filter( json_decode($item->addjoomla_modules, true), @@ -913,7 +937,7 @@ class ComponentbuilderModelJoomla_components extends ListModel if ('component_plugins' === $table) { // we remove those plugins not part of the export - if (isset($item->addjoomla_plugins) && ComponentbuilderHelper::checkJson($item->addjoomla_plugins)) + if (isset($item->addjoomla_plugins) && JsonHelper::check($item->addjoomla_plugins)) { $item->addjoomla_plugins = array_filter( json_decode($item->addjoomla_plugins, true), @@ -976,7 +1000,7 @@ class ComponentbuilderModelJoomla_components extends ListModel // check if this field has multiple fields if ($this->checkMultiFields($item->fieldtype)) { - $fields = ComponentbuilderHelper::getBetween(json_decode($item->xml), 'fields="', '"'); + $fields = GetHelper::between(json_decode($item->xml), 'fields="', '"'); $fieldsSets = array(); if (strpos($fields, ',') !== false) { @@ -989,17 +1013,17 @@ class ComponentbuilderModelJoomla_components extends ListModel $fieldsSets[] = (int) $fields; } // get fields - if (ComponentbuilderHelper::checkArray($fieldsSets)) + if (JCBArrayHelper::check($fieldsSets)) { $this->setData('field', $fieldsSets, 'id'); } } // check if validation rule is found - $validationRule = ComponentbuilderHelper::getBetween(json_decode($item->xml), 'validate="', '"'); - if (ComponentbuilderHelper::checkString($validationRule)) + $validationRule = GetHelper::between(json_decode($item->xml), 'validate="', '"'); + if (StringHelper::check($validationRule)) { // make sure it is lowercase - $validationRule = ComponentbuilderHelper::safeString($validationRule); + $validationRule = StringHelper::safe($validationRule); // get core validation rules if ($coreValidationRules = ComponentbuilderHelper::getExistingValidationRuleNames(true)) { @@ -1013,7 +1037,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } } // check if a search is required - if (isset($searchTLArray) && ComponentbuilderHelper::checkArray($searchTLArray)){ + if (isset($searchTLArray) && JCBArrayHelper::check($searchTLArray)){ // add search array templates and layouts foreach ($searchTLArray as $scripter => $add) @@ -1169,7 +1193,7 @@ class ComponentbuilderModelJoomla_components extends ListModel protected function smartCloner() { // check if data is set - if (isset($this->smartBox) && ComponentbuilderHelper::checkArray($this->smartBox)) + if (isset($this->smartBox) && JCBArrayHelper::check($this->smartBox)) { // get the import_joomla_components $model = ComponentbuilderHelper::getModel('import_joomla_components'); @@ -1178,7 +1202,7 @@ class ComponentbuilderModelJoomla_components extends ListModel // trigger the create new (clone) feature $model->canmerge = 0; // set some postfix - $model->postfix = ' ('.ComponentbuilderHelper::randomkey(2).')'; + $model->postfix = ' ('.StringHelper::random(2).')'; // get App $model->app = JFactory::getApplication(); // set user @@ -1227,10 +1251,11 @@ class ComponentbuilderModelJoomla_components extends ListModel protected function smartExportBuilder() { // check if data is set - if (isset($this->smartBox) && ComponentbuilderHelper::checkArray($this->smartBox)) + if (isset($this->smartBox) && JCBArrayHelper::check($this->smartBox)) { // set db data $data = serialize($this->smartBox); + // Set the key owner information $this->info['source'] = array(); $this->info['source']['company'] = $this->params->get('export_company', null); @@ -1239,26 +1264,16 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->info['source']['website'] = $this->params->get('export_website', null); $this->info['source']['license'] = $this->params->get('export_license', null); $this->info['source']['copyright'] = $this->params->get('export_copyright', null); + // lock the data if set - if (ComponentbuilderHelper::checkArray($this->key)) + if (JCBArrayHelper::check($this->key)) { // lock the data $this->key = md5(implode('', $this->key)); - // April 20, 2022 we moved away from FOF for good... sorry that it took this long - // $locker = new FOFEncryptAes($this->key, 128); - // $data = $locker->encryptString($data); - // load phpseclib - if(ComponentbuilderHelper::crypt('AES', 'CBC') instanceof \phpseclib\Crypt\Rijndael) - { - // set the password - ComponentbuilderHelper::crypt('AES', 'CBC')->setPassword($this->key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); - // lock the data - $data = base64_encode(ComponentbuilderHelper::crypt('AES', 'CBC')->encrypt($data)); - } - else - { - return false; - } + + // lock the data + $data = PackageFactory::_('Crypt')->encrypt($data, 'aes', $this->key); + // Set the key owner information $this->info['getKeyFrom'] = array(); $this->info['getKeyFrom']['company'] = $this->info['source']['company']; @@ -1268,13 +1283,16 @@ class ComponentbuilderModelJoomla_components extends ListModel $this->info['getKeyFrom']['license'] = $this->info['source']['license']; $this->info['getKeyFrom']['copyright'] = $this->info['source']['copyright']; // add buy link if only one link is set - if (isset($this->info['export_buy_link']) && ComponentbuilderHelper::checkArray($this->info['export_buy_link']) && count((array) $this->info['export_buy_link']) == 1) + if (isset($this->info['export_buy_link']) + && JCBArrayHelper::check($this->info['export_buy_link']) + && count((array) $this->info['export_buy_link']) == 1) { $this->info['getKeyFrom']['buy_link'] = array_values($this->info['export_buy_link'])[0]; } else { - // use global if more then one component is exported (since they now have one key), or if none has a buy link + // use global if more then one component is exported + // (since they now have one key), or if none has a buy link $this->info['getKeyFrom']['buy_link'] = $this->params->get('export_buy_link', null); } // no remove the buy links @@ -1282,75 +1300,82 @@ class ComponentbuilderModelJoomla_components extends ListModel // if we have multi links add them also // we started adding this at v2.7.7 $this->info['key'] = true; - // we started adding this at v3.0.11 and v2.12.17 - $this->info['phpseclib'] = true; + // Changed: 25th Feb. 2023 at v3.1.18 + // $this->info['phpseclib'] = false; + // we started adding this at v3.1.18 + $this->info['phpseclib3'] = true; } else { // we started adding this at v2.7.7 $this->info['key'] = false; // we started adding this at v3.0.11 and v2.12.17 - $this->info['phpseclib'] = false; + // $this->info['phpseclib'] = false; + // we started adding this at v3.1.18 + $this->info['phpseclib3'] = false; // base 64 encode the data $data = base64_encode($data); } + // set the path $dbPath = $this->packagePath . '/db.vdm'; + // write the db data to file in package - if (!ComponentbuilderHelper::writeFile($dbPath, wordwrap($data, 128, "\n", true))) + if (!FileHelper::write($dbPath, wordwrap($data, 128, "\n", true))) { return false; } - // set info data - if(ComponentbuilderHelper::crypt('AES', 'CBC') instanceof \phpseclib\Crypt\Rijndael) + + // lock the info data + $info = PackageFactory::_('Crypt')->encrypt(json_encode($this->info), 'local'); + + // set the path + $infoPath = $this->packagePath . '/info.vdm'; + + // write the info data to file in package + if (!FileHelper::write($infoPath, wordwrap($info, 128, "\n", true))) { - // set system password - $db = 'COM_COMPONENTBUILDER_SZDEQZDMVSMHBTRWFIFTYTSQFLVVXJTMTHREEJTWOIXM'; - $password = base64_decode(JText::sprintf($db, 'VjR', 'WV0aE9k')); - // set the password - ComponentbuilderHelper::crypt('AES', 'CBC')->setPassword($password, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); - // lock the data - $info = base64_encode(ComponentbuilderHelper::crypt('AES', 'CBC')->encrypt(json_encode($this->info))); - // set the path - $infoPath = $this->packagePath . '/info.vdm'; - // write the info data to file in package - if (!ComponentbuilderHelper::writeFile($infoPath, wordwrap($info, 128, "\n", true))) - { - return false; - } - } - else - { - return false; + return false; } + // lock all files $this->lockFiles(); + // remove old zip files with the same name if (JFile::exists($this->zipPath)) { // remove file if found JFile::delete($this->zipPath); } + // zip the folder - if (!ComponentbuilderHelper::zip($this->packagePath, $this->zipPath)) + if (!FileHelper::zip($this->packagePath, $this->zipPath)) { return false; } + // move to remote server if needed if (2 == $this->backupType) { - if (!ComponentbuilderHelper::moveToServer($this->zipPath, $this->packageName.'.zip', $this->backupServer, null, 'joomla_component.export')) + if (!PackageFactory::_('Server')->legacyMove( + $this->zipPath, $this->packageName.'.zip', + $this->backupServer, null, 'joomla_component.export' + ) + ) { return false; } + // remove the local file JFile::delete($this->zipPath); } + // remove the folder if (!ComponentbuilderHelper::removeFolder($this->packagePath)) { return false; } + return true; } return false; @@ -1364,25 +1389,27 @@ class ComponentbuilderModelJoomla_components extends ListModel protected function lockFiles() { // lock the data if set - if (ComponentbuilderHelper::checkString($this->key) && strlen($this->key) == 32) + if (StringHelper::check($this->key) && strlen($this->key) == 32) { - // set secure password - ComponentbuilderHelper::crypt('AES', 'CBC')->setPassword($this->key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); // we must first store the current working directory $joomla = getcwd(); + // to avoid that it encrypt the db and info file again we must move per/folder $folders = array('images', 'custom', 'dynamic'); + // loop the folders foreach ($folders as $folder) { // the sub path $subPath = $this->packagePath.'/'.$folder; + // go to the package sub folder if found - if (JFolder::exists($subPath)) + if (FileHelper::exists($subPath)) { $this->lock($subPath); } } + // change back to working dir chdir($joomla); } @@ -1397,16 +1424,21 @@ class ComponentbuilderModelJoomla_components extends ListModel { // we are changing the working directory to the tmp path (important) chdir($tmpPath); + // get a list of files in the current directory tree (all) $files = JFolder::files('.', '.', true, true); + // read in the file content foreach ($files as $file) { + // get file content + $content = FileHelper::getContent($file); + // write the encrypted string back to file - if (!ComponentbuilderHelper::writeFile($file, wordwrap(base64_encode(ComponentbuilderHelper::crypt('AES', 'CBC')->encrypt(file_get_contents($file))), 128, "\n", true))) - { - // we should add error handler here in case file could not be locked - } + $content = PackageFactory::_('Crypt')->encrypt($content, 'eac', $this->key); + + // store the encrypted file content in the same file + FileHelper::write($file, wordwrap($content, 128, "\n", true)); } } @@ -1418,10 +1450,11 @@ class ComponentbuilderModelJoomla_components extends ListModel protected function moveIt($paths, $type, $dynamic = false) { // make sure we have an array - if (!ComponentbuilderHelper::checkArray($paths)) + if (!JCBArrayHelper::check($paths)) { return false; } + // set the name of the folder if ('file' === $type || 'folder' === $type) { @@ -1440,19 +1473,22 @@ class ComponentbuilderModelJoomla_components extends ListModel { return false; } + // setup the type path $tmpPath = str_replace('//', '/', $this->packagePath . '/' . $folderName); + // create type path if not set - if (!JFolder::exists($tmpPath)) + if (!FileHelper::exists($tmpPath)) { // create the folders if not found JFolder::create($tmpPath); } + // now move it foreach ($paths as $item) { // make sure we have a string - if (ComponentbuilderHelper::checkString($item)) + if (StringHelper::check($item)) { // if the file type if ('file' === $type) @@ -1475,14 +1511,16 @@ class ComponentbuilderModelJoomla_components extends ListModel JFile::copy($customFilePath, $tmpFilePath); } } + // if the image type if ('image' === $type) { $imageName = basename($item); $imagePath = str_replace($imageName, '', $item); $imageFolderPath = str_replace('//', '/', $this->packagePath.'/'. $imagePath); + // check if image folder exist - if (!JFolder::exists($imageFolderPath)) + if (!FileHelper::exists($imageFolderPath)) { // create the folders if not found JFolder::create($imageFolderPath); @@ -1495,6 +1533,7 @@ class ComponentbuilderModelJoomla_components extends ListModel JFile::copy($customImagePath, $tmpImagePath); } } + // if the folder type if ('folder' === $type) { @@ -1509,7 +1548,8 @@ class ComponentbuilderModelJoomla_components extends ListModel $tmpFolderPath = str_replace('//', '/', $tmpPath.'/'.$item); $customFolderPath = str_replace('//', '/', $this->customPath.'/'.$item); } - if (!JFolder::exists($tmpFolderPath) && JFolder::exists($customFolderPath)) + + if (!FileHelper::exists($tmpFolderPath) && FileHelper::exists($customFolderPath)) { // move the folder to its place JFolder::copy($customFolderPath, $tmpFolderPath,'',true); @@ -1562,14 +1602,14 @@ class ComponentbuilderModelJoomla_components extends ListModel if (!isset($this->fieldTypes[$id])) { $properties = ComponentbuilderHelper::getVar('fieldtype', $id, 'id', 'properties'); - if (ComponentbuilderHelper::checkJson($properties)) + if (JsonHelper::check($properties)) { $properties = json_decode($properties, true); foreach ($properties as $property) { if ('type' === $property['name']) { - if (isset($property['example']) && ComponentbuilderHelper::checkString($property['example'])) + if (isset($property['example']) && StringHelper::check($property['example'])) { $this->fieldTypes[$id] = $property['example']; break; @@ -1580,7 +1620,7 @@ class ComponentbuilderModelJoomla_components extends ListModel // if not found if (!isset($this->fieldTypes[$id]) && $name = ComponentbuilderHelper::getVar('fieldtype', $id, 'id', 'name')) { - $this->fieldTypes[$id] = ComponentbuilderHelper::safeString($name); + $this->fieldTypes[$id] = StringHelper::safe($name); } } // return the type @@ -1607,31 +1647,31 @@ class ComponentbuilderModelJoomla_components extends ListModel $default = base64_decode($default); } // set the Template data - $temp1 = ComponentbuilderHelper::getAllBetween($default, "\$this->loadTemplate('","')"); - $temp2 = ComponentbuilderHelper::getAllBetween($default, '$this->loadTemplate("','")'); + $temp1 = GetHelper::allBetween($default, "\$this->loadTemplate('","')"); + $temp2 = GetHelper::allBetween($default, '$this->loadTemplate("','")'); $templates = array(); $again = array(); - if (ComponentbuilderHelper::checkArray($temp1) && ComponentbuilderHelper::checkArray($temp2)) + if (JCBArrayHelper::check($temp1) && JCBArrayHelper::check($temp2)) { $templates = array_merge($temp1,$temp2); } else { - if (ComponentbuilderHelper::checkArray($temp1)) + if (JCBArrayHelper::check($temp1)) { $templates = $temp1; } - elseif (ComponentbuilderHelper::checkArray($temp2)) + elseif (JCBArrayHelper::check($temp2)) { $templates = $temp2; } } - if (ComponentbuilderHelper::checkArray($templates)) + if (JCBArrayHelper::check($templates)) { foreach ($templates as $template) { $data = $this->getDataWithAlias($template, 'template'); - if (ComponentbuilderHelper::checkArray($data)) + if (JCBArrayHelper::check($data)) { if (!isset($this->smartIDs['template']) || !isset($this->smartIDs['template'][$data['id']])) { @@ -1644,29 +1684,29 @@ class ComponentbuilderModelJoomla_components extends ListModel } } // set the layout data - $lay1 = ComponentbuilderHelper::getAllBetween($default, "JLayoutHelper::render('","',"); - $lay2 = ComponentbuilderHelper::getAllBetween($default, 'JLayoutHelper::render("','",'); - if (ComponentbuilderHelper::checkArray($lay1) && ComponentbuilderHelper::checkArray($lay2)) + $lay1 = GetHelper::allBetween($default, "JLayoutHelper::render('","',"); + $lay2 = GetHelper::allBetween($default, 'JLayoutHelper::render("','",'); + if (JCBArrayHelper::check($lay1) && JCBArrayHelper::check($lay2)) { $layouts = array_merge($lay1,$lay2); } else { - if (ComponentbuilderHelper::checkArray($lay1)) + if (JCBArrayHelper::check($lay1)) { $layouts = $lay1; } - elseif (ComponentbuilderHelper::checkArray($lay2)) + elseif (JCBArrayHelper::check($lay2)) { $layouts = $lay2; } } - if (isset($layouts) && ComponentbuilderHelper::checkArray($layouts)) + if (isset($layouts) && JCBArrayHelper::check($layouts)) { foreach ($layouts as $layout) { $data = $this->getDataWithAlias($layout, 'layout'); - if (ComponentbuilderHelper::checkArray($data)) + if (JCBArrayHelper::check($data)) { if (!isset($this->smartIDs['layout']) || !isset($this->smartIDs['layout'][$data['id']])) { @@ -1678,7 +1718,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } } } - if (ComponentbuilderHelper::checkArray($again)) + if (JCBArrayHelper::check($again)) { foreach ($again as $get) { @@ -1689,12 +1729,12 @@ class ComponentbuilderModelJoomla_components extends ListModel if ($user) { // add templates - if (isset($this->smartIDs['template']) && ComponentbuilderHelper::checkArray($this->smartIDs['template'])) + if (isset($this->smartIDs['template']) && JCBArrayHelper::check($this->smartIDs['template'])) { $this->setData('template', array_values($this->smartIDs['template']), 'id'); } // add layouts - if (isset($this->smartIDs['layout']) && ComponentbuilderHelper::checkArray($this->smartIDs['layout'])) + if (isset($this->smartIDs['layout']) && JCBArrayHelper::check($this->smartIDs['layout'])) { $this->setData('layout', array_values($this->smartIDs['layout']), 'id'); } @@ -1721,7 +1761,7 @@ class ComponentbuilderModelJoomla_components extends ListModel $rows = $this->_db->loadObjectList(); foreach ($rows as $row) { - $k_ey = ComponentbuilderHelper::safeString($row->alias); + $k_ey = StringHelper::safe($row->alias); $key = preg_replace("/[^A-Za-z]/", '', $k_ey); $name = preg_replace("/[^A-Za-z]/", '', $n_ame); if ($k_ey == $n_ame || $key == $name) @@ -1761,7 +1801,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } elseif (!isset($keys['not_base64'][$key])) { - $value = ComponentbuilderHelper::openValidBase64($item->{$key}, null); + $value = Base64Helper::open($item->{$key}, null); } elseif (isset($keys['not_base64'][$key]) && 'json' === $keys['not_base64'][$key] && 'xml' === $key) // just for field search { @@ -1782,8 +1822,8 @@ class ComponentbuilderModelJoomla_components extends ListModel if ('custom_code' === $type) { // search the value to see if it has custom code - $codeArray = ComponentbuilderHelper::getAllBetween($value, '[CUSTOMC' . 'ODE=',']'); - if (ComponentbuilderHelper::checkArray($codeArray)) + $codeArray = GetHelper::allBetween($value, '[CUSTOMC' . 'ODE=',']'); + if (JCBArrayHelper::check($codeArray)) { foreach ($codeArray as $func) { @@ -1801,7 +1841,7 @@ class ComponentbuilderModelJoomla_components extends ListModel { $this->setSmartIDs($func, $type); } - elseif (ComponentbuilderHelper::checkString($func)) + elseif (StringHelper::check($func)) { if (($funcID = ComponentbuilderHelper::getVar($type, $func, 'function_name', 'id')) !== false && is_numeric($funcID)) { @@ -1819,12 +1859,12 @@ class ComponentbuilderModelJoomla_components extends ListModel elseif ('placeholder' === $type) { // check if we already have the placeholder search array - if (!componentbuilderHelper::checkArray($this->placeholderM) && !componentbuilderHelper::checkArray($this->placeholderS)) + if (!JCBArrayHelper::check($this->placeholderM) && !JCBArrayHelper::check($this->placeholderS)) { $this->placeholderS = ComponentbuilderHelper::getVars($type, 1, 'published', 'target'); } // only continue search if placeholders found - if (componentbuilderHelper::checkArray($this->placeholderS)) + if (JCBArrayHelper::check($this->placeholderS)) { foreach ($this->placeholderS as $remove => $placeholder) { @@ -1887,7 +1927,7 @@ class ComponentbuilderModelJoomla_components extends ListModel { $items = $this->_db->loadObjectList(); // check if we have items - if (ComponentbuilderHelper::checkArray($items)) + if (JCBArrayHelper::check($items)) { if (!isset($this->smartBox['language_translation'])) { @@ -1895,7 +1935,7 @@ class ComponentbuilderModelJoomla_components extends ListModel } foreach ($items as $item) { - if (!isset($this->smartBox['language_translation'][$item->id]) && ComponentbuilderHelper::checkJson($item->{$target})) + if (!isset($this->smartBox['language_translation'][$item->id]) && JsonHelper::check($item->{$target})) { $targets = json_decode($item->{$target}, true); if (in_array($id, $targets)) @@ -1928,11 +1968,11 @@ class ComponentbuilderModelJoomla_components extends ListModel { if (isset($item->system_name)) { - return ComponentbuilderHelper::safeString($item->system_name, 'cAmel'); + return StringHelper::safe($item->system_name, 'cAmel'); } else { - return ComponentbuilderHelper::safeString($item->name_code); + return StringHelper::safe($item->name_code); } } } @@ -1995,9 +2035,9 @@ class ComponentbuilderModelJoomla_components extends ListModel if (isset($target['_start'])) { // get all values - $allBetween = ComponentbuilderHelper::getAllBetween($value, $target['start'], $target['_start']); + $allBetween = GetHelper::allBetween($value, $target['start'], $target['_start']); // just again make sure we found some - if (ComponentbuilderHelper::checkArray($allBetween)) + if (JCBArrayHelper::check($allBetween)) { if (count((array) $allBetween) > 1) { @@ -2028,14 +2068,14 @@ class ComponentbuilderModelJoomla_components extends ListModel $starts[] = $target['start']; } // has any been found - if (ComponentbuilderHelper::checkArray($starts)) + if (JCBArrayHelper::check($starts)) { foreach ($starts as $_start) { // get the base64 string - $base64 = ComponentbuilderHelper::getBetween($value, $_start, $target['end']); + $base64 = GetHelper::between($value, $_start, $target['end']); // now open the base64 text - $tmp = ComponentbuilderHelper::openValidBase64($base64); + $tmp = Base64Helper::open($base64); // insert it back into the value (so we still search the whole string) $value = str_replace($base64, $tmp, $value); } @@ -2632,7 +2672,7 @@ class ComponentbuilderModelJoomla_components extends ListModel // Get the basic encryption key. $basickey = ComponentbuilderHelper::getCryptKey('basic'); // Get the encryption object. - $basic = new FOFEncryptAes($basickey); + $basic = new AES($basickey); // Set values to display correctly. if (ComponentbuilderHelper::checkArray($items)) @@ -2647,33 +2687,38 @@ class ComponentbuilderModelJoomla_components extends ListModel continue; } - // decode php_helper_both - $item->php_helper_both = base64_decode($item->php_helper_both); - // decode php_method_uninstall - $item->php_method_uninstall = base64_decode($item->php_method_uninstall); - // decode php_preflight_install - $item->php_preflight_install = base64_decode($item->php_preflight_install); // decode css_admin $item->css_admin = base64_decode($item->css_admin); // decode php_admin_event $item->php_admin_event = base64_decode($item->php_admin_event); // decode php_site_event $item->php_site_event = base64_decode($item->php_site_event); + if ($basickey && !is_numeric($item->crowdin_username) && $item->crowdin_username === base64_encode(base64_decode($item->crowdin_username, true))) + { + // decrypt crowdin_username + $item->crowdin_username = $basic->decryptString($item->crowdin_username); + } // decode php_postflight_install $item->php_postflight_install = base64_decode($item->php_postflight_install); // decode sql_uninstall $item->sql_uninstall = base64_decode($item->sql_uninstall); + // decode php_preflight_install + $item->php_preflight_install = base64_decode($item->php_preflight_install); + // decode php_method_uninstall + $item->php_method_uninstall = base64_decode($item->php_method_uninstall); + // decode buildcompsql + $item->buildcompsql = base64_decode($item->buildcompsql); // decode php_helper_admin $item->php_helper_admin = base64_decode($item->php_helper_admin); + // decode php_helper_site + $item->php_helper_site = base64_decode($item->php_helper_site); + // decode javascript + $item->javascript = base64_decode($item->javascript); if ($basickey && !is_numeric($item->whmcs_key) && $item->whmcs_key === base64_encode(base64_decode($item->whmcs_key, true))) { // decrypt whmcs_key $item->whmcs_key = $basic->decryptString($item->whmcs_key); } - // decode php_helper_site - $item->php_helper_site = base64_decode($item->php_helper_site); - // decode javascript - $item->javascript = base64_decode($item->javascript); // decode css_site $item->css_site = base64_decode($item->css_site); // decode php_preflight_update @@ -2682,13 +2727,6 @@ class ComponentbuilderModelJoomla_components extends ListModel $item->php_postflight_update = base64_decode($item->php_postflight_update); // decode sql $item->sql = base64_decode($item->sql); - if ($basickey && !is_numeric($item->crowdin_username) && $item->crowdin_username === base64_encode(base64_decode($item->crowdin_username, true))) - { - // decrypt crowdin_username - $item->crowdin_username = $basic->decryptString($item->crowdin_username); - } - // decode buildcompsql - $item->buildcompsql = base64_decode($item->buildcompsql); if ($basickey && !is_numeric($item->export_key) && $item->export_key === base64_encode(base64_decode($item->export_key, true))) { // decrypt export_key @@ -2706,6 +2744,8 @@ class ComponentbuilderModelJoomla_components extends ListModel // decrypt crowdin_account_api_key $item->crowdin_account_api_key = $basic->decryptString($item->crowdin_account_api_key); } + // decode php_helper_both + $item->php_helper_both = base64_decode($item->php_helper_both); // unset the values we don't want exported. unset($item->asset_id); unset($item->checked_out); @@ -2735,7 +2775,7 @@ class ComponentbuilderModelJoomla_components extends ListModel $db = JFactory::getDbo(); // get the columns $columns = $db->getTableColumns("#__componentbuilder_joomla_component"); - if (ComponentbuilderHelper::checkArray($columns)) + if (JCBArrayHelper::check($columns)) { // remove the headers you don't import/export. unset($columns['asset_id']); diff --git a/admin/models/joomla_module.php b/admin/models/joomla_module.php index 804e2e4e9..9458ba6df 100644 --- a/admin/models/joomla_module.php +++ b/admin/models/joomla_module.php @@ -16,6 +16,12 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Joomla_module Admin Model @@ -189,7 +195,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'joomla_module__'.$id); ComponentbuilderHelper::set('joomla_module__'.$id, $this->vastDevMod); // set a return value if found @@ -197,7 +203,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -363,7 +369,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'joomla_module__'.$id); ComponentbuilderHelper::set('joomla_module__'.$id, $this->vastDevMod); // set a return value if found @@ -371,7 +377,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -497,7 +503,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -512,9 +518,9 @@ class ComponentbuilderModelJoomla_module extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -576,7 +582,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_module.edit.state', 'com_componentbuilder'); } @@ -742,7 +748,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel } // we must also delete the linked tables found - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { // linked tables to update $_tablesArray = array( @@ -784,7 +790,7 @@ class ComponentbuilderModelJoomla_module extends AdminModel } // we must also update all linked tables - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { // linked tables to update $_tablesArray = array( @@ -1183,12 +1189,12 @@ class ComponentbuilderModelJoomla_module extends AdminModel if (strpos($data['name'], '[[[') === false && strpos($data['name'], '###') === false) { // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); } // always reset the snippets $data['snippet'] = 0; // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } @@ -1197,15 +1203,15 @@ class ComponentbuilderModelJoomla_module extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('joomla_module', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('joomla_module', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "joomla_module", $data['id'])) + while (!GuidHelper::valid($data['guid'], "joomla_module", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the libraries items to data. if (isset($data['libraries']) && is_array($data['libraries'])) diff --git a/admin/models/joomla_module_files_folders_urls.php b/admin/models/joomla_module_files_folders_urls.php index ad402341d..f7081ddd7 100644 --- a/admin/models/joomla_module_files_folders_urls.php +++ b/admin/models/joomla_module_files_folders_urls.php @@ -327,7 +327,7 @@ class ComponentbuilderModelJoomla_module_files_folders_urls extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_module_files_folders_urls.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/joomla_module_updates.php b/admin/models/joomla_module_updates.php index 3b80f2756..8056d763c 100644 --- a/admin/models/joomla_module_updates.php +++ b/admin/models/joomla_module_updates.php @@ -284,7 +284,7 @@ class ComponentbuilderModelJoomla_module_updates extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_module_updates.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/joomla_plugin.php b/admin/models/joomla_plugin.php index 4b6ef7b28..1a29725ad 100644 --- a/admin/models/joomla_plugin.php +++ b/admin/models/joomla_plugin.php @@ -16,6 +16,12 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Joomla_plugin Admin Model @@ -166,7 +172,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'joomla_plugin__'.$id); ComponentbuilderHelper::set('joomla_plugin__'.$id, $this->vastDevMod); // set a return value if found @@ -174,7 +180,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -328,7 +334,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'joomla_plugin__'.$id); ComponentbuilderHelper::set('joomla_plugin__'.$id, $this->vastDevMod); // set a return value if found @@ -336,7 +342,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -462,7 +468,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -477,9 +483,9 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -541,7 +547,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_plugin.edit.state', 'com_componentbuilder'); } @@ -707,7 +713,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel } // we must also delete the linked tables found - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { // linked tables to update $_tablesArray = array( @@ -749,7 +755,7 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel } // we must also update all linked tables - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { // linked tables to update $_tablesArray = array( @@ -1148,10 +1154,10 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel if (strpos($data['name'], '[[[') === false && strpos($data['name'], '###') === false) { // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); } // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } @@ -1160,15 +1166,15 @@ class ComponentbuilderModelJoomla_plugin extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('joomla_plugin', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('joomla_plugin', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "joomla_plugin", $data['id'])) + while (!GuidHelper::valid($data['guid'], "joomla_plugin", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the method_selection items to data. if (isset($data['method_selection']) && is_array($data['method_selection'])) diff --git a/admin/models/joomla_plugin_files_folders_urls.php b/admin/models/joomla_plugin_files_folders_urls.php index 1f4ef4d6b..e5bde43ed 100644 --- a/admin/models/joomla_plugin_files_folders_urls.php +++ b/admin/models/joomla_plugin_files_folders_urls.php @@ -327,7 +327,7 @@ class ComponentbuilderModelJoomla_plugin_files_folders_urls extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_plugin_files_folders_urls.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/joomla_plugin_group.php b/admin/models/joomla_plugin_group.php index b8d9b0bc0..505402500 100644 --- a/admin/models/joomla_plugin_group.php +++ b/admin/models/joomla_plugin_group.php @@ -16,6 +16,7 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; /** * Componentbuilder Joomla_plugin_group Admin Model @@ -271,7 +272,7 @@ class ComponentbuilderModelJoomla_plugin_group extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::canEditState($record); } @@ -540,7 +541,7 @@ class ComponentbuilderModelJoomla_plugin_group extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('joomla_plugin_group'); } - if (!$this->canDo->get('core.create') || !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.create') && !$this->canDo->get('joomla_plugin_group.batch')) { return false; } @@ -683,7 +684,7 @@ class ComponentbuilderModelJoomla_plugin_group extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('joomla_plugin_group'); } - if (!$this->canDo->get('core.edit') && !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.edit') && !$this->canDo->get('joomla_plugin_group.batch')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; @@ -794,7 +795,7 @@ class ComponentbuilderModelJoomla_plugin_group extends AdminModel } // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); // Set the Params Items to data if (isset($data['params']) && is_array($data['params'])) diff --git a/admin/models/joomla_plugin_updates.php b/admin/models/joomla_plugin_updates.php index 7d77ceb19..05a5b6d8f 100644 --- a/admin/models/joomla_plugin_updates.php +++ b/admin/models/joomla_plugin_updates.php @@ -284,7 +284,7 @@ class ComponentbuilderModelJoomla_plugin_updates extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('joomla_plugin_updates.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/joomla_plugins.php b/admin/models/joomla_plugins.php index ada80be0d..77998a47c 100644 --- a/admin/models/joomla_plugins.php +++ b/admin/models/joomla_plugins.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\StringHelper; /** * Joomla_plugins List Model @@ -62,7 +64,7 @@ class ComponentbuilderModelJoomla_plugins extends ListModel } )); // make sure we have the correct boilerplate - if (ComponentbuilderHelper::checkArray($found) && count($found) == 1 && method_exists(__CLASS__, 'getPluginsBoilerplate')) + if (UtilitiesArrayHelper::check($found) && count($found) == 1 && method_exists(__CLASS__, 'getPluginsBoilerplate')) { // get the plugins boilerplate return $this->getPluginsBoilerplate($found[0]->url); @@ -99,7 +101,7 @@ class ComponentbuilderModelJoomla_plugins extends ListModel // get the needed data of each plugin group $groups = array_map( function($tree) use(&$app, &$models, &$tables){ - if (($fooClass = ComponentbuilderHelper::getFileContents(ComponentbuilderHelper::$bolerplatePath . '/plugins/' . $tree->path . '/foo.php')) !== false && ComponentbuilderHelper::checkString($fooClass)) + if (($fooClass = ComponentbuilderHelper::getFileContents(ComponentbuilderHelper::$bolerplatePath . '/plugins/' . $tree->path . '/foo.php')) !== false && StringHelper::check($fooClass)) { // extract the boilerplate class extends and check if already set if (($classExtends = ComponentbuilderHelper::extractBoilerplateClassExtends($fooClass, 'plugins')) !== false && @@ -132,7 +134,7 @@ class ComponentbuilderModelJoomla_plugins extends ListModel if (($classProperiesMethods = ComponentbuilderHelper::extractBoilerplateClassPropertiesMethods($fooClass, $classExtends, 'plugins', $pluginGroupID)) !== false) { // create the properties found - if (isset($classProperiesMethods['property']) && ComponentbuilderHelper::checkArray($classProperiesMethods['property'])) + if (isset($classProperiesMethods['property']) && UtilitiesArrayHelper::check($classProperiesMethods['property'])) { foreach ($classProperiesMethods['property'] as $_property) { @@ -141,7 +143,7 @@ class ComponentbuilderModelJoomla_plugins extends ListModel } } // create the method found (TODO just create for now but we could later add a force update) - if (isset($classProperiesMethods['method']) && ComponentbuilderHelper::checkArray($classProperiesMethods['method'])) + if (isset($classProperiesMethods['method']) && UtilitiesArrayHelper::check($classProperiesMethods['method'])) { foreach ($classProperiesMethods['method'] as $_method) { diff --git a/admin/models/language.php b/admin/models/language.php index f35e510d3..034602ba8 100644 --- a/admin/models/language.php +++ b/admin/models/language.php @@ -271,7 +271,7 @@ class ComponentbuilderModelLanguage extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('language.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/language_translation.php b/admin/models/language_translation.php index 2f584729a..0950456e0 100644 --- a/admin/models/language_translation.php +++ b/admin/models/language_translation.php @@ -16,6 +16,8 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; /** * Componentbuilder Language_translation Admin Model @@ -101,7 +103,7 @@ class ComponentbuilderModelLanguage_translation extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'language_translation__'.$id); ComponentbuilderHelper::set('language_translation__'.$id, $this->vastDevMod); // set a return value if found @@ -109,7 +111,7 @@ class ComponentbuilderModelLanguage_translation extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -181,7 +183,7 @@ class ComponentbuilderModelLanguage_translation extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'language_translation__'.$id); ComponentbuilderHelper::set('language_translation__'.$id, $this->vastDevMod); // set a return value if found @@ -189,7 +191,7 @@ class ComponentbuilderModelLanguage_translation extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -368,7 +370,7 @@ class ComponentbuilderModelLanguage_translation extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('language_translation.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/language_translations.php b/admin/models/language_translations.php index 13bdfcc66..9a74c5c81 100644 --- a/admin/models/language_translations.php +++ b/admin/models/language_translations.php @@ -14,6 +14,11 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; /** * Language_translations List Model @@ -55,7 +60,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel // Create the "extension" filter $form->setField(new SimpleXMLElement( - ComponentbuilderHelper::getExtensionGroupedListXml() + JCBFilterHelper::extensions() ),'filter'); $form->setValue( 'extension', @@ -75,7 +80,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_LANGUAGES_FOUND') . ' -' ); // check if we have languages set - if (($languages = ComponentbuilderHelper::getAvailableLanguages()) !== false) + if (($languages = JCBFilterHelper::languages()) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_TRANSLATED_IN') . ' -', @@ -85,7 +90,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $options = array_merge($options, $languages); } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'translated', 'filter', @@ -114,7 +119,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $options = array_merge($options, $languages); } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'not_translated', 'filter', @@ -216,12 +221,12 @@ class ComponentbuilderModelLanguage_translations extends ListModel // escape all strings if not being exported if (!isset($_export)) { - $item->source = ComponentbuilderHelper::htmlEscape($item->source, 'UTF-8', true, 150); + $item->source = StringHelper::html($item->source, 'UTF-8', true, 150); } } } // prep the lang strings for export - if (isset($_export) && $_export && ComponentbuilderHelper::checkArray($items)) + if (isset($_export) && $_export && UtilitiesArrayHelper::check($items)) { // insure we have the same order in the languages $languages = ComponentbuilderHelper::getVars('language', 1, 'published', 'langtag'); @@ -249,15 +254,15 @@ class ComponentbuilderModelLanguage_translations extends ListModel $item->{$lanTag} = ''; } // now adapt the source - if (isset($item->translation) && ComponentbuilderHelper::checkJson($item->translation)) + if (isset($item->translation) && JsonHelper::check($item->translation)) { $translations = json_decode($item->translation, true); - if (ComponentbuilderHelper::checkArray($translations)) + if (UtilitiesArrayHelper::check($translations)) { foreach ($translations as $language) { - if (isset($language['translation']) && ComponentbuilderHelper::checkString($language['translation']) - && isset($language['language']) && ComponentbuilderHelper::checkString($language['language'])) + if (isset($language['translation']) && StringHelper::check($language['translation']) + && isset($language['language']) && StringHelper::check($language['language'])) { $item->{$language['language']} = $language['translation']; } @@ -300,7 +305,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_translated = $this->state->get("filter.translated"); if ($filter_translated !== null && !empty($filter_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_translated)) !== false) + if (($ids = JCBFilterHelper::translations($filter_translated)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -315,7 +320,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_not_translated = $this->state->get("filter.not_translated"); if ($filter_not_translated !== null && !empty($filter_not_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_not_translated, false)) !== false) + if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')'); } @@ -332,7 +337,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getTranslationExtensionsIds($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::translation((int) $type_extension[1], $type_extension[0])) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -459,7 +464,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_translated = $this->state->get("filter.translated"); if ($filter_translated !== null && !empty($filter_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_translated)) !== false) + if (($ids = JCBFilterHelper::translations($filter_translated)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -474,7 +479,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_not_translated = $this->state->get("filter.not_translated"); if ($filter_not_translated !== null && !empty($filter_not_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_not_translated, false)) !== false) + if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')'); } @@ -491,7 +496,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getTranslationExtensionsIds($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::translation((int) $type_extension[1], $type_extension[0])) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -535,7 +540,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel // escape all strings if not being exported if (!isset($_export)) { - $item->source = ComponentbuilderHelper::htmlEscape($item->source, 'UTF-8', true, 150); + $item->source = StringHelper::html($item->source, 'UTF-8', true, 150); } // unset the values we don't want exported. unset($item->asset_id); @@ -551,7 +556,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel } // prep the lang strings for export - if (isset($_export) && $_export && ComponentbuilderHelper::checkArray($items)) + if (isset($_export) && $_export && UtilitiesArrayHelper::check($items)) { // insure we have the same order in the languages $languages = ComponentbuilderHelper::getVars('language', 1, 'published', 'langtag'); @@ -579,15 +584,15 @@ class ComponentbuilderModelLanguage_translations extends ListModel $item->{$lanTag} = ''; } // now adapt the source - if (isset($item->translation) && ComponentbuilderHelper::checkJson($item->translation)) + if (isset($item->translation) && JsonHelper::check($item->translation)) { $translations = json_decode($item->translation, true); - if (ComponentbuilderHelper::checkArray($translations)) + if (UtilitiesArrayHelper::check($translations)) { foreach ($translations as $language) { - if (isset($language['translation']) && ComponentbuilderHelper::checkString($language['translation']) - && isset($language['language']) && ComponentbuilderHelper::checkString($language['language'])) + if (isset($language['translation']) && StringHelper::check($language['translation']) + && isset($language['language']) && StringHelper::check($language['language'])) { $item->{$language['language']} = $language['translation']; } @@ -618,7 +623,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $headers->id = 'id'; $headers->Source = 'Source'; // add the languages - if (ComponentbuilderHelper::checkArray($languages)) + if (UtilitiesArrayHelper::check($languages)) { foreach ($languages as $language) { diff --git a/admin/models/languages.php b/admin/models/languages.php index 27091efff..0e5bd0ed7 100644 --- a/admin/models/languages.php +++ b/admin/models/languages.php @@ -14,6 +14,7 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; /** * Languages List Model @@ -51,7 +52,7 @@ class ComponentbuilderModelLanguages extends ListModel if ($languages = $this->getLanguages()) { // make sure we have an array - if (ComponentbuilderHelper::checkArray($languages)) + if (UtilitiesArrayHelper::check($languages)) { // get the model $model = ComponentbuilderHelper::getModel('language'); diff --git a/admin/models/layout.php b/admin/models/layout.php index ce6b1cc96..b26fb3146 100644 --- a/admin/models/layout.php +++ b/admin/models/layout.php @@ -16,6 +16,9 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; /** * Componentbuilder Layout Admin Model @@ -123,7 +126,7 @@ class ComponentbuilderModelLayout extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'layout__'.$id); ComponentbuilderHelper::set('layout__'.$id, $this->vastDevMod); // set a return value if found @@ -131,7 +134,7 @@ class ComponentbuilderModelLayout extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -209,7 +212,7 @@ class ComponentbuilderModelLayout extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'layout__'.$id); ComponentbuilderHelper::set('layout__'.$id, $this->vastDevMod); // set a return value if found @@ -217,7 +220,7 @@ class ComponentbuilderModelLayout extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -341,7 +344,7 @@ class ComponentbuilderModelLayout extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -413,7 +416,7 @@ class ComponentbuilderModelLayout extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::canEditState($record); } @@ -683,7 +686,7 @@ class ComponentbuilderModelLayout extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('layout'); } - if (!$this->canDo->get('core.create') || !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.create') && !$this->canDo->get('layout.batch')) { return false; } @@ -821,7 +824,7 @@ class ComponentbuilderModelLayout extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('layout'); } - if (!$this->canDo->get('core.edit') && !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.edit') && !$this->canDo->get('layout.batch')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; diff --git a/admin/models/library.php b/admin/models/library.php index 2a35c2fd8..b3a31c222 100644 --- a/admin/models/library.php +++ b/admin/models/library.php @@ -16,6 +16,11 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Library Admin Model @@ -138,7 +143,7 @@ class ComponentbuilderModelLibrary extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'library__'.$id); ComponentbuilderHelper::set('library__'.$id, $this->vastDevMod); // set a return value if found @@ -146,7 +151,7 @@ class ComponentbuilderModelLibrary extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -226,7 +231,7 @@ class ComponentbuilderModelLibrary extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'library__'.$id); ComponentbuilderHelper::set('library__'.$id, $this->vastDevMod); // set a return value if found @@ -234,7 +239,7 @@ class ComponentbuilderModelLibrary extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -356,9 +361,9 @@ class ComponentbuilderModelLibrary extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -420,7 +425,7 @@ class ComponentbuilderModelLibrary extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('library.edit.state', 'com_componentbuilder'); } @@ -596,7 +601,7 @@ class ComponentbuilderModelLibrary extends AdminModel } } // check if we can still continue - if (!ComponentbuilderHelper::checkArray($pks)) + if (!UtilitiesArrayHelper::check($pks)) { return false; } @@ -606,7 +611,7 @@ class ComponentbuilderModelLibrary extends AdminModel } // we must also delete the linked tables found - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { $_tablesArray = array( 'snippet', @@ -647,7 +652,7 @@ class ComponentbuilderModelLibrary extends AdminModel } // we must also update all linked tables - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { $_tablesArray = array( 'snippet', @@ -1046,15 +1051,15 @@ class ComponentbuilderModelLibrary extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('library', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('library', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "library", $data['id'])) + while (!GuidHelper::valid($data['guid'], "library", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the libraries items to data. if (isset($data['libraries']) && is_array($data['libraries'])) diff --git a/admin/models/library_config.php b/admin/models/library_config.php index a7abd5e3c..d3d2459e0 100644 --- a/admin/models/library_config.php +++ b/admin/models/library_config.php @@ -281,7 +281,7 @@ class ComponentbuilderModelLibrary_config extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('library_config.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/library_files_folders_urls.php b/admin/models/library_files_folders_urls.php index 38780de8e..324ee8f5d 100644 --- a/admin/models/library_files_folders_urls.php +++ b/admin/models/library_files_folders_urls.php @@ -327,7 +327,7 @@ class ComponentbuilderModelLibrary_files_folders_urls extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('library_files_folders_urls.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/placeholder.php b/admin/models/placeholder.php index 404d097f4..920f8a8d2 100644 --- a/admin/models/placeholder.php +++ b/admin/models/placeholder.php @@ -16,6 +16,8 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; /** * Componentbuilder Placeholder Admin Model @@ -103,7 +105,7 @@ class ComponentbuilderModelPlaceholder extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'placeholder__'.$id); ComponentbuilderHelper::set('placeholder__'.$id, $this->vastDevMod); // set a return value if found @@ -111,7 +113,7 @@ class ComponentbuilderModelPlaceholder extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -175,7 +177,7 @@ class ComponentbuilderModelPlaceholder extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'placeholder__'.$id); ComponentbuilderHelper::set('placeholder__'.$id, $this->vastDevMod); // set a return value if found @@ -183,7 +185,7 @@ class ComponentbuilderModelPlaceholder extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -362,7 +364,7 @@ class ComponentbuilderModelPlaceholder extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('placeholder.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/power.php b/admin/models/power.php index 6c2f82742..501de225a 100644 --- a/admin/models/power.php +++ b/admin/models/power.php @@ -16,6 +16,13 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Power\Factory as PowerFactory; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Power Admin Model @@ -33,10 +40,10 @@ class ComponentbuilderModelPower extends AdminModel 'name', 'description', 'extends', - 'implements_custom', - 'implements', - 'namespace', 'extends_custom', + 'implements', + 'implements_custom', + 'namespace', 'add_head' ), 'right' => array( @@ -58,6 +65,27 @@ class ComponentbuilderModelPower extends AdminModel 'type', 'power_version' ) + ), + 'licensing' => array( + 'fullwidth' => array( + 'add_licensing_template', + 'licensing_template' + ) + ), + 'super_power' => array( + 'left' => array( + 'approved', + 'approved_paths' + ), + 'right' => array( + 'note_approved_paths' + ) + ), + 'composer' => array( + 'fullwidth' => array( + 'autoload_composer_note', + 'composer' + ) ) ); @@ -123,7 +151,7 @@ class ComponentbuilderModelPower extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'power__'.$id); ComponentbuilderHelper::set('power__'.$id, $this->vastDevMod); // set a return value if found @@ -131,7 +159,7 @@ class ComponentbuilderModelPower extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -172,10 +200,10 @@ class ComponentbuilderModelPower extends AdminModel $item->metadata = $registry->toArray(); } - if (!empty($item->main_class_code)) + if (!empty($item->licensing_template)) { - // base64 Decode main_class_code. - $item->main_class_code = base64_decode($item->main_class_code); + // base64 Decode licensing_template. + $item->licensing_template = base64_decode($item->licensing_template); } if (!empty($item->head)) @@ -184,6 +212,20 @@ class ComponentbuilderModelPower extends AdminModel $item->head = base64_decode($item->head); } + if (!empty($item->main_class_code)) + { + // base64 Decode main_class_code. + $item->main_class_code = base64_decode($item->main_class_code); + } + + if (!empty($item->method_selection)) + { + // Convert the method_selection field to an array. + $method_selection = new Registry; + $method_selection->loadString($item->method_selection); + $item->method_selection = $method_selection->toArray(); + } + if (!empty($item->load_selection)) { // Convert the load_selection field to an array. @@ -192,12 +234,12 @@ class ComponentbuilderModelPower extends AdminModel $item->load_selection = $load_selection->toArray(); } - if (!empty($item->use_selection)) + if (!empty($item->composer)) { - // Convert the use_selection field to an array. - $use_selection = new Registry; - $use_selection->loadString($item->use_selection); - $item->use_selection = $use_selection->toArray(); + // Convert the composer field to an array. + $composer = new Registry; + $composer->loadString($item->composer); + $item->composer = $composer->toArray(); } if (!empty($item->property_selection)) @@ -216,12 +258,18 @@ class ComponentbuilderModelPower extends AdminModel $item->implements = $implements->toArray(); } - if (!empty($item->method_selection)) + if (!empty($item->use_selection)) { - // Convert the method_selection field to an array. - $method_selection = new Registry; - $method_selection->loadString($item->method_selection); - $item->method_selection = $method_selection->toArray(); + // Convert the use_selection field to an array. + $use_selection = new Registry; + $use_selection->loadString($item->use_selection); + $item->use_selection = $use_selection->toArray(); + } + + if (!empty($item->approved_paths)) + { + // JSON Decode approved_paths. + $item->approved_paths = json_decode($item->approved_paths); } @@ -241,7 +289,7 @@ class ComponentbuilderModelPower extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'power__'.$id); ComponentbuilderHelper::set('power__'.$id, $this->vastDevMod); // set a return value if found @@ -249,7 +297,7 @@ class ComponentbuilderModelPower extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -375,7 +423,7 @@ class ComponentbuilderModelPower extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -390,9 +438,9 @@ class ComponentbuilderModelPower extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -454,7 +502,7 @@ class ComponentbuilderModelPower extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('power.edit.state', 'com_componentbuilder'); } @@ -977,24 +1025,32 @@ class ComponentbuilderModelPower extends AdminModel $data['metadata'] = (string) $metadata; } + // Set the empty approved_paths item to data + if (!isset($data['approved_paths'])) + { + $data['approved_paths'] = ''; + } + // check if the name has placeholder if (strpos($data['name'], '[[[') === false && strpos($data['name'], '###') === false) { // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); } + // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } + // must set the version if empty - if (empty($data['power_version']) && $data['id'] > 0 && ($power_version = ComponentbuilderHelper::getVar('power', $data['id'], 'id', 'power_version')) !== false) + if (empty($data['power_version']) && $data['id'] > 0 && ($power_version = GetHelper::var('power', $data['id'], 'id', 'power_version')) !== false) { $data['power_version'] = $power_version; } // we must preserve versions (so that a change to the version number must result in save as copy) - elseif ($data['id'] > 0 && ($old_version = ComponentbuilderHelper::getVar('power', $data['id'], 'id', 'power_version')) && $data['power_version'] != $old_version) + elseif ($data['id'] > 0 && ($old_version = GetHelper::var('power', $data['id'], 'id', 'power_version')) && $data['power_version'] != $old_version) { // lets check if we already have this version if (($existing_id = ComponentbuilderHelper::checkExist('power', ['power_version' => $data['power_version'], 'name' => $data['name'], 'namespace' => $data['namespace']])) !== false) @@ -1010,20 +1066,39 @@ class ComponentbuilderModelPower extends AdminModel JFactory::getApplication()->input->set('task', 'save2copy'); } } + + // load dynamic code if relevant + if (($main_class_code = PowerFactory::_('Power.Generator')->get($data)) !== null) + { + $data['main_class_code'] = $main_class_code; + } // Set the GUID if empty or not valid if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('power', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('power', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "power", $data['id'])) + while (!GuidHelper::valid($data['guid'], "power", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } + $data['guid'] = (string) GuidHelper::get(); + } + // Set the method_selection items to data. + if (isset($data['method_selection']) && is_array($data['method_selection'])) + { + $method_selection = new JRegistry; + $method_selection->loadArray($data['method_selection']); + $data['method_selection'] = (string) $method_selection; + } + elseif (!isset($data['method_selection'])) + { + // Set the empty method_selection to data + $data['method_selection'] = ''; + } // Set the load_selection items to data. if (isset($data['load_selection']) && is_array($data['load_selection'])) @@ -1038,17 +1113,17 @@ class ComponentbuilderModelPower extends AdminModel $data['load_selection'] = ''; } - // Set the use_selection items to data. - if (isset($data['use_selection']) && is_array($data['use_selection'])) + // Set the composer items to data. + if (isset($data['composer']) && is_array($data['composer'])) { - $use_selection = new JRegistry; - $use_selection->loadArray($data['use_selection']); - $data['use_selection'] = (string) $use_selection; + $composer = new JRegistry; + $composer->loadArray($data['composer']); + $data['composer'] = (string) $composer; } - elseif (!isset($data['use_selection'])) + elseif (!isset($data['composer'])) { - // Set the empty use_selection to data - $data['use_selection'] = ''; + // Set the empty composer to data + $data['composer'] = ''; } // Set the property_selection items to data. @@ -1077,23 +1152,29 @@ class ComponentbuilderModelPower extends AdminModel $data['implements'] = ''; } - // Set the method_selection items to data. - if (isset($data['method_selection']) && is_array($data['method_selection'])) + // Set the use_selection items to data. + if (isset($data['use_selection']) && is_array($data['use_selection'])) { - $method_selection = new JRegistry; - $method_selection->loadArray($data['method_selection']); - $data['method_selection'] = (string) $method_selection; + $use_selection = new JRegistry; + $use_selection->loadArray($data['use_selection']); + $data['use_selection'] = (string) $use_selection; } - elseif (!isset($data['method_selection'])) + elseif (!isset($data['use_selection'])) { - // Set the empty method_selection to data - $data['method_selection'] = ''; + // Set the empty use_selection to data + $data['use_selection'] = ''; } - // Set the main_class_code string to base64 string. - if (isset($data['main_class_code'])) + // Set the approved_paths string to JSON string. + if (isset($data['approved_paths'])) { - $data['main_class_code'] = base64_encode($data['main_class_code']); + $data['approved_paths'] = (string) json_encode($data['approved_paths']); + } + + // Set the licensing_template string to base64 string. + if (isset($data['licensing_template'])) + { + $data['licensing_template'] = base64_encode($data['licensing_template']); } // Set the head string to base64 string. @@ -1101,6 +1182,12 @@ class ComponentbuilderModelPower extends AdminModel { $data['head'] = base64_encode($data['head']); } + + // Set the main_class_code string to base64 string. + if (isset($data['main_class_code'])) + { + $data['main_class_code'] = base64_encode($data['main_class_code']); + } // Set the Params Items to data if (isset($data['params']) && is_array($data['params'])) diff --git a/admin/models/powers.php b/admin/models/powers.php index 55c580c18..62e60f37f 100644 --- a/admin/models/powers.php +++ b/admin/models/powers.php @@ -14,6 +14,9 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\Component\Helper as JCBHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; +use VDM\Joomla\Utilities\FormHelper as JCBFormHelper; /** * Powers List Model @@ -32,16 +35,123 @@ class ComponentbuilderModelPowers extends ListModel 'a.created_by','created_by', 'a.modified_by','modified_by', 'a.type','type', - 'a.power_version','power_version', - 'h.name','extends', + 'a.approved','approved', 'a.system_name','system_name', - 'a.namespace','namespace' + 'a.namespace','namespace', + 'a.power_version','power_version' ); } parent::__construct($config); } + /** + * Get the filter form - Override the parent method + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return \JForm|boolean The \JForm object or false on error + * + * @since JCB 2.12.5 + */ + public function getFilterForm($data = array(), $loadData = true) + { + // load form from the parent class + $form = parent::getFilterForm($data, $loadData); + + // Create the "admin_view" filter + $attributes = array( + 'name' => 'namegroup', + 'type' => 'list', + 'onchange' => 'this.form.submit();', + ); + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_NAMESPACE_FOUND') . ' -' + ); + // check if we have namespace (and limit to an extension if it is set) + if (($namespaces = JCBFilterHelper::namespaces()) !== null) + { + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_A_NAMESPACE') . ' -' + ); + // make sure we do not lose the key values in normal merge + $options = $options + $namespaces; + } + + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); + $form->setValue( + 'namegroup', + 'filter', + $this->state->get("filter.namegroup") + ); + array_push($this->filter_fields, 'namegroup'); + + // get the component params + $params = JCBHelper::getParams(); + $activate = $params->get('super_powers_repositories', 0); + if ($activate == 1) + { + $subform = $params->get('approved_paths', null); + + // create approved paths filter + $attributes = array( + 'name' => 'approved_paths', + 'type' => 'list', + 'onchange' => 'this.form.submit();', + ); + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_PATHS_FOUND') . ' -' + ); + + // add the paths found in global settings + if (is_object($subform)) + { + $core = $params->get('super_powers_core', 'joomla/super-powers'); + + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_APPROVED_PATH') . ' -', + $core => $core + ); + + foreach ($subform as $value) + { + if (isset($value->owner) && strlen($value->owner) > 1 && + isset($value->repo) && strlen($value->repo) > 1) + { + $value = trim($value->owner) . '/' . trim($value->repo); + + $options[$value] = $value; + } + } + } + + $form->setField(JCBFormHelper::xml($attributes, $options), 'filter'); + $form->setValue( + 'approved_paths', + 'filter', + $this->state->get("filter.approved_paths") + ); + array_push($this->filter_fields, 'approved_paths'); + } + + return $form; + } + + /** + * Check if a power can be used in linking + * + * @param string $type the type of power + * + * @return bool + * @since JCB 3.1.23 + */ + protected function isSuperPower(string $type): bool + { + return in_array($type, ['class', 'abstract class', 'final class', 'trait']); + } + + /** * Method to auto-populate the model state. * @@ -95,18 +205,11 @@ class ComponentbuilderModelPowers extends ListModel $this->setState('filter.type', $type); } - $power_version = $this->getUserStateFromRequest($this->context . '.filter.power_version', 'filter_power_version'); + $approved = $this->getUserStateFromRequest($this->context . '.filter.approved', 'filter_approved'); if ($formSubmited) { - $power_version = $app->input->post->get('power_version'); - $this->setState('filter.power_version', $power_version); - } - - $extends = $this->getUserStateFromRequest($this->context . '.filter.extends', 'filter_extends'); - if ($formSubmited) - { - $extends = $app->input->post->get('extends'); - $this->setState('filter.extends', $extends); + $approved = $app->input->post->get('approved'); + $this->setState('filter.approved', $approved); } $system_name = $this->getUserStateFromRequest($this->context . '.filter.system_name', 'filter_system_name'); @@ -123,6 +226,13 @@ class ComponentbuilderModelPowers extends ListModel $this->setState('filter.namespace', $namespace); } + $power_version = $this->getUserStateFromRequest($this->context . '.filter.power_version', 'filter_power_version'); + if ($formSubmited) + { + $power_version = $app->input->post->get('power_version'); + $this->setState('filter.power_version', $power_version); + } + // List state information. parent::populateState($ordering, $direction); } @@ -158,6 +268,13 @@ class ComponentbuilderModelPowers extends ListModel continue; } + // create the GUID placeholder key + if ($this->isSuperPower($item->type)) + { + $item->super_power_key = 'Super_'.'_'.'_' . str_replace('-', '_', $item->guid) . '_'.'_'.'_Power'; + } + // remove dots + $item->namespace = str_replace('.','\\', $item->namespace); } } @@ -168,6 +285,8 @@ class ComponentbuilderModelPowers extends ListModel { // convert type $item->type = $this->selectionTranslation($item->type, 'type'); + // convert approved + $item->approved = $this->selectionTranslation($item->approved, 'approved'); } } @@ -199,6 +318,19 @@ class ComponentbuilderModelPowers extends ListModel return $typeArray[$value]; } } + // Array of approved language strings + if ($name === 'approved') + { + $approvedArray = array( + 0 => 'COM_COMPONENTBUILDER_POWER_NOT_APPROVED', + 1 => 'COM_COMPONENTBUILDER_POWER_APPROVED' + ); + // Now check if value is found in this array + if (isset($approvedArray[$value]) && ComponentbuilderHelper::checkString($approvedArray[$value])) + { + return $approvedArray[$value]; + } + } return $value; } @@ -221,9 +353,43 @@ class ComponentbuilderModelPowers extends ListModel // From the componentbuilder_item table $query->from($db->quoteName('#__componentbuilder_power', 'a')); + // do not use these filters in the export method + if (!isset($_export) || !$_export) + { + // Filtering "namegroup" + $filter_namegroup = $this->state->get("filter.namegroup"); + if ($filter_namegroup !== null && !empty($filter_namegroup)) + { + if (($ids = JCBFilterHelper::namegroup($filter_namegroup)) !== null) + { + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); + } + else + { + // there is none + $query->where($db->quoteName('a.id') . ' = ' . 0); + } + } + + // Filtering "approved paths" + $filter_approved_paths = $this->state->get("filter.approved_paths"); + if ($filter_approved_paths !== null && !empty($filter_approved_paths)) + { + if (($ids = JCBFilterHelper::paths($filter_approved_paths)) !== null) + { + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); + } + else + { + // there is none + $query->where($db->quoteName('a.id') . ' = ' . 0); + } + } + } + // From the componentbuilder_power table. - $query->select($db->quoteName(['h.name','h.id'],['extends_name','extends_id'])); - $query->join('LEFT', $db->quoteName('#__componentbuilder_power', 'h') . ' ON (' . $db->quoteName('a.extends') . ' = ' . $db->quoteName('h.guid') . ')'); + $query->select($db->quoteName(['g.name','g.id'],['extends_name','extends_id'])); + $query->join('LEFT', $db->quoteName('#__componentbuilder_power', 'g') . ' ON (' . $db->quoteName('a.extends') . ' = ' . $db->quoteName('g.guid') . ')'); // Filter by published state $published = $this->getState('filter.published'); @@ -269,7 +435,7 @@ class ComponentbuilderModelPowers extends ListModel else { $search = $db->quote('%' . $db->escape($search) . '%'); - $query->where('(a.system_name LIKE '.$search.' OR a.type LIKE '.$search.' OR a.description LIKE '.$search.' OR a.extends_custom LIKE '.$search.' OR a.extends LIKE '.$search.' OR a.name LIKE '.$search.')'); + $query->where('(a.system_name LIKE '.$search.' OR a.type LIKE '.$search.' OR a.description LIKE '.$search.' OR a.extends LIKE '.$search.' OR a.extends_custom LIKE '.$search.' OR a.approved_paths LIKE '.$search.' OR a.guid LIKE '.$search.' OR a.name LIKE '.$search.')'); } } @@ -313,39 +479,22 @@ class ComponentbuilderModelPowers extends ListModel // Filter by the Type Array. $query->where('a.type IN (' . implode(',', $_type) . ')'); } - // Filter by Power_version. - $_power_version = $this->getState('filter.power_version'); - if (is_numeric($_power_version)) + // Filter by Approved. + $_approved = $this->getState('filter.approved'); + if (is_numeric($_approved)) { - if (is_float($_power_version)) + if (is_float($_approved)) { - $query->where('a.power_version = ' . (float) $_power_version); + $query->where('a.approved = ' . (float) $_approved); } else { - $query->where('a.power_version = ' . (int) $_power_version); + $query->where('a.approved = ' . (int) $_approved); } } - elseif (ComponentbuilderHelper::checkString($_power_version)) + elseif (ComponentbuilderHelper::checkString($_approved)) { - $query->where('a.power_version = ' . $db->quote($db->escape($_power_version))); - } - // Filter by Extends. - $_extends = $this->getState('filter.extends'); - if (is_numeric($_extends)) - { - if (is_float($_extends)) - { - $query->where('a.extends = ' . (float) $_extends); - } - else - { - $query->where('a.extends = ' . (int) $_extends); - } - } - elseif (ComponentbuilderHelper::checkString($_extends)) - { - $query->where('a.extends = ' . $db->quote($db->escape($_extends))); + $query->where('a.approved = ' . $db->quote($db->escape($_approved))); } // Add the list ordering clause. @@ -398,10 +547,10 @@ class ComponentbuilderModelPowers extends ListModel { $id .= ':' . $_type; } - $id .= ':' . $this->getState('filter.power_version'); - $id .= ':' . $this->getState('filter.extends'); + $id .= ':' . $this->getState('filter.approved'); $id .= ':' . $this->getState('filter.system_name'); $id .= ':' . $this->getState('filter.namespace'); + $id .= ':' . $this->getState('filter.power_version'); return parent::getStoreId($id); } diff --git a/admin/models/search.php b/admin/models/search.php new file mode 100644 index 000000000..792896e36 --- /dev/null +++ b/admin/models/search.php @@ -0,0 +1,244 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +use Joomla\CMS\MVC\Model\ItemModel; +use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory; + +/** + * Componentbuilder Search Item Model + */ +class ComponentbuilderModelSearch extends ItemModel +{ + /** + * Model context string. + * + * @var string + */ + protected $_context = 'com_componentbuilder.search'; + + /** + * Model user data. + * + * @var strings + */ + protected $user; + protected $userId; + protected $guest; + protected $groups; + protected $levels; + protected $app; + protected $input; + protected $uikitComp; + + /** + * @var object item + */ + protected $item; + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @since 1.6 + * + * @return void + */ + protected function populateState() + { + $this->app = JFactory::getApplication(); + $this->input = $this->app->input; + // Get the item main id + $id = $this->input->getInt('id', null); + $this->setState('search.id', $id); + + // Load the parameters. + parent::populateState(); + } + + /** + * Method to get article data. + * + * @param integer $pk The id of the article. + * + * @return mixed Menu item data object on success, false on failure. + */ + public function getItem($pk = null) + { + $this->user = JFactory::getUser(); + // check if this user has permission to access item + if (!$this->user->authorise('search.access', 'com_componentbuilder')) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('Not authorised!'), 'error'); + // redirect away if not a correct to cPanel/default view + $app->redirect('index.php?option=com_componentbuilder'); + return false; + } + $this->userId = $this->user->get('id'); + $this->guest = $this->user->get('guest'); + $this->groups = $this->user->get('groups'); + $this->authorisedGroups = $this->user->getAuthorisedGroups(); + $this->levels = $this->user->getAuthorisedViewLevels(); + $this->initSet = true; + + $pk = (!empty($pk)) ? $pk : (int) $this->getState('search.id'); + + $pk = $this->userId; + + if ($this->_item === null) + { + $this->_item = array(); + } + + if (!isset($this->_item[$pk])) + { + try + { + // Get a db connection. + $db = JFactory::getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + + // Get data + // load the tables and components + $data = ['tables' => SearchFactory::_('Table')->tables(), 'components' => $this->getComponents()]; + + + if (empty($data)) + { + $app = JFactory::getApplication(); + // If no data is found redirect to default page and show warning. + $app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_NOT_FOUND_OR_ACCESS_DENIED'), 'warning'); + $app->redirect('index.php?option=com_componentbuilder'); + return false; + } + + // set data object to item. + $this->_item[$pk] = $data; + } + catch (Exception $e) + { + if ($e->getCode() == 404) + { + // Need to go thru the error handler to allow Redirect to work. + JError::raiseWarning(404, $e->getMessage()); + } + else + { + $this->setError($e); + $this->_item[$pk] = false; + } + } + } + + return $this->_item[$pk]; + } + + /** + * Custom Method + * + * @return mixed item data object on success, false on failure. + * + */ + public function getUrlValues() + { + + if (!isset($this->initSet) || !$this->initSet) + { + $this->user = JFactory::getUser(); + $this->userId = $this->user->get('id'); + $this->guest = $this->user->get('guest'); + $this->groups = $this->user->get('groups'); + $this->authorisedGroups = $this->user->getAuthorisedGroups(); + $this->levels = $this->user->getAuthorisedViewLevels(); + $this->initSet = true; + } + // Get a db connection. + $db = JFactory::getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + + // Get data + $data = [ + 'type_search' => SearchFactory::_('Config')->get('type_search', 1), + 'search_value' => SearchFactory::_('Config')->get('search_value', ''), + 'replace_value' => SearchFactory::_('Config')->get('replace_value', ''), + 'match_case' => SearchFactory::_('Config')->get('match_case', 0), + 'whole_word' => SearchFactory::_('Config')->get('whole_word', 0), + 'regex_search' => SearchFactory::_('Config')->get('regex_search', 0), + 'table_name' => SearchFactory::_('Config')->get('table_name', -1) + ]; + + if (empty($data)) + { + return false; + } + + // return data object. + return $data; + } + + /** + * Get the uikit needed components + * + * @return mixed An array of objects on success. + * + */ + public function getUikitComp() + { + if (isset($this->uikitComp) && ComponentbuilderHelper::checkArray($this->uikitComp)) + { + return $this->uikitComp; + } + return false; + } + + + /** + * Get all components in the system + * + * @return array + * @since 3.2.0 + **/ + public function getComponents(): array + { + // Get a db connection. + $db = $this->getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + + // Select only id and system name + $query->select($db->quoteName(array('id', 'system_name'),array('id', 'name'))); + $query->from($db->quoteName('#__componentbuilder_joomla_component')); + + // only the active components + $query->where($db->quoteName('published') . ' = 1'); + + // Order it by the ordering field. + $query->order('modified DESC'); + $query->order('created DESC'); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + + // return the result + return $db->loadObjectList(); + } + +} diff --git a/admin/models/server.php b/admin/models/server.php index de6948f84..6f6dd0f20 100644 --- a/admin/models/server.php +++ b/admin/models/server.php @@ -16,6 +16,7 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\FOF\Encrypt\AES; /** * Componentbuilder Server Admin Model @@ -120,7 +121,7 @@ class ComponentbuilderModelServer extends AdminModel // Get the basic encryption. $basickey = ComponentbuilderHelper::getCryptKey('basic'); // Get the encryption object. - $basic = new FOFEncryptAes($basickey); + $basic = new AES($basickey); if (!empty($item->signature) && $basickey && !is_numeric($item->signature) && $item->signature === base64_encode(base64_decode($item->signature, true))) { @@ -443,7 +444,7 @@ class ComponentbuilderModelServer extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('server.edit.state', 'com_componentbuilder'); } @@ -1005,7 +1006,7 @@ class ComponentbuilderModelServer extends AdminModel // Get the basic encryption key. $basickey = ComponentbuilderHelper::getCryptKey('basic'); // Get the encryption object - $basic = new FOFEncryptAes($basickey); + $basic = new AES($basickey); // Encrypt data signature. if (isset($data['signature']) && $basickey) diff --git a/admin/models/servers.php b/admin/models/servers.php index f84fd2a09..dfa6b5215 100644 --- a/admin/models/servers.php +++ b/admin/models/servers.php @@ -14,6 +14,7 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\FOF\Encrypt\AES; /** * Servers List Model @@ -356,7 +357,7 @@ class ComponentbuilderModelServers extends ListModel // Get the basic encryption key. $basickey = ComponentbuilderHelper::getCryptKey('basic'); // Get the encryption object. - $basic = new FOFEncryptAes($basickey); + $basic = new AES($basickey); // Set values to display correctly. if (ComponentbuilderHelper::checkArray($items)) diff --git a/admin/models/site_view.php b/admin/models/site_view.php index 1b9aee892..844413f06 100644 --- a/admin/models/site_view.php +++ b/admin/models/site_view.php @@ -16,6 +16,11 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Site_view Admin Model @@ -169,7 +174,7 @@ class ComponentbuilderModelSite_view extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'site_view__'.$id); ComponentbuilderHelper::set('site_view__'.$id, $this->vastDevMod); // set a return value if found @@ -177,7 +182,7 @@ class ComponentbuilderModelSite_view extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -339,7 +344,7 @@ class ComponentbuilderModelSite_view extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'site_view__'.$id); ComponentbuilderHelper::set('site_view__'.$id, $this->vastDevMod); // set a return value if found @@ -347,7 +352,7 @@ class ComponentbuilderModelSite_view extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -510,7 +515,7 @@ class ComponentbuilderModelSite_view extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -525,9 +530,9 @@ class ComponentbuilderModelSite_view extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -589,7 +594,7 @@ class ComponentbuilderModelSite_view extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::canEditState($record); } @@ -859,7 +864,7 @@ class ComponentbuilderModelSite_view extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('site_view'); } - if (!$this->canDo->get('core.create') || !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.create') && !$this->canDo->get('site_view.batch')) { return false; } @@ -1002,7 +1007,7 @@ class ComponentbuilderModelSite_view extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('site_view'); } - if (!$this->canDo->get('core.edit') && !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.edit') && !$this->canDo->get('site_view.batch')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; @@ -1115,44 +1120,44 @@ class ComponentbuilderModelSite_view extends AdminModel // always reset the snippets $data['snippet'] = 0; // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } // if codename is empty create from name - if (empty($data['codename']) || !ComponentbuilderHelper::checkString($data['codename'])) + if (empty($data['codename']) || !UtilitiesStringHelper::check($data['codename'])) { - $data['codename'] = ComponentbuilderHelper::safeString($data['name']); + $data['codename'] = UtilitiesStringHelper::safe($data['name']); } else { // always make safe string - $data['codename'] = ComponentbuilderHelper::safeString($data['codename']); + $data['codename'] = UtilitiesStringHelper::safe($data['codename']); } // if context is empty create from codename - if (empty($data['context']) || !ComponentbuilderHelper::checkString($data['context'])) + if (empty($data['context']) || !UtilitiesStringHelper::check($data['context'])) { $data['context'] = $data['codename']; } else { // always make safe string - $data['context'] = ComponentbuilderHelper::safeString($data['context']); + $data['context'] = UtilitiesStringHelper::safe($data['context']); } // Set the GUID if empty or not valid if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('site_view', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('site_view', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "site_view", $data['id'])) + while (!GuidHelper::valid($data['guid'], "site_view", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the custom_get items to data. if (isset($data['custom_get']) && is_array($data['custom_get'])) diff --git a/admin/models/site_views.php b/admin/models/site_views.php index 5294f6603..2b9240617 100644 --- a/admin/models/site_views.php +++ b/admin/models/site_views.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; /** * Site_views List Model @@ -69,7 +71,7 @@ class ComponentbuilderModelSite_views extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND') . ' -' ); // check if we have joomla components - if (($joomla_components = ComponentbuilderHelper::getByTypeTheIdsSystemNames('joomla_component')) !== false) + if (($joomla_components = JCBFilterHelper::names('joomla_component')) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_COMPONENT') . ' -' @@ -78,7 +80,7 @@ class ComponentbuilderModelSite_views extends ListModel $options = $options + $joomla_components; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'joomla_component', 'filter', @@ -301,7 +303,7 @@ class ComponentbuilderModelSite_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_site_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_site_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -506,7 +508,7 @@ class ComponentbuilderModelSite_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_site_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_site_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/models/snippet.php b/admin/models/snippet.php index 6b875bd09..acd7306bd 100644 --- a/admin/models/snippet.php +++ b/admin/models/snippet.php @@ -16,6 +16,9 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Snippet Admin Model @@ -241,9 +244,9 @@ class ComponentbuilderModelSnippet extends AdminModel // Only load the GUID if new item (or empty) if (0 == $id || !($val = $form->getValue('guid'))) { - $form->setValue('guid', null, ComponentbuilderHelper::GUID()); + $form->setValue('guid', null, GuidHelper::get()); } - + return $form; } @@ -305,7 +308,7 @@ class ComponentbuilderModelSnippet extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::canEditState($record); } @@ -575,7 +578,7 @@ class ComponentbuilderModelSnippet extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('snippet'); } - if (!$this->canDo->get('core.create') || !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.create') && !$this->canDo->get('snippet.batch')) { return false; } @@ -718,7 +721,7 @@ class ComponentbuilderModelSnippet extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('snippet'); } - if (!$this->canDo->get('core.edit') && !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.edit') && !$this->canDo->get('snippet.batch')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; @@ -836,7 +839,7 @@ class ComponentbuilderModelSnippet extends AdminModel // get the library name $type = ($name = ComponentbuilderHelper::getVar('snippet_type', $item['type'], 'id', 'name')) ? $name:'No Library'; // build the filename - $filename = ComponentbuilderHelper::safeString($library . ' - (' . $type . ') ' . $item['name'], 'filename', '', false). '.json'; + $filename = UtilitiesStringHelper::safe($library . ' - (' . $type . ') ' . $item['name'], 'filename', '', false). '.json'; // now get the contributor details (slow) $contributor = ComponentbuilderHelper::getContributorDetails($filename); // now update the local snippet contributor details @@ -850,15 +853,15 @@ class ComponentbuilderModelSnippet extends AdminModel if (empty($data['guid']) && $data['id'] > 0) { // get the existing one - $data['guid'] = (string) ComponentbuilderHelper::getVar('snippet', $data['id'], 'id', 'guid'); + $data['guid'] = (string) GetHelper::var('snippet', $data['id'], 'id', 'guid'); } + // Set the GUID if empty or not valid - while (!ComponentbuilderHelper::validGUID($data['guid'], "snippet", $data['id'])) + while (!GuidHelper::valid($data['guid'], "snippet", $data['id'])) { // must always be set - $data['guid'] = (string) ComponentbuilderHelper::GUID(); - } - + $data['guid'] = (string) GuidHelper::get(); + } // Set the snippet string to base64 string. if (isset($data['snippet'])) diff --git a/admin/models/snippet_type.php b/admin/models/snippet_type.php index f4ef6768d..282a7cdd3 100644 --- a/admin/models/snippet_type.php +++ b/admin/models/snippet_type.php @@ -271,7 +271,7 @@ class ComponentbuilderModelSnippet_type extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('snippet_type.edit.state', 'com_componentbuilder'); } diff --git a/admin/models/snippets.php b/admin/models/snippets.php index b02657bc6..8c32f55a4 100644 --- a/admin/models/snippets.php +++ b/admin/models/snippets.php @@ -14,6 +14,9 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\StringHelper; /** * Snippets List Model @@ -53,15 +56,15 @@ class ComponentbuilderModelSnippets extends ListModel public function shareSnippets($pks) { // setup the query - if (ComponentbuilderHelper::checkArray($pks)) + if (UtilitiesArrayHelper::check($pks)) { // Get the user object. - if (!ComponentbuilderHelper::checkObject($this->user)) + if (!ObjectHelper::check($this->user)) { $this->user = JFactory::getUser(); } // Create a new query object. - if (!ComponentbuilderHelper::checkObject($this->_db)) + if (!ObjectHelper::check($this->_db)) { $this->_db = JFactory::getDBO(); } @@ -99,7 +102,7 @@ class ComponentbuilderModelSnippets extends ListModel // load the items from db $items = $this->_db->loadObjectList(); // check if we have items - if (ComponentbuilderHelper::checkArray($items)) + if (UtilitiesArrayHelper::check($items)) { // get the shared paths $this->fullPath = rtrim(ComponentbuilderHelper::getFolderPath('path', 'sharepath', JFactory::getConfig()->get('tmp_path')), '/') . '/snippets'; @@ -125,7 +128,7 @@ class ComponentbuilderModelSnippets extends ListModel // just unlock the snippet $item->snippet = base64_decode($item->snippet); // build filename - $fileName = ComponentbuilderHelper::safeString($item->library . ' - (' . $item->type . ') ' . $item->name, 'filename', '', false) . '.json'; + $fileName = StringHelper::safe($item->library . ' - (' . $item->type . ') ' . $item->name, 'filename', '', false) . '.json'; // if the snippet has its own contributor details set, then do not change if (!strlen($item->contributor_company) || !strlen($item->contributor_name) || !strlen($item->contributor_email) || !strlen($item->contributor_website)) { diff --git a/admin/models/template.php b/admin/models/template.php index 751332deb..a77583393 100644 --- a/admin/models/template.php +++ b/admin/models/template.php @@ -16,6 +16,9 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper; /** * Componentbuilder Template Admin Model @@ -123,7 +126,7 @@ class ComponentbuilderModelTemplate extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'template__'.$id); ComponentbuilderHelper::set('template__'.$id, $this->vastDevMod); // set a return value if found @@ -131,7 +134,7 @@ class ComponentbuilderModelTemplate extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -209,7 +212,7 @@ class ComponentbuilderModelTemplate extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'template__'.$id); ComponentbuilderHelper::set('template__'.$id, $this->vastDevMod); // set a return value if found @@ -217,7 +220,7 @@ class ComponentbuilderModelTemplate extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -341,7 +344,7 @@ class ComponentbuilderModelTemplate extends AdminModel // now get all the editor fields $editors = $form->getXml()->xpath("//field[@type='editor']"); // check if we found any - if (ComponentbuilderHelper::checkArray($editors)) + if (UtilitiesArrayHelper::check($editors)) { foreach ($editors as $editor) { @@ -413,7 +416,7 @@ class ComponentbuilderModelTemplate extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::canEditState($record); } @@ -683,7 +686,7 @@ class ComponentbuilderModelTemplate extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('template'); } - if (!$this->canDo->get('core.create') || !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.create') && !$this->canDo->get('template.batch')) { return false; } @@ -821,7 +824,7 @@ class ComponentbuilderModelTemplate extends AdminModel $this->canDo = ComponentbuilderHelper::getActions('template'); } - if (!$this->canDo->get('core.edit') && !$this->canDo->get('core.batch')) + if (!$this->canDo->get('core.edit') && !$this->canDo->get('template.batch')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; diff --git a/admin/models/validation_rule.php b/admin/models/validation_rule.php index ffab04481..864092ff0 100644 --- a/admin/models/validation_rule.php +++ b/admin/models/validation_rule.php @@ -16,6 +16,8 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\ObjectHelper; /** * Componentbuilder Validation_rule Admin Model @@ -106,7 +108,7 @@ class ComponentbuilderModelValidation_rule extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'validation_rule__'.$id); ComponentbuilderHelper::set('validation_rule__'.$id, $this->vastDevMod); // set a return value if found @@ -114,7 +116,7 @@ class ComponentbuilderModelValidation_rule extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -178,7 +180,7 @@ class ComponentbuilderModelValidation_rule extends AdminModel else { // set the vast development method key - $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + $this->vastDevMod = UtilitiesStringHelper::random(50); ComponentbuilderHelper::set($this->vastDevMod, 'validation_rule__'.$id); ComponentbuilderHelper::set('validation_rule__'.$id, $this->vastDevMod); // set a return value if found @@ -186,7 +188,7 @@ class ComponentbuilderModelValidation_rule extends AdminModel $return = $jinput->get('return', null, 'base64'); ComponentbuilderHelper::set($this->vastDevMod . '__return', $return); // set a GUID value if found - if (isset($item) && ComponentbuilderHelper::checkObject($item) && isset($item->guid) + if (isset($item) && ObjectHelper::check($item) && isset($item->guid) && method_exists('ComponentbuilderHelper', 'validGUID') && ComponentbuilderHelper::validGUID($item->guid)) { @@ -365,7 +367,7 @@ class ComponentbuilderModelValidation_rule extends AdminModel return false; } } - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return $user->authorise('validation_rule.edit.state', 'com_componentbuilder'); } diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index 9fd04d5ce..f34caaf5e 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -2,9 +2,11 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_component` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `add_admin_event` TINYINT(1) NOT NULL DEFAULT 0, + `add_backup_folder_path` TINYINT(1) NOT NULL DEFAULT 0, `add_css_admin` TINYINT(1) NOT NULL DEFAULT 0, `add_css_site` TINYINT(1) NOT NULL DEFAULT 0, `add_email_helper` TINYINT(1) NOT NULL DEFAULT 0, + `add_git_folder_path` TINYINT(1) NOT NULL DEFAULT 0, `add_javascript` TINYINT(1) NOT NULL DEFAULT 0, `add_license` TINYINT(1) NOT NULL DEFAULT 0, `add_menu_prefix` CHAR(1) NOT NULL DEFAULT '', @@ -29,6 +31,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_component` ( `adduikit` TINYINT(1) NOT NULL DEFAULT 0, `assets_table_fix` TINYINT(1) NOT NULL DEFAULT 3, `author` VARCHAR(255) NOT NULL DEFAULT '', + `backup_folder_path` VARCHAR(255) NOT NULL DEFAULT '', `bom` CHAR(64) NOT NULL DEFAULT '', `buildcomp` TINYINT(1) NOT NULL DEFAULT 0, `buildcompsql` MEDIUMTEXT NOT NULL, @@ -51,6 +54,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_component` ( `emptycontributors` TINYINT(1) NOT NULL DEFAULT 0, `export_buy_link` VARCHAR(255) NOT NULL DEFAULT '', `export_key` TEXT NOT NULL, + `git_folder_path` VARCHAR(255) NOT NULL DEFAULT '', `guid` VARCHAR(36) NOT NULL DEFAULT '', `image` CHAR(64) NOT NULL DEFAULT '', `javascript` TEXT NOT NULL, @@ -105,18 +109,17 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_component` ( PRIMARY KEY (`id`), KEY `idx_system_name` (`system_name`), KEY `idx_name_code` (`name_code`), - KEY `idx_mvc_versiondate` (`mvc_versiondate`), KEY `idx_remove_line_breaks` (`remove_line_breaks`), - KEY `idx_add_placeholders` (`add_placeholders`), KEY `idx_debug_linenr` (`debug_linenr`), + KEY `idx_mvc_versiondate` (`mvc_versiondate`), + KEY `idx_add_placeholders` (`add_placeholders`), + KEY `idx_add_sales_server` (`add_sales_server`), + KEY `idx_translation_tool` (`translation_tool`), KEY `idx_add_license` (`add_license`), KEY `idx_license_type` (`license_type`), - KEY `idx_add_email_helper` (`add_email_helper`), KEY `idx_addreadme` (`addreadme`), - KEY `idx_add_sales_server` (`add_sales_server`), KEY `idx_add_powers` (`add_powers`), - KEY `idx_translation_tool` (`translation_tool`), - KEY `idx_add_php_helper_both` (`add_php_helper_both`), + KEY `idx_add_backup_folder_path` (`add_backup_folder_path`), KEY `idx_add_php_helper_admin` (`add_php_helper_admin`), KEY `idx_add_admin_event` (`add_admin_event`), KEY `idx_add_php_helper_site` (`add_php_helper_site`), @@ -137,10 +140,13 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_component` ( KEY `idx_emptycontributors` (`emptycontributors`), KEY `idx_add_update_server` (`add_update_server`), KEY `idx_update_server_target` (`update_server_target`), + KEY `idx_add_git_folder_path` (`add_git_folder_path`), KEY `idx_creatuserhelper` (`creatuserhelper`), KEY `idx_adduikit` (`adduikit`), - KEY `idx_guid` (`guid`), KEY `idx_addfootable` (`addfootable`), + KEY `idx_add_email_helper` (`add_email_helper`), + KEY `idx_add_php_helper_both` (`add_php_helper_both`), + KEY `idx_guid` (`guid`), KEY `idx_access` (`access`), KEY `idx_checkout` (`checked_out`), KEY `idx_createdby` (`created_by`), @@ -313,6 +319,10 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_power` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `add_head` TINYINT(1) NOT NULL DEFAULT 0, + `add_licensing_template` TINYINT(1) NOT NULL DEFAULT 1, + `approved` TINYINT(1) NOT NULL DEFAULT 0, + `approved_paths` TEXT NOT NULL, + `composer` TEXT NOT NULL, `description` TEXT NOT NULL, `extends` VARCHAR(36) NOT NULL DEFAULT '', `extends_custom` VARCHAR(64) NOT NULL DEFAULT '', @@ -320,6 +330,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_power` ( `head` TEXT NOT NULL, `implements` TEXT NULL, `implements_custom` VARCHAR(1024) NOT NULL DEFAULT '', + `licensing_template` TEXT NOT NULL, `load_selection` TEXT NOT NULL, `main_class_code` MEDIUMTEXT NOT NULL, `method_selection` TEXT NOT NULL, @@ -346,8 +357,9 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_power` ( KEY `idx_system_name` (`system_name`), KEY `idx_namespace` (`namespace`), KEY `idx_type` (`type`), - KEY `idx_implements_custom` (`implements_custom`), KEY `idx_extends_custom` (`extends_custom`), + KEY `idx_implements_custom` (`implements_custom`), + KEY `idx_add_licensing_template` (`add_licensing_template`), KEY `idx_guid` (`guid`), KEY `idx_name` (`name`), KEY `idx_access` (`access`), @@ -1143,10 +1155,10 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_fieldtype` ( KEY `idx_indexes` (`indexes`), KEY `idx_datadefault_other` (`datadefault_other`), KEY `idx_datadefault` (`datadefault`), - KEY `idx_datalenght_other` (`datalenght_other`), KEY `idx_datatype` (`datatype`), KEY `idx_has_defaults` (`has_defaults`), KEY `idx_datalenght` (`datalenght`), + KEY `idx_datalenght_other` (`datalenght_other`), KEY `idx_guid` (`guid`), KEY `idx_catid` (`catid`), KEY `idx_access` (`access`), @@ -1962,41 +1974,6 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_plugin_files_folders_urls INSERT INTO `#__componentbuilder_joomla_component` (`id`, `add_license`, `license_type`, `mvc_versiondate`, `add_css_admin`, `add_css_site`, `add_email_helper`, `add_javascript`, `add_php_helper_admin`, `add_php_helper_both`, `add_php_helper_site`, `add_php_postflight_install`, `add_php_method_uninstall`, `add_php_postflight_update`, `add_php_preflight_install`, `add_php_preflight_update`, `add_placeholders`, `add_sql`, `add_sql_uninstall`, `addfootable`, `adduikit`, `add_admin_event`, `add_site_event`, `add_update_server`, `add_sales_server`, `sales_server`, `update_server`, `update_server_target`, `update_server_url`, `php_admin_event`, `php_site_event`, `addreadme`, `readme`, `author`, `bom`, `buildcomp`, `buildcompsql`, `companyname`, `component_version`, `copyright`, `creatuserhelper`, `css_admin`, `css_site`, `dashboard`, `dashboard_type`, `debug_linenr`, `description`, `email`, `emptycontributors`, `export_buy_link`, `joomla_source_link`, `export_key`, `image`, `javascript`, `license`, `name`, `system_name`, `toignore`, `name_code`, `number`, `php_helper_admin`, `php_helper_both`, `php_helper_site`, `php_postflight_install`, `php_method_uninstall`, `php_postflight_update`, `php_preflight_install`, `php_preflight_update`, `short_description`, `sql`, `sql_uninstall`, `website`, `published`, `created`, `modified`, `hits`, `ordering`, `whmcs_key`, `whmcs_url`, `guid`) VALUES (25, '', 1, '', '', '', '', '', '', '', 1, 1, '', '', '', '', '', '', '', '', 1, '', '', 1, '', '', '', 2, 'https://raw.githubusercontent.com/namibia/demo-joomla-3-component/master/demo_updateserver.xml', '', '', 1, 'IyAjIyNDb21wb25lbnRfbmFtZSMjIyAoIyMjVkVSU0lPTiMjIykNCg0KIVsjIyNDb21wb25lbnRfbmFtZSMjIyBpbWFnZV0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25hbWliaWEvZGVtby1qb29tbGEtMy1jb21wb25lbnQvbWFzdGVyL2FkbWluL2Fzc2V0cy9pbWFnZXMvdmRtLWNvbXBvbmVudC5qcGcgIlRoZSAjIyNDb21wb25lbnRfbmFtZSMjIyIpDQoNCiMjI0RFU0NSSVBUSU9OIyMjDQoNCiMgQnVpbGQgRGV0YWlscw0KDQorICpDb21wYW55KjogWyMjI0NPTVBBTllOQU1FIyMjXSgjIyNBVVRIT1JXRUJTSVRFIyMjKQ0KKyAqQXV0aG9yKjogWyMjI0FVVEhPUiMjI10obWFpbHRvOiMjI0FVVEhPUkVNQUlMIyMjKQ0KKyAqTmFtZSo6IFsjIyNDb21wb25lbnRfbmFtZSMjI10oIyMjQVVUSE9SV0VCU0lURSMjIykNCisgKkZpcnN0IEJ1aWxkKjogIyMjQ1JFQVRJT05EQVRFIyMjDQorICpMYXN0IEJ1aWxkKjogIyMjQlVJTEREQVRFIyMjDQorICpWZXJzaW9uKjogIyMjVkVSU0lPTiMjIw0KKyAqQ29weXJpZ2h0KjogIyMjQ09QWVJJR0hUIyMjDQorICpMaWNlbnNlKjogIyMjTElDRU5TRSMjIw0KDQojIyBCdWlsZCBUaW1lDQoNCioqIyMjdG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjdG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqIChhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNhdmVkIC0NCmR1ZSB0byBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKSkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gbmV2ZXIgbWFraW5nIG9uZSBtaXN0YWtlIG9yIHRha2luZyBhbnkgY29mZmVlIGJyZWFrLikNCg0KKyAqTGluZSBjb3VudCo6ICoqIyMjTElORV9DT1VOVCMjIyoqDQorICpGaWxlIGNvdW50KjogKiojIyNGSUxFX0NPVU5UIyMjKioNCisgKkZvbGRlciBjb3VudCo6ICoqIyMjRk9MREVSX0NPVU5UIyMjKioNCg0KKiojIyNhY3R1YWxIb3Vyc1NwZW50IyMjIEhvdXJzKiogb3IgKiojIyNhY3R1YWxEYXlzU3BlbnQjIyMgRWlnaHQgSG91ciBEYXlzKiogKHRoZSBhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNwZW50KQ0KDQo+ICh3aXRoIHRoZSBmb2xsb3dpbmcgYnJlYWsgZG93bjoNCj4gKipkZWJ1Z2dpbmcgQCMjI2RlYnVnZ2luZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA0Ow0KPiAqKnBsYW5uaW5nIEAjIyNwbGFubmluZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA3Ow0KPiAqKm1hcHBpbmcgQCMjI21hcHBpbmdIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gMTA7DQo+ICoqb2ZmaWNlIEAjIyNvZmZpY2VIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gNjspDQoNCioqIyMjYWN0dWFsVG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjYWN0dWFsVG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqDQooYSB0b3RhbCBvZiB0aGUgcmVhbGlzdGljIHRpbWUgZnJhbWUgZm9yIHRoaXMgcHJvamVjdCkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gd2l0aCB0aGUgbm9ybWFsIGV2ZXJ5ZGF5IHJlYWxpdGllcyBhdCB0aGUgb2ZmaWNlLCB0aGF0IGluY2x1ZGVzIHRoZSBjb21wb25lbnQgcGxhbm5pbmcsIG1hcHBpbmcgJiBkZWJ1Z2dpbmcuKQ0KDQpQcm9qZWN0IGR1cmF0aW9uOiAqKiMjI3Byb2plY3RXZWVrVGltZSMjIyB3ZWVrcyoqIG9yICoqIyMjcHJvamVjdE1vbnRoVGltZSMjIyBtb250aHMqKg0KDQo+IFRoaXMgKipjb21wb25lbnQqKiB3YXMgYnVpbGQgd2l0aCBhIEpvb21sYSBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKS4NCj4gRGV2ZWxvcGVkIGJ5IFtMbGV3ZWxseW4gdmFuIGRlciBNZXJ3ZV0obWFpbHRvOmpvb21sYUB2ZG0uaW8pDQoNCltDVVNUT01DT0RFPXJlYWRNRWNvbnRyaWJ1dG9yc10=', 'Llewellyn van der Merwe', 'default.txt', '', '', 'Vast Development Method', '2.1.0', 'Copyright (C) 2015. All Rights Reserved', '', '', '', '', 1, '', 'Just a basic demo of the most basic implementations of the [Joomla](http://www.joomla.org) Component Builder\'s ability.', 'joomla@vdm.io', '', '', 'https://github.com/Llewellynvdm/Joomla-Demo-Component', 'hcYWdyvSGveEnSAqqDG8ybLDgwZ50qMcicGZ3GYQkHc=', 'images/vdm/demo500.jpg', '', 'GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html', 'Demo', 'Demo (public)', '.git', 'demo', 4, '', '', 'CS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGZhbmN5IGRhdGUNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZhbmN5RGF0ZSgkZGF0ZSkNCgl7DQoJCWlmICghc2VsZjo6aXNWYWxpZFRpbWVTdGFtcCgkZGF0ZSkpDQoJCXsNCgkJCSRkYXRlID0gc3RydG90aW1lKCRkYXRlKTsNCgkJfQ0KCQlyZXR1cm4gZGF0ZSgnalMgXG9cZiBGIFknLCRkYXRlKTsNCgl9DQoNCgkvKioNCgkgKglDaGFuZ2UgdG8gbmljZSBmYW5jeSB0aW1lIGFuZCBkYXRlDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeURhdGVUaW1lKCR0aW1lKQ0KCXsNCgkJaWYgKCFzZWxmOjppc1ZhbGlkVGltZVN0YW1wKCR0aW1lKSkNCgkJew0KCQkJJHRpbWUgPSBzdHJ0b3RpbWUoJHRpbWUpOw0KCQl9DQoJCXJldHVybiBkYXRlKCcoRzppKSBqUyBcb1xmIEYgWScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGhvdXI6bWludXRlcyB0aW1lDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeVRpbWUoJHRpbWUpDQoJew0KCQlpZiAoIXNlbGY6OmlzVmFsaWRUaW1lU3RhbXAoJHRpbWUpKQ0KCQl7DQoJCQkkdGltZSA9IHN0cnRvdGltZSgkdGltZSk7DQoJCX0NCgkJcmV0dXJuIGRhdGUoJ0c6aScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoZWNrIGlmIHN0cmluZyBpcyBhIHZhbGlkIHRpbWUgc3RhbXANCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzVmFsaWRUaW1lU3RhbXAoJHRpbWVzdGFtcCkNCgl7DQoJCXJldHVybiAoKGludCkgJHRpbWVzdGFtcCA9PT0gJHRpbWVzdGFtcCkNCgkJJiYgKCR0aW1lc3RhbXAgPD0gUEhQX0lOVF9NQVgpDQoJCSYmICgkdGltZXN0YW1wID49IH5QSFBfSU5UX01BWCk7DQoJfQ0K', 'CQkvLyBHZXQgQXBwbGljYXRpb24gb2JqZWN0DQoJCSRhcHAgPSBKRmFjdG9yeTo6Z2V0QXBwbGljYXRpb24oKTsNCgkJJGFwcC0+ZW5xdWV1ZU1lc3NhZ2UoJ1RoaXMgaXMgYSBkZW1vIGNvbXBvbmVudCBkZXZlbG9wZWQgaW4gPGEgaHJlZj0iaHR0cDovL3ZkbS5iei9jb21wb25lbnQtYnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+SkNCPC9hPiEgWW91IGNhbiBidWlsZCBtb3JlIGNvbXBvbmVudHMgbGlrZSB0aGlzIHdpdGggSkNCLCBjaGVja291dCBvdXIgcGFnZSBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vdmRtLWlvL0pvb21sYS1Db21wb25lbnQtQnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+Z2l0aHViPC9hPiBmb3IgbW9yZSBpbmZvLiBUaGUgZnV0dXJlIG9mIDxhIGhyZWY9Imh0dHA6Ly92ZG0uYnovY29tcG9uZW50LWJ1aWxkZXIiIHRhZ2V0PSJfYmFsbmsiIHRpdGxlPSJKb29tbGEgQ29tcG9uZW50IEJ1aWxkZXIiPkpvb21sYSBDb21wb25lbnQgRGV2ZWxvcG1lbnQ8L2E+IGlzIEhlcmUhJywgJ0luZm8nKTs=', '', '', '', '', 'Demo Component', '', '', 'https://www.vdm.io/', 1, '2016-10-18 11:44:09', '2020-11-17 17:19:57', '', 10, 'G2Rww7JuEI+de+Bm1ljKg72Hgt3MUfutTh1P15UayKU=', '', 'efde995e-60aa-4b39-b644-44349dfb660d'); --- --- Dumping data for table `#__componentbuilder_power` --- - -INSERT INTO `#__componentbuilder_power` (`id`, `add_head`, `description`, `extends`, `extends_custom`, `guid`, `head`, `implements`, `implements_custom`, `load_selection`, `main_class_code`, `method_selection`, `name`, `namespace`, `power_version`, `property_selection`, `system_name`, `type`, `use_selection`, `params`, `published`, `created`, `modified`, `version`, `ordering`) VALUES -(1, '', 'Basic shared utilities, a legacy implementation\r\n\r\n@since 3.0.9', '', '', '79d765b3-7319-4988-9730-446c7f347020', '', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBNYWluIEFjdGl2ZSBMYW5ndWFnZQ0KCSAqIA0KCSAqIEB2YXIgICAgICBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyAkbGFuZ1RhZzsNCg0KCS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYSBzdHJpbmcgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyBUaGUgc3RyaW5nIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrU3RyaW5nKCRzdHJpbmcpOiBib29sDQoJew0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKTsNCgl9DQoNCgkvKioNCgkgKiBTaG9ydGVuIGEgc3RyaW5nDQoJICoNCgkgKiBAaW5wdXQgICAgc3RyaW5nICAkc3RyaW5nIFRoYXQgeW91IHdvdWxkIGxpa2UgdG8gc2hvcnRlbg0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6c2hvcnRlbigkc3RyaW5nLCAkbGVuZ3RoLCAkYWRkVGlwKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNob3J0ZW4oJHN0cmluZywgJGxlbmd0aCA9IDQwLCAkYWRkVGlwID0gdHJ1ZSkNCgl7DQoJCXJldHVybiBTdHJpbmdIZWxwZXI6OnNob3J0ZW4oJHN0cmluZywgJGxlbmd0aCwgJGFkZFRpcCk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIHN0cmluZ3Mgc2FmZSAodmFyaW91cyB3YXlzKQ0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyBUaGF0IHlvdSB3b3VsZCBsaWtlIHRvIG1ha2Ugc2FmZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6c2FmZSgkc3RyaW5nLCAkdHlwZSwgJHNwYWNlciwgJHJlcGxhY2VOdW1iZXJzLCAka2VlcE9ubHlDaGFyYWN0ZXJzKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVTdHJpbmcoJHN0cmluZywgJHR5cGUgPSAnTCcsICRzcGFjZXIgPSAnXycsICRyZXBsYWNlTnVtYmVycyA9IHRydWUsICRrZWVwT25seUNoYXJhY3RlcnMgPSB0cnVlKQ0KCXsNCgkJLy8gc2V0IHRoZSBsb2NhbCBjb21wb25lbnQgb3B0aW9uDQoJCXNlbGY6OnNldENvbXBvbmVudE9wdGlvbigpOw0KDQoJCXJldHVybiBTdHJpbmdIZWxwZXI6OnNhZmUoJHN0cmluZywgJHR5cGUsICRzcGFjZXIsICRyZXBsYWNlTnVtYmVycywgJGtlZXBPbmx5Q2hhcmFjdGVycyk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGNsYXNzIG9yIGZ1bmN0aW9uIG5hbWUgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgbmFtZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBDbGFzc2Z1bmN0aW9uSGVscGVyOjpzYWZlKCRuYW1lKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVDbGFzc0Z1bmN0aW9uTmFtZSgkbmFtZSkNCgl7DQoJCXJldHVybiBDbGFzc2Z1bmN0aW9uSGVscGVyOjpzYWZlKCRuYW1lKTsNCgl9DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgbmFtZXMgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICogQGlucHV0CWJvb2xlYW4gICAgICBUaGUgc3dpdGNoIHRvIHJldHVybiBhbiBBTEwgVVBQRVIgQ0FTRSBzdHJpbmcNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSBzdHJpbmcgdG8gdXNlIGluIHdoaXRlIHNwYWNlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgRmllbGRIZWxwZXI6OnNhZmUoJHN0cmluZywgJGFsbGNhcCwgJHNwYWNlcik7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlRmllbGROYW1lKCRzdHJpbmcsICRhbGxjYXAgPSBmYWxzZSwgJHNwYWNlciA9ICdfJykNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gRmllbGRIZWxwZXI6OnNhZmUoJHN0cmluZywgJGFsbGNhcCwgJHNwYWNlcik7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGZpZWxkIHR5cGUgbmFtZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBUeXBlSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FmZVR5cGVOYW1lKCRzdHJpbmcpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJc2VsZjo6c2V0Q29tcG9uZW50T3B0aW9uKCk7DQoNCgkJcmV0dXJuIFR5cGVIZWxwZXI6OnNhZmUoJHN0cmluZyk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIG5hbWVzcGFjZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBOYW1lc3BhY2VIZWxwZXI6OnNhZmUoJHN0cmluZyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlTmFtZXNwYWNlKCRzdHJpbmcpDQoJew0KCQlyZXR1cm4gTmFtZXNwYWNlSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKiANCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRyYW5zbGl0ZXJhdGUoJHN0cmluZykNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjp0cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKiANCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6aHRtbCgkdmFyLCAkY2hhcnNldCwgJHNob3J0ZW4sICRsZW5ndGgpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaHRtbEVzY2FwZSgkdmFyLCAkY2hhcnNldCA9ICdVVEYtOCcsICRzaG9ydGVuID0gZmFsc2UsICRsZW5ndGggPSA0MCkNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpodG1sKCR2YXIsICRjaGFyc2V0LCAkc2hvcnRlbiwgJGxlbmd0aCk7DQoJfQ0KDQoJLyoqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqIA0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgU3RyaW5nSGVscGVyOjpudW1iZXJzKCRzdHJpbmcpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVwbGFjZU51bWJlcnMoJHN0cmluZykNCgl7DQoJCXJldHVybiBTdHJpbmdIZWxwZXI6Om51bWJlcnMoJHN0cmluZyk7DQoJfQ0KDQoJLyoqDQoJICogQ29udmVydCBhbiBpbnRlZ2VyIGludG8gYW4gRW5nbGlzaCB3b3JkIHN0cmluZw0KCSAqIFRoYW5rcyB0byBUb20gTmljaG9sc29uIDxodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RydmFsLnBocCM0MTk4OD4NCgkgKg0KCSAqIEBpbnB1dCAgICBpbnQgJHggYW4gaW50DQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgYSBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6bnVtYmVyKCR4KTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG51bWJlclRvU3RyaW5nKCR4KQ0KCXsNCgkJcmV0dXJuIFN0cmluZ0hlbHBlcjo6bnVtYmVyKCR4KTsNCgl9DQoNCgkvKioNCgkgKiBSYW5kb20gS2V5DQoJICoNCgkgKiBAaW5wdXQgaW50ICRzaXplIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZw0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIGEgc3RyaW5nIG9mIHJhbmRvbSBjaGFyYWN0ZXJzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBTdHJpbmdIZWxwZXI6OnJhbmRvbSgkc2l6ZSk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByYW5kb21rZXkoJHNpemUpOiBzdHJpbmcNCgl7DQoJCXJldHVybiBTdHJpbmdIZWxwZXI6OnJhbmRvbSgkc2l6ZSk7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgeW91IGhhdmUgYSBqc29uIHN0cmluZw0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyAgVGhlIGpzb24gc3RyaW5nIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgSnNvbkhlbHBlcjo6Y2hlY2soJHN0cmluZyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVja0pzb24oJHN0cmluZyk6IGJvb2wNCgl7DQoJCXJldHVybiBKc29uSGVscGVyOjpjaGVjaygkc3RyaW5nKTsNCgl9DQoNCgkvKioNCgkgKiBAc2luY2UgIDMuMC45DQoJICogDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBKc29uSGVscGVyOjpzdHJpbmcoJHZhbHVlLCAkc3BlcmF0b3IsICR0YWJsZSwgJGlkLCAkbmFtZSk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBqc29uVG9TdHJpbmcoJHZhbHVlLCAkc3BlcmF0b3IgPSAiLCAiLCAkdGFibGUgPSBudWxsLCAkaWQgPSAnaWQnLCAkbmFtZSA9ICduYW1lJykNCgl7DQoJCXJldHVybiBKc29uSGVscGVyOjpzdHJpbmcoJHZhbHVlLCAkc3BlcmF0b3IsICR0YWJsZSwgJGlkLCAkbmFtZSk7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgeW91IGhhdmUgYW4gYXJyYXkgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIG1peGVkICRhcnJheSAgICAgICAgICAgICAgVGhlIGFycmF5IHRvIGNoZWNrDQoJICogQGlucHV0ICAgIGJvb2wgICRyZW1vdmVFbXB0eVN0cmluZyAgU2hvdWxkIHdlIHJlbW92ZSBlbXB0eSB2YWx1ZXMNCgkgKg0KCSAqIEByZXR1cm5zIGludCAgbnVtYmVyIG9mIGl0ZW1zIGluIGFycmF5IG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEFycmF5SGVscGVyOjpjaGVjaygkYXJyYXksICRyZW1vdmVFbXB0eVN0cmluZyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVja0FycmF5KCRhcnJheSwgJHJlbW92ZUVtcHR5U3RyaW5nID0gZmFsc2UpOiBpbnQNCgl7DQoJCXJldHVybiBBcnJheUhlbHBlcjo6Y2hlY2soJGFycmF5LCAkcmVtb3ZlRW1wdHlTdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIE1lcmdlIGFuIGFycmF5IG9mIGFycmF5J3MNCgkgKg0KCSAqIEBpbnB1dCAgICBtaXhlZCAgJGFycmF5cyBUaGUgYXJyYXlzIHlvdSB3b3VsZCBsaWtlIHRvIG1lcmdlDQoJICoNCgkgKiBAcmV0dXJucyBtaXhlZCBhcnJheSBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBBcnJheUhlbHBlcjo6bWVyZ2UoJGFycmF5cyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXJnZUFycmF5cygkYXJyYXlzKQ0KCXsNCgkJcmV0dXJuIEFycmF5SGVscGVyOjptZXJnZSgkYXJyYXlzKTsNCgl9DQoNCgkvKioNCgkgKiBDaGVjayBpZiB5b3UgaGF2ZSBhbiBvYmplY3Qgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIG9iamVjdCAkb2JqZWN0ICBUaGUgb2JqZWN0IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgT2JqZWN0SGVscGVyOjpjaGVjaygkb2JqZWN0KTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrT2JqZWN0KCRvYmplY3QpOiBib29sDQoJew0KCQlyZXR1cm4gT2JqZWN0SGVscGVyOjpjaGVjaygkb2JqZWN0KTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYSBWYXJpYWJsZSANCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR0YWJsZSAgICAgICAgVGhlIHRhYmxlIGZyb20gd2hpY2ggdG8gZ2V0IHRoZSB2YXJpYWJsZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR3aGVyZSAgICAgICAgVGhlIHZhbHVlIHdoZXJlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlU3RyaW5nICBUaGUgdGFyZ2V0L2ZpZWxkIHN0cmluZyB3aGVyZS9uYW1lDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoYXQgICAgICAgICBUaGUgcmV0dXJuIGZpZWxkDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG9wZXJhdG9yICAgICBUaGUgb3BlcmF0b3IgYmV0d2VlbiAkd2hlcmVTdHJpbmcvZmllbGQgYW5kICR3aGVyZS92YWx1ZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRtYWluICAgICAgICAgVGhlIGNvbXBvbmVudCBpbiB3aGljaCB0aGUgdGFibGUgaXMgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIG1peCBzdHJpbmcvaW50L2Zsb2F0DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OnZhcigkdGFibGUsICR3aGVyZSwgJHdoZXJlU3RyaW5nLCAkd2hhdCwgJG9wZXJhdG9yLCAkbWFpbik7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRWYXIoJHRhYmxlLCAkd2hlcmUgPSBudWxsLCAkd2hlcmVTdHJpbmcgPSAndXNlcicsICR3aGF0ID0gJ2lkJywgJG9wZXJhdG9yID0gJz0nLCAkbWFpbiA9IG51bGwpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJc2VsZjo6c2V0Q29tcG9uZW50T3B0aW9uKCk7DQoNCgkJcmV0dXJuIEdldEhlbHBlcjo6dmFyKCR0YWJsZSwgJHdoZXJlLCAkd2hlcmVTdHJpbmcsICR3aGF0LCAkb3BlcmF0b3IsICRtYWluKTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYXJyYXkgb2YgdmFyaWFibGVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdGFibGUgICAgICAgIFRoZSB0YWJsZSBmcm9tIHdoaWNoIHRvIGdldCB0aGUgdmFyaWFibGVzDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqIEBwYXJhbSAgIGJvb2wgICAgICR1bmlxdWUgICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYSB1bmlxdWUgYXJyYXkNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OnZhcnMoJHRhYmxlLCAkd2hlcmUsICR3aGVyZVN0cmluZywgJHdoYXQsICRvcGVyYXRvciwgJG1haW4sICR1bmlxdWUpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmFycygkdGFibGUsICR3aGVyZSA9IG51bGwsICR3aGVyZVN0cmluZyA9ICd1c2VyJywgJHdoYXQgPSAnaWQnLCAkb3BlcmF0b3IgPSAnSU4nLCAkbWFpbiA9IG51bGwsICR1bmlxdWUgPSB0cnVlKQ0KCXsNCgkJLy8gc2V0IHRoZSBsb2NhbCBjb21wb25lbnQgb3B0aW9uDQoJCXNlbGY6OnNldENvbXBvbmVudE9wdGlvbigpOw0KDQoJCXJldHVybiBHZXRIZWxwZXI6OnZhcnMoJHRhYmxlLCAkd2hlcmUsICR3aGVyZVN0cmluZywgJHdoYXQsICRvcGVyYXRvciwgJG1haW4sICR1bmlxdWUpOw0KCX0NCg0KCS8qKg0KCSAqIGdldCBhbGwgc3RyaW5ncyBiZXR3ZWVuIHR3byBvdGhlciBzdHJpbmdzDQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkc3RhcnQgICAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRlbmQgICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheSAgICAgICAgICBPbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OmFsbEJldHdlZW4oJGNvbnRlbnQsICRzdGFydCwgJGVuZCk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRBbGxCZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQpDQoJew0KCQlyZXR1cm4gR2V0SGVscGVyOjphbGxCZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQpOw0KCX0NCg0KCS8qKg0KCSAqIGdldCBhIHN0cmluZyBiZXR3ZWVuIHR3byBvdGhlciBzdHJpbmdzDQoJICogDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJGNvbnRlbnQgICAgVGhlIGNvbnRlbnQgdG8gc2VhcmNoDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJHN0YXJ0ICAgICAgICBUaGUgc3RhcnRpbmcgdmFsdWUNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkZW5kICAgICAgICAgVGhlIGVuZGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRkZWZhdWx0ICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpZiBub25lIGZvdW5kDQoJICoNCgkgKiBAcmV0dXJuICBzdHJpbmcgICAgICAgICAgT24gc3VjY2VzcyAvIGVtcHR5IHN0cmluZyBvbiBmYWlsdXJlDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OmJldHdlZW4oJGNvbnRlbnQsICRzdGFydCwgJGVuZCwgJGRlZmF1bHQpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0QmV0d2VlbigkY29udGVudCwgJHN0YXJ0LCAkZW5kLCAkZGVmYXVsdCA9ICcnKQ0KCXsNCgkJcmV0dXJuIEdldEhlbHBlcjo6YmV0d2VlbigkY29udGVudCwgJHN0YXJ0LCAkZW5kLCAkZGVmYXVsdCk7DQoJfQ0KDQoJLyoqDQoJICogYmMgbWF0aCB3cmFwcGVyICh2ZXJ5IGJhc2ljIG5vdCBmb3IgYWNjb3VudGluZykNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR0eXBlICAgIFRoZSB0eXBlIGJjIG1hdGgNCgkgKiBAcGFyYW0gICBpbnQgICAgICAkdmFsMSAgICBUaGUgZmlyc3QgdmFsdWUNCgkgKiBAcGFyYW0gICBpbnQgICAgICAkdmFsMiAgICBUaGUgc2Vjb25kIHZhbHVlDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0fGludA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgTWF0aEhlbHBlcjo6YmMoJHR5cGUsICR2YWwxLCAkdmFsMiwgJHNjYWxlKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGJjbWF0aCgkdHlwZSwgJHZhbDEsICR2YWwyLCAkc2NhbGUgPSAwKQ0KCXsNCgkJcmV0dXJuIE1hdGhIZWxwZXI6OmJjKCR0eXBlLCAkdmFsMSwgJHZhbDIsICRzY2FsZSk7DQoJfQ0KDQoJLyoqDQoJICogQmFzaWMgc3VtIG9mIGFuIGFycmF5IHdpdGggbW9yZSBwcmVjaXNpb24NCgkgKg0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGFycmF5ICAgIFRoZSB2YWx1ZXMgdG8gc3VtDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0fGludA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgTWF0aEhlbHBlcjo6c3VtKCRhcnJheSwgJHNjYWxlKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGJjc3VtKCRhcnJheSwgJHNjYWxlID0gNCkNCgl7DQoJCXJldHVybiBNYXRoSGVscGVyOjpzdW0oJGFycmF5LCAkc2NhbGUpOw0KCX0NCg0KICAgICAgICAvKioNCiAgICAgICAgICogY3JlYXRlIHBsdWdpbiBjbGFzcyBuYW1lDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSBncm91cCBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgbmFtZQ0KCSAqDQoJICogQHJldHVybiBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFBsdWdpbkhlbHBlcjo6c2FmZSgkbmFtZSwgJGdyb3VwKTsNCiAgICAgICAgICovDQogICAgICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlUGx1Z2luQ2xhc3NOYW1lKCRncm91cCwgJG5hbWUpDQoJew0KCQlyZXR1cm4gUGx1Z2luSGVscGVyOjpzYWZlQ2xhc3NOYW1lKCRuYW1lLCAkZ3JvdXApOw0KCX0NCg0KCS8qKg0KCSAqIFJldHVybnMgYSBHVUlEdjQgc3RyaW5nDQoJICogDQoJICogVGhhbmtzIHRvIERhdmUgUGVhcnNvbiAoYW5kIG90aGVyKQ0KCSAqIGh0dHBzOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmNvbS1jcmVhdGUtZ3VpZC5waHAjMTE5MTY4IA0KCSAqDQoJICogVXNlcyB0aGUgYmVzdCBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgbWV0aG9kDQoJICogZm9yIGFsbCBzdXBwb3J0ZWQgcGxhdGZvcm1zIHdpdGggZmFsbGJhY2sgdG8gYW4gb2xkZXIsDQoJICogbGVzcyBzZWN1cmUgdmVyc2lvbi4NCgkgKg0KCSAqIEBwYXJhbSBib29sICR0cmltDQoJICoNCgkgKiBAcmV0dXJuIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgR3VpZEhlbHBlcjo6Z2V0KCR0cmltKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIEdVSUQoJHRyaW0gPSB0cnVlKQ0KCXsNCgkJcmV0dXJuIEd1aWRIZWxwZXI6OmdldCgkdHJpbSk7DQoJfQ0KDQoJLyoqDQoJICogVmFsaWRhdGUgdGhlIEdsb2JhbGx5IFVuaXF1ZSBJZGVudGlmaWVyICggYW5kIGNoZWNrIGlmIHRhYmxlIGFscmVhZHkgaGFzIHRoaXMgaWRlbnRpZmllcikNCgkgKg0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGd1aWQNCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICR0YWJsZQ0KCSAqIEBwYXJhbSBpbnQgICAgICAgICAgICAkaWQNCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGNvbXBvbmVudA0KCSAqDQoJICogQHJldHVybiBib29sDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHdWlkSGVscGVyOjp2YWxpZCgkZ3VpZCwgJHRhYmxlLCAkaWQsICRjb21wb25lbnQpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmFsaWRHVUlEKCRndWlkLCAkdGFibGUgPSBudWxsLCAkaWQgPSAwLCAkY29tcG9uZW50ID0gbnVsbCkNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gR3VpZEhlbHBlcjo6dmFsaWQoJGd1aWQsICR0YWJsZSwgJGlkLCAkY29tcG9uZW50KTsNCgl9DQoNCgkvKioNCgkgKiBnZXQgdGhlIElURU0gb2YgYSBHVUlEIGJ5IHRhYmxlDQoJICoNCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkZ3VpZA0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICR0YWJsZQ0KCSAqIEBwYXJhbSBzdHJpbmcvYXJyYXkgICR3aGF0DQoJICogQHBhcmFtIHN0cmluZ3xudWxsICAgICRjb21wb25lbnQNCgkgKg0KCSAqIEByZXR1cm4gbWl4DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHdWlkSGVscGVyOjp2YWxpZCgkZ3VpZCwgJHRhYmxlLCAkaWQsICRjb21wb25lbnQpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0R1VJRCgkZ3VpZCwgJHRhYmxlLCAkd2hhdCA9ICdhLmlkJywgJGNvbXBvbmVudCA9IG51bGwpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJc2VsZjo6c2V0Q29tcG9uZW50T3B0aW9uKCk7DQoNCgkJcmV0dXJuIEd1aWRIZWxwZXI6Oml0ZW0oJGd1aWQsICR0YWJsZSwgJHdoYXQsICRjb21wb25lbnQpOw0KCX0NCg0KCS8qKg0KCSAqIFZhbGlkYXRlIHRoZSBHbG9iYWxseSBVbmlxdWUgSWRlbnRpZmllcg0KCSAqDQoJICogVGhhbmtzIHRvIExld2llDQoJICogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE1MTU0NTYvMTQyOTY3Nw0KCSAqDQoJICogQHBhcmFtIHN0cmluZyAkZ3VpZA0KCSAqDQoJICogQHJldHVybiBib29sDQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEd1aWRIZWxwZXI6OnZhbGlkYXRlKCRndWlkKTsNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHZhbGlkYXRlR1VJRCgkZ3VpZCkNCgl7DQoJCXJldHVybiBHdWlkSGVscGVyOjp2YWxpZGF0ZSgkZ3VpZCk7DQoJfQ0KDQoJLyoqDQoJICogVGhlIHppcHBlciBtZXRob2QNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICR3b3JraW5nRElSICAgIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGl0ZW1zIG11c3QgYmUgemlwcGVkDQoJICogQHBhcmFtICBzdHJpbmcgICAkZmlsZXBhdGggICAgICAgICAgVGhlIHBhdGggdG8gd2hlcmUgdGhlIHppcCBmaWxlIG11c3QgYmUgcGxhY2VkDQoJICoNCgkgKiBAcmV0dXJuICBib29sIHRydWUgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OnppcCgkd29ya2luZ0RJUiwgJGZpbGVwYXRoKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHppcCgkd29ya2luZ0RJUiwgJiRmaWxlcGF0aCkNCgl7DQoJCXJldHVybiBGaWxlSGVscGVyOjp6aXAoJHdvcmtpbmdESVIsICRmaWxlcGF0aCk7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IHRoZSBjb250ZW50IG9mIGEgZmlsZQ0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICRwYXRoICAgVGhlIHBhdGggdG8gdGhlIGZpbGUNCgkgKiBAcGFyYW0gIHN0cmluZy9ib29sICAgJG5vbmUgICBUaGUgcmV0dXJuIHZhbHVlIGlmIG5vIGNvbnRlbnQgd2FzIGZvdW5kDQoJICoNCgkgKiBAcmV0dXJuICBzdHJpbmcgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OmdldENvbnRlbnQoJHBhdGgsICRub25lKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEZpbGVDb250ZW50cygkcGF0aCwgJG5vbmUgPSAnJykNCgl7DQoJCXJldHVybiBGaWxlSGVscGVyOjpnZXRDb250ZW50KCRwYXRoLCAkbm9uZSk7DQoJfQ0KDQoJLyoqDQoJICogV3JpdGUgYSBmaWxlIHRvIHRoZSBzZXJ2ZXINCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHBhdGggICAgVGhlIHBhdGggYW5kIGZpbGUgbmFtZSB3aGVyZSB0byBzYWZlIHRoZSBkYXRhDQoJICogQHBhcmFtICBzdHJpbmcgICAkZGF0YSAgICBUaGUgZGF0YSB0byBzYWZlDQoJICoNCgkgKiBAcmV0dXJuICBib29sIHRydWUgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OndyaXRlKCRwYXRoLCAkZGF0YSk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB3cml0ZUZpbGUoJHBhdGgsICRkYXRhKQ0KCXsNCgkJcmV0dXJuIEZpbGVIZWxwZXI6OndyaXRlKCRwYXRoLCAkZGF0YSk7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGFsbCB0aGUgZmlsZSBwYXRocyBpbiBmb2xkZXIgYW5kIHN1YiBmb2xkZXJzDQoJICogDQoJICogQHBhcmFtICAgc3RyaW5nICAkZm9sZGVyICAgICBUaGUgbG9jYWwgcGF0aCB0byBwYXJzZQ0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGZpbGVUeXBlcyAgVGhlIHR5cGUgb2YgZmlsZXMgdG8gZ2V0DQoJICoNCgkgKiBAcmV0dXJuICB2b2lkDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OmdldFBhdGhzKCRmb2xkZXIsICRmaWxlVHlwZXMgLCAkcmVjdXJzZSwgJGZ1bGwpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0QWxsRmlsZVBhdGhzKCRmb2xkZXIsICRmaWxlVHlwZXMgPSBhcnJheSgnXC5waHAnLCAnXC5qcycsICdcLmNzcycsICdcLmxlc3MnKSwgJHJlY3Vyc2UgPSB0cnVlLCAkZnVsbCA9IHRydWUpDQoJew0KCQlyZXR1cm4gRmlsZUhlbHBlcjo6Z2V0UGF0aHMoJGZvbGRlciwgJGZpbGVUeXBlcyAsICRyZWN1cnNlLCAkZnVsbCk7DQoJfQ0KDQoJLyoqDQoJICogR2V0IHRoZSBmaWxlIHBhdGggb3IgdXJsDQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICR0eXBlICAgICAgICAgICAgICBUaGUgKHVybC9wYXRoKSB0eXBlIHRvIHJldHVybg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHRhcmdldCAgICAgICAgICAgIFRoZSBQYXJhbXMgVGFyZ2V0IG5hbWUgKGlmIHNldCkNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRmaWxlVHlwZSAgICAgICAgICBUaGUga2luZCBvZiBmaWxlbmFtZSB0byBnZW5lcmF0ZSAoaWYgbm90IHNldCBubyBmaWxlIG5hbWUgaXMgZ2VuZXJhdGVkKQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJGtleSAgICAgICAgICAgICAgIFRoZSBrZXkgdG8gYWRqdXN0IHRoZSBmaWxlbmFtZSAoaWYgbm90IHNldCBpZ25vcmVkKQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJGRlZmF1bHQgICAgICAgICAgIFRoZSBkZWZhdWx0IHBhdGggaWYgbm90IHNldCBpbiBQYXJhbXMgKGZhbGxiYWNrIHBhdGgpDQoJICogQHBhcmFtICBib29sICAgICAkY3JlYXRlSWZOb3RTZXQgICAgVGhlIHN3aXRjaCB0byBjcmVhdGUgdGhlIGZvbGRlciBpZiBub3QgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIHN0cmluZyAgICBPbiBzdWNjZXNzIHRoZSBwYXRoIG9yIHVybCBpcyByZXR1cm5lZCBiYXNlZCBvbiB0aGUgdHlwZSByZXF1ZXN0ZWQNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgRmlsZUhlbHBlcjo6Z2V0UGF0aCgkdHlwZSwgJHRhcmdldCwgJGZpbGVUeXBlLCAka2V5LCAkZGVmYXVsdCwgJGNyZWF0ZUlmTm90U2V0KTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEZpbGVQYXRoKCR0eXBlID0gJ3BhdGgnLCAkdGFyZ2V0ID0gJ2ZpbGVwYXRoJywgJGZpbGVUeXBlID0gbnVsbCwgJGtleSA9ICcnLCAkZGVmYXVsdCA9ICcnLCAkY3JlYXRlSWZOb3RTZXQgPSB0cnVlKQ0KCXsNCgkJLy8gc2V0IHRoZSBsb2NhbCBjb21wb25lbnQgb3B0aW9uDQoJCXNlbGY6OnNldENvbXBvbmVudE9wdGlvbigpOw0KDQoJCXJldHVybiBGaWxlSGVscGVyOjpnZXRQYXRoKCR0eXBlLCAkdGFyZ2V0LCAkZmlsZVR5cGUsICRrZXksICRkZWZhdWx0LCAkY3JlYXRlSWZOb3RTZXQpOw0KCX0NCg0KCS8qKg0KCSAqIENoZWNrIGlmIGZpbGUgZXhpc3QNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHBhdGggICBUaGUgdXJsL3BhdGggdG8gY2hlY2sNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wgICAgICBJZiBleGlzdCB0cnVlDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OmV4aXN0cygkcGF0aCk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB1cmxFeGlzdHMoJHBhdGgpDQoJew0KCQlyZXR1cm4gRmlsZUhlbHBlcjo6ZXhpc3RzKCRwYXRoKTsNCgl9DQoNCgkvKioNCgkgKiBTZXQgdGhlIGNvbXBvbmVudCBvcHRpb24NCgkgKg0KCSAqIEBwYXJhbSAgIFN0cmluZ3xudWxsICAgICAgICRvcHRpb24gICAgVGhlIG9wdGlvbiBmb3IgdGhlIGNvbXBvbmVudC4NCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRDb21wb25lbnRPcHRpb24oJG9wdGlvbiA9IG51bGwpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJaWYgKGVtcHR5KCRvcHRpb24pKQ0KCQl7DQoJCQlpZiAoZW1wdHkoSGVscGVyOjokb3B0aW9uKSAmJiBwcm9wZXJ0eV9leGlzdHMoX19DTEFTU19fLCAnQ29tcG9uZW50Q29kZU5hbWUnKSkNCgkJCXsNCgkJCQlIZWxwZXI6OiRvcHRpb24gPSAnY29tXycgLiBzZWxmOjokQ29tcG9uZW50Q29kZU5hbWU7DQoJCQl9DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlIZWxwZXI6OiRvcHRpb24gPSAkb3B0aW9uOw0KCQl9DQoJfQ0K', '{}', 'Utilities', 'VDM\\Joomla\\Utilities', '1.0.0', '{}', 'Utilities', 'trait', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\",\"as\":\"default\"},\"use_selection1\":{\"use\":\"4b225c51-d293-48e4-b3f6-5136cf5c3f18\",\"as\":\"default\"},\"use_selection2\":{\"use\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\",\"as\":\"default\"},\"use_selection3\":{\"use\":\"91004529-94a9-4590-b842-e7c6b624ecf5\",\"as\":\"default\"},\"use_selection4\":{\"use\":\"152c8793-8b75-4715-996a-257b9f65451c\",\"as\":\"default\"},\"use_selection5\":{\"use\":\"db87c339-5bb6-4291-a7ef-2c48ea1b06bc\",\"as\":\"default\"},\"use_selection6\":{\"use\":\"9c513baf-b279-43fd-ae29-a585c8cbc4f0\",\"as\":\"default\"},\"use_selection7\":{\"use\":\"a223b31e-ea1d-4cdf-92ae-5f9becffaff0\",\"as\":\"default\"},\"use_selection8\":{\"use\":\"9ef0eb24-aae4-4f5a-99af-d724db44808f\",\"as\":\"default\"},\"use_selection9\":{\"use\":\"a8935cbe-7701-40dc-bfd5-675f2d600954\",\"as\":\"default\"},\"use_selection10\":{\"use\":\"30c5b4c2-f75f-4d15-869a-f8bfedd87358\",\"as\":\"default\"},\"use_selection11\":{\"use\":\"ce8cf834-6bac-44fb-941c-861f7e046cc0\",\"as\":\"default\"},\"use_selection12\":{\"use\":\"3cf76fbf-fd95-4a33-878e-7aff6d36b7f6\",\"as\":\"default\"},\"use_selection13\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2021-11-06 13:25:19', '2022-06-07 13:29:51', 69, 1), -(2, 1, 'To extrude tables structures from lila', '', '', '050f5a27-3aab-4087-8a3d-e2302fcfd5db', 'dXNlIERpcmVjdG9yeUl0ZXJhdG9yOw0KdXNlIFNwbEZpbGVPYmplY3Q7DQp1c2Ugc3RkQ2xhc3M7DQp1c2UgZnVuY3Rpb24gYXJyYXlfcG9wOw0KdXNlIGZ1bmN0aW9uIGNvdW50Ow0KdXNlIGZ1bmN0aW9uIGV4cGxvZGU7DQp1c2UgZnVuY3Rpb24gZmlsZV9leGlzdHM7DQp1c2UgZnVuY3Rpb24gaXNfbnVsbDsNCnVzZSBmdW5jdGlvbiBhcnJheV9yZXZlcnNlOw0KdXNlIGZ1bmN0aW9uIHN0cl9yZXBsYWNlOw0KdXNlIGZ1bmN0aW9uIHN0cmxlbjsNCnVzZSBmdW5jdGlvbiBzdHJwb3M7DQp1c2UgZnVuY3Rpb24gc3RycnBvczsNCnVzZSBmdW5jdGlvbiBzdWJzdHI7DQp1c2UgZnVuY3Rpb24gdHJpbTsNCg==', '', '', '', 'CS8qKg0KCSAqIEFkZGluZyB0aGUgdXRpbGl0aWVzIHRyYWl0IHRvIHRoaXMgY2xhc3MNCgkgKiBTaW5jZSB3ZSBuZWVkIHNvbWUgb2YgaXRzIGZ1bmN0aW9ucw0KCSAqLw0KCXVzZSBVdGlsOw0KDQoJLyoqDQoJICogVGhlIG1vZHVsZSBuYW1lDQoJICoNCgkgKiBAdmFyIHN0cmluZw0KCSAqLw0KCXByb3RlY3RlZCAkbW9kdWxlOw0KDQoJLyoqDQoJICogVGhlIGFjdGlvbg0KCSAqDQoJICogQHZhciBzdHJpbmcNCgkgKi8NCglwcm90ZWN0ZWQgJGFjdGlvbjsNCg0KCS8qKg0KCSAqIFRoZSB0YWJsZXMgYXJyYXkNCgkgKg0KCSAqIEB2YXIgYXJyYXkNCgkgKi8NCglwcm90ZWN0ZWQgJHRhYmxlcyA9IGFycmF5KCk7DQoNCgkvKioNCgkgKiBUaGUgbGlua3MgYXJyYXkNCgkgKg0KCSAqIEB2YXIgYXJyYXkNCgkgKi8NCglwcm90ZWN0ZWQgJGxpbmtzID0gYXJyYXkoKTsNCg0KCS8qKg0KCSAqIFRoZSB0bXAgYXJyYXkNCgkgKg0KCSAqIEB2YXIgYXJyYXkNCgkgKi8NCglwcm90ZWN0ZWQgJHRtcCA9IGFycmF5KCk7DQoNCgkvKioNCgkgKiBUaGUgZmllbGQgbGlua2VyDQoJICoNCgkgKiBAdmFyIG1peGVkDQoJICovDQoJcHJvdGVjdGVkICRmaWVsZCA9IG51bGw7DQoNCgkvKioNCgkgKiBUaGUgdGFibGUgbGlua2VyDQoJICoNCgkgKiBAdmFyIG1peGVkDQoJICovDQoJcHJvdGVjdGVkICR0YWJsZSA9IG51bGw7DQoNCgkvKioNCgkgKiBUaGUgaW5kZXhlcg0KCSAqDQoJICogQHZhciBtaXhlZA0KCSAqLw0KCXByb3RlY3RlZCAkaW5kZXggPSBmYWxzZTsNCg0KCS8qKg0KCSAqIFRoZSBkaXJlY3RvcnkNCgkgKg0KCSAqIEB2YXIgRGlyZWN0b3J5SXRlcmF0b3INCgkgKi8NCglwcm90ZWN0ZWQgJGRpcmVjdG9yeTsNCg0KCS8qKg0KCSAqIENvbnN0cnVjdG9yDQoJICoNCgkgKiBAcGFyYW0gICBEaXJlY3RvcnlJdGVyYXRvciAgJGRpciAgVGhlIGRpcmVjdG9yeSBvYmplY3Qgb2YgZGYgZmlsZXMNCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoRGlyZWN0b3J5SXRlcmF0b3IgJGRpcikNCgl7DQoJCS8vIHNldCB0aGUgZGlyZWN0b3J5DQoJCSR0aGlzLT5kaXJlY3RvcnkgPSAkZGlyOw0KCQkvLyBsb2FkIHRoZSBsaW5rYWdlDQoJCSR0aGlzLT5zZXRMaW5rcygpOw0KCQkvLyBidWlsZCB0aGUganNvbiB0YWJsZSBzdHJ1Y3R1cmUNCgkJJHRoaXMtPnNldFRhYmxlcygpOw0KCQkvLyBsaW5lLXVwIHRoZSBpbmRleCBhbmQgbGlua3MNCgkJJHRoaXMtPnNldFJlbGF0aW9uc2hpcHMoKTsNCgl9DQoNCgkvKioNCgkgKiBnZXQgcHJvcGVydHkNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGtleSAgVGhlIGtleSB2YWx1ZSB0byByZXR1cm4NCgkgKg0KCSAqIEByZXR1cm4gbWl4ZWQNCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19nZXQoc3RyaW5nICRrZXkpDQoJew0KCQkka2V5ID0gc3RydG9sb3dlcigka2V5KTsNCgkJaWYgKCRrZXkgPT09ICd0YWJsZXMnKQ0KCQl7DQoJCQlyZXR1cm4gJHRoaXMtPnRhYmxlczsNCgkJfQ0KCQllbHNlaWYgKCRrZXkgPT09ICdsaW5rcycpDQoJCXsNCgkJCXJldHVybiAkdGhpcy0+bGlua3M7DQoJCX0NCgkJLy8ganVzdCB0d28gbGF5ZXJzICh0YWJsZS5tb2R1bGVfbmFtZS50YWJsZV9uYW1lKSBpbiBmb3Igbm93DQoJCWVsc2VpZiAoc3RycG9zKCRrZXksICcuJykgIT09IGZhbHNlKQ0KCQl7DQoJCQkka2V5X2FycmF5ID0gZXhwbG9kZSgnLicsICRrZXkpOw0KCQkJLy8gdGFibGVzDQoJCQlpZiAoJGtleV9hcnJheVswXSA9PT0gJ3RhYmxlJyAmJiBpc3NldCgka2V5X2FycmF5WzFdKSAmJiBpc3NldCgkdGhpcy0+dGFibGVzWyRrZXlfYXJyYXlbMV1dKQ0KCQkJCSYmIGlzc2V0KCRrZXlfYXJyYXlbMl0pICYmIGlzc2V0KCR0aGlzLT50YWJsZXNbJGtleV9hcnJheVsxXV1bJGtleV9hcnJheVsyXV0pKQ0KCQkJew0KCQkJCXJldHVybiAkdGhpcy0+dGFibGVzWyRrZXlfYXJyYXlbMV1dWyRrZXlfYXJyYXlbMl1dOw0KCQkJfQ0KCQkJLy8gbGlua3MNCgkJCWVsc2VpZiAoJGtleV9hcnJheVswXSA9PT0gJ2xpbmsnICYmIGlzc2V0KCRrZXlfYXJyYXlbMV0pICYmIGlzc2V0KCR0aGlzLT5saW5rc1ska2V5X2FycmF5WzFdXSkNCgkJCQkmJiBpc3NldCgka2V5X2FycmF5WzJdKSAmJiBpc3NldCgkdGhpcy0+bGlua3NbJGtleV9hcnJheVsxXV1bJGtleV9hcnJheVsyXV0pKQ0KCQkJew0KCQkJCXJldHVybiAkdGhpcy0+bGlua3NbJGtleV9hcnJheVsxXV1bJGtleV9hcnJheVsyXV07DQoJCQl9DQoJCX0NCg0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogbGluLXVwIHRoZSBsaW5rcyBhbmQgaW5kZXggdmFsdWVzDQoJICoNCgkgKiBAcmV0dXJuICB2b2lkDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldFJlbGF0aW9uc2hpcHMoKQ0KCXsNCgkJLy8gbGluZSB1cCBpbmRleCBmaWVsZHMNCgkJZm9yZWFjaCAoJHRoaXMtPnRtcFsnaW5kZXgnXSBhcyAkbW9kID0+ICR0YWJsZXMpDQoJCXsNCgkJCWZvcmVhY2ggKCR0YWJsZXMgYXMgJHRhYmxlID0+ICRpbmRleF9uYW1lcykNCgkJCXsNCgkJCQlmb3JlYWNoICgkaW5kZXhfbmFtZXMgYXMgJGluZGV4ID0+ICRmaWVsZHMpDQoJCQkJew0KCQkJCQkkdGhpcy0+dGFibGVzWyRtb2RdWyR0YWJsZV0tPmluZGV4WyRpbmRleF0tPmluZGV4X2ZpZWxkID0gJGZpZWxkczsNCgkJCQl9DQoJCQl9DQoJCX0NCgkJLy8gY2xlYXIgdGhlIHRtcCBpbmRleA0KCQl1bnNldCgkdGhpcy0+dG1wWydpbmRleCddKTsNCgkJLy8gbGluZSB1cCBsaW5rcyB3aXRoIHRoZSBsaW5rZWQgZGF0YQ0KCQlmb3JlYWNoICgkdGhpcy0+dG1wWydsaW5rcyddIGFzICRwYXJlbnRfbW9kID0+ICRjaGlsZHJlbikNCgkJew0KCQkJLy8gdGhpc19tb2RlbChwYXJlbnRfbW9kKSA9IG90aGVyX3RhYmxlc1tjaGlsZHJlbj1jaGlsZF0gPSB0aGlzX3RhYmxlW3BhcmVudHM9cGFyZW50XSA9IGtleXNbZmllbGRzXQ0KCQkJZm9yZWFjaCAoJGNoaWxkcmVuIGFzICRjaGlsZCA9PiAkcGFyZW50cykNCgkJCXsNCgkJCQlmb3JlYWNoICgkcGFyZW50cyBhcyAkcGFyZW50ID0+ICRmaWVsZHMpDQoJCQkJew0KCQkJCQkvLyBjaGVjayBpZiB0aGlzIGlzIGEgbGVnaXRpbWF0ZSBtYXRjaA0KCQkJCQlpZiAoISR0aGlzLT5sZWdpdGltYXRlSW5kZXhMaW5rKCRwYXJlbnRfbW9kLCAkcGFyZW50LCAkZmllbGRzKSkNCgkJCQkJew0KCQkJCQkJY29udGludWU7DQoJCQkJCX0NCgkJCQkJJGNoaWxkX21vZCA9ICR0aGlzLT5nZXRNb2ROYW1lKCRjaGlsZCk7DQoJCQkJCS8vIHNldCB0aGUgbGluaw0KCQkJCQlpZiAoIWlzc2V0KCR0aGlzLT50YWJsZXNbJGNoaWxkX21vZF1bJGNoaWxkXS0+bGlua3MpKQ0KCQkJCQl7DQoJCQkJCQkkdGhpcy0+dGFibGVzWyRjaGlsZF9tb2RdWyRjaGlsZF0tPmxpbmtzID0gYXJyYXkoKTsNCgkJCQkJfQ0KCQkJCQkvLyBub3cgc2V0IHRoZSBtb2R1bGUNCgkJCQkJaWYgKCFpc3NldCgkdGhpcy0+dGFibGVzWyRjaGlsZF9tb2RdWyRjaGlsZF0tPmxpbmtzWyRwYXJlbnRfbW9kXSkpDQoJCQkJCXsNCgkJCQkJCSR0aGlzLT50YWJsZXNbJGNoaWxkX21vZF1bJGNoaWxkXS0+bGlua3NbJHBhcmVudF9tb2RdID0gbmV3IHN0ZENsYXNzKCk7DQoJCQkJCQkvLyBzZXQgdGhlIG5hbWUNCgkJCQkJCSR0aGlzLT50YWJsZXNbJGNoaWxkX21vZF1bJGNoaWxkXS0+bGlua3NbJHBhcmVudF9tb2RdLT5tb2R1bGUgPSAkcGFyZW50X21vZDsNCgkJCQkJfQ0KCQkJCQkvLyBub3cgc2V0IHRoZSB0YWJsZQ0KCQkJCQlpZiAoIWlzc2V0KCR0aGlzLT50YWJsZXNbJGNoaWxkX21vZF1bJGNoaWxkXS0+bGlua3NbJHBhcmVudF9tb2RdLT50YWJsZXMpKQ0KCQkJCQl7DQoJCQkJCQkkdGhpcy0+dGFibGVzWyRjaGlsZF9tb2RdWyRjaGlsZF0tPmxpbmtzWyRwYXJlbnRfbW9kXS0+dGFibGVzID0gYXJyYXkoKTsNCgkJCQkJfQ0KCQkJCQkvLyBzZXQgdGhlIGZpZWxkcw0KCQkJCQlmb3JlYWNoICgkZmllbGRzIGFzICRmaWVsZCkNCgkJCQkJew0KCQkJCQkJJHRoaXMtPnRhYmxlc1skY2hpbGRfbW9kXVskY2hpbGRdLT5saW5rc1skcGFyZW50X21vZF0tPnRhYmxlc1skcGFyZW50XVtdID0gJGZpZWxkOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KDQoJLyoqDQoJICogY2hlY2sgaWYgYSBmaWVsZCBpcyByZWFsbHkgYW4gaW5kZXggbGluaw0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkbW9kICAgICBUaGUgbW9kdWxlIHRhYmxlIHRvIGNoZWNrDQoJICogQHBhcmFtICAgc3RyaW5nICAkdGFibGUgICBUaGUgdGFibGUgaW5kZXggdG8gY2hlY2sNCgkgKiBAcGFyYW0gICBhcnJheSAgICRmaWVsZHMgIFRoZSBmaWVsZHMgdGhhdCBtdXN0IGJlIHBhcnQgb2YgdGhlIG1vZHVsZS50YWJsZS5pbmRleA0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBsZWdpdGltYXRlSW5kZXhMaW5rKHN0cmluZyAkbW9kLCBzdHJpbmcgJHRhYmxlLCBhcnJheSAkZmllbGRzKTogYm9vbA0KCXsNCgkJLy8gY2hlY2sgaWYgdGFibGUgaGFzIGtleXMNCgkJaWYgKGlzc2V0KCR0aGlzLT5saW5rc1skbW9kXVskdGFibGVdLT5rZXlzKSAmJiAkdGhpcy0+Y2hlY2tBcnJheSgkdGhpcy0+bGlua3NbJG1vZF1bJHRhYmxlXS0+a2V5cykgJiYgJHRoaXMtPmNoZWNrQXJyYXkoJGZpZWxkcykpDQoJCXsNCgkJCSRvbmUgPSAoYXJyYXkpIGFycmF5X2RpZmYoJHRoaXMtPmxpbmtzWyRtb2RdWyR0YWJsZV0tPmtleXMsICRmaWVsZHMpOw0KCQkJJHR3byA9IChhcnJheSkgYXJyYXlfZGlmZigkZmllbGRzLCAkdGhpcy0+bGlua3NbJG1vZF1bJHRhYmxlXS0+a2V5cyk7DQoJCQlpZiAoISR0aGlzLT5jaGVja0FycmF5KCRvbmUpICYmICEkdGhpcy0+Y2hlY2tBcnJheSgkdHdvKSkNCgkJCXsNCgkJCQlyZXR1cm4gdHJ1ZTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogYnVpbGQgdGhlIGpzb24gc3RydWN0dXJlcw0KCSAqDQoJICogQHJldHVybiAgdm9pZA0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRUYWJsZXMoKQ0KCXsNCgkJLy8gc2V0IHRoZSBhY3Rpb24NCgkJJHRoaXMtPmFjdGlvbiA9ICd0YWJsZXMnOw0KCQkkdGhpcy0+ZmllbGQgID0gbnVsbDsNCgkJJHRoaXMtPnRhYmxlICA9IG51bGw7DQoJCSR0aGlzLT5pbmRleCAgPSBmYWxzZTsNCgkJLy8gbm93IGdvIG92ZXIgdGhlbQ0KCQlmb3JlYWNoICgkdGhpcy0+ZGlyZWN0b3J5IGFzICRmaWxlX2luZm8pDQoJCXsNCgkJCS8vIHdlIGRvIG5vdCBhY3Qgb24gZGlyZWN0b3J5IGRvdA0KCQkJaWYgKCEkZmlsZV9pbmZvLT5pc0RvdCgpKQ0KCQkJew0KCQkJCS8vIGdldCB0aGUgcGF0aCBuYW1lDQoJCQkJJHBhdGhfbmFtZSA9ICRmaWxlX2luZm8tPmdldFBhdGhuYW1lKCk7DQoJCQkJLy8gZ2V0IHRoZSBtb2R1bGUgbmFtZQ0KCQkJCSR0aGlzLT5tb2R1bGUgPSBzdHJfcmVwbGFjZSgnX3RhYmxlcy5kZicsICcnLCAkZmlsZV9pbmZvLT5nZXRiYXNlbmFtZSgpKTsNCgkJCQkvLyB3ZSByZXNldCB0aGUgdGFibGUgd2l0aCBlYWNoIGxvb3A7DQoJCQkJJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXSA9IGFycmF5KCk7DQoJCQkJLy8gYmFzaWMgZ2V0IGZpbGUgZnVuY3Rpb24NCgkJCQlmb3JlYWNoIChuZXcgU3BsRmlsZU9iamVjdCgkcGF0aF9uYW1lKSBhcyAkbGluZV9jb250ZW50KQ0KCQkJCXsNCgkJCQkJLy8gbGV0cyBnZXQgdGhlIGxpbmsgcGFyc2VkDQoJCQkJCWlmICghJHRoaXMtPnBhcnNlcigkbGluZV9jb250ZW50KSkNCgkJCQkJew0KCQkJCQkJYnJlYWs7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBsb2FkIHRoZSBsaW5rcw0KCSAqDQoJICogQHJldHVybiAgdm9pZA0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRMaW5rcygpDQoJew0KCQkvLyBzZXQgdGhlIGFjdGlvbg0KCQkkdGhpcy0+YWN0aW9uID0gJ2xpbmtzJzsNCgkJLy8gbm93IGdvIG92ZXIgdGhlbQ0KCQlmb3JlYWNoICgkdGhpcy0+ZGlyZWN0b3J5IGFzICRmaWxlX2luZm8pDQoJCXsNCgkJCS8vIHdlIGRvIG5vdCBhY3Qgb24gZGlyZWN0b3J5IGRvdA0KCQkJaWYgKCEkZmlsZV9pbmZvLT5pc0RvdCgpKQ0KCQkJew0KCQkJCS8vIGdldCB0aGUgcGF0aCBuYW1lDQoJCQkJJHBhdGhfbmFtZSA9ICRmaWxlX2luZm8tPmdldFBhdGhuYW1lKCk7DQoJCQkJLy8gZ2V0IG1hcHBpbmcgcGF0aA0KCQkJCSRtYXBwaW5nX3BhdGhfbmFtZSA9IHN0cl9yZXBsYWNlKGFycmF5KCcvc3RydWN0dXJlLycsICcuZGYnKSwgYXJyYXkoJy9tYXBwaW5nLycsICcuZGF0YScpLCAkcGF0aF9uYW1lKTsNCgkJCQkvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhIGZpbGUNCgkJCQlpZiAoZmlsZV9leGlzdHMoJG1hcHBpbmdfcGF0aF9uYW1lKSkNCgkJCQl7DQoJCQkJCS8vIGdldCB0aGUgbW9kdWxlIG5hbWUNCgkJCQkJJHRoaXMtPm1vZHVsZSA9IHN0cl9yZXBsYWNlKCdfdGFibGVzLmRmJywgJycsICRmaWxlX2luZm8tPmdldGJhc2VuYW1lKCkpOw0KCQkJCQkvLyB3ZSByZXNldCB0aGUgdGFibGUgd2l0aCBlYWNoIGxvb3A7DQoJCQkJCSR0aGlzLT57JHRoaXMtPmFjdGlvbn1bJHRoaXMtPm1vZHVsZV0gPSBhcnJheSgpOw0KCQkJCQkvLyBiYXNpYyBnZXQgZmlsZSBmdW5jdGlvbg0KCQkJCQlmb3JlYWNoIChuZXcgU3BsRmlsZU9iamVjdCgkbWFwcGluZ19wYXRoX25hbWUpIGFzICRsaW5lX2NvbnRlbnQpDQoJCQkJCXsNCgkJCQkJCS8vIGxldHMgZ2V0IHRoZSBsaW5rYWdlcw0KCQkJCQkJaWYgKCEkdGhpcy0+c2V0TGluaygkbGluZV9jb250ZW50KSkNCgkJCQkJCXsNCgkJCQkJCQlicmVhazsNCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEZ1bmN0aW9uIHRvIGFkZCB0aGUgbGlua3MNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGxpbmUgIFRoZSBjb250ZW50IGxpbmUgZnJvbSB0aGUgZmlsZQ0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRMaW5rKHN0cmluZyAkbGluZSk6IGJvb2wNCgl7DQoJCS8vIG5vdyBuZXcgbGluZXMNCgkJaWYgKCFlbXB0eSh0cmltKCRsaW5lKSkgJiYgc3RycG9zKCRsaW5lLCAnPScpICE9PSBmYWxzZSkNCgkJew0KCQkJLy8gZ2V0IHRoZSB0YWJsZSBuYW1lDQoJCQkkZGF0YV9hcnJheSA9IChhcnJheSkgZXhwbG9kZSgnPScsICRsaW5lKTsNCgkJCS8vIG5vdyBsb29wIHRoZSBmaWVsZHMNCgkJCSRmaWVsZHMgPSBhcnJheV9yZXZlcnNlKCRkYXRhX2FycmF5KTsNCgkJCS8vIGxvYWQgdGhlIHRhYmxlDQoJCQkkdGhpcy0+dGFibGUgPSBhcnJheV9wb3AoJGZpZWxkcyk7DQoJCQkvLyBtYWtlIHN1cmUgd2UgaGF2ZSBuYW1lIGZpeCBhcHBsaWVkDQoJCQkkdGhpcy0+Zml4TmFtZXMoKTsNCgkJCS8vIGNoYW5nZSBiYWNrIHRvIGEgc3RpbmcNCgkJCSRmaWVsZHMgPSB0cmltKGltcGxvZGUoJyAnLCAkZmllbGRzKSk7DQoJCQkvLyBjaGVjayBpZiB3ZSBoYXZlIGZpZWxkcw0KCQkJaWYgKCFlbXB0eSgkZmllbGRzKSkNCgkJCXsNCgkJCQkvLyBjaGVjayBpZiB3ZSBoYXZlIGFuIGFycmF5DQoJCQkJaWYgKHN0cnBvcygkZmllbGRzLCAnKCcpICE9PSBmYWxzZSkNCgkJCQl7DQoJCQkJCS8vIGdldCBhcnJheSBmaWVsZHMNCgkJCQkJJGZpZWxkcyA9IGV4cGxvZGUoJyAnLCB0cmltKCRmaWVsZHMsICIoKSIpKTsNCgkJCQl9DQoJCQkJZWxzZQ0KCQkJCXsNCgkJCQkJLy8gc2V0IGFycmF5IGZpZWxkcw0KCQkJCQkkZmllbGRzID0gYXJyYXkoJGZpZWxkcyk7DQoJCQkJfQ0KCQkJCS8vIGNoZWNrIGlmIHdlIHN0aWxsIGhhdmUgYW4gYXJyYXkgb2YgZmllbGRzDQoJCQkJaWYgKCR0aGlzLT5jaGVja0FycmF5KCRmaWVsZHMsIHRydWUpKQ0KCQkJCXsNCgkJCQkJLy8gY2hlY2sgaWYgaXQgaXMgdGhlIGxpbmtlciBsaW5lDQoJCQkJCWlmIChzdHJwb3MoJHRoaXMtPnRhYmxlLCAnX19saW5rJykgIT09IGZhbHNlKQ0KCQkJCQl7DQoJCQkJCQkvLyBmaXggdGhlIHRhYmxlDQoJCQkJCQkkdGhpcy0+dGFibGUgPSBzdHJfcmVwbGFjZSgnX19saW5rJywgJycsICR0aGlzLT50YWJsZSk7DQoJCQkJCQkvLyBjaGVjayBpZiB3ZSBoYXZlIHRoZSBjb3JyZWN0IGNvbnZlbnRpb24NCgkJCQkJCWZvcmVhY2ggKCRmaWVsZHMgYXMgJGZpZWxkKQ0KCQkJCQkJew0KCQkJCQkJCWlmIChzdHJwb3MoJGZpZWxkLCAnLicpICE9PSBmYWxzZSkNCgkJCQkJCQl7DQoJCQkJCQkJCS8vIGdldCBhcnJheSBvdGhlcl90YWJsZS5maWVsZA0KCQkJCQkJCQkkZmllbGRfYXJyYXkgPSBleHBsb2RlKCcuJywgdHJpbSgkZmllbGQpKTsNCgkJCQkJCQkJLy8gbWFrZSBzdXJlIHdlIGhhdmUgdHdvIHZhbHVlcw0KCQkJCQkJCQlpZiAoY291bnQoJGZpZWxkX2FycmF5KSA9PSAyKQ0KCQkJCQkJCQl7DQoJCQkJCQkJCQkvLyBmaXggdGhlIG5hbWVzDQoJCQkJCQkJCQkkdGhpcy0+Zml4TmFtZSgkZmllbGRfYXJyYXlbMF0pOw0KCQkJCQkJCQkJJHRoaXMtPmZpeE5hbWUoJGZpZWxkX2FycmF5WzFdKTsNCgkJCQkJCQkJCS8vIHNldCB0aGUgdGhpc19tb2RlbCA9IG90aGVyX3RhYmxlID0gdGhpc190YWJsZSA9IGtleXMNCgkJCQkJCQkJCSR0aGlzLT50bXBbJ2xpbmtzJ11bJHRoaXMtPm1vZHVsZV1bJGZpZWxkX2FycmF5WzBdXVskdGhpcy0+dGFibGVdW10gPSAkZmllbGRfYXJyYXlbMV07DQoJCQkJCQkJCX0NCgkJCQkJCQl9DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQkJZWxzZQ0KCQkJCQl7DQoJCQkJCQkvLyBzZXQgdGhlIGZpZWxkcw0KCQkJCQkJJHRoaXMtPnNldFRhYmxlVmFsdWUoJ2tleXMnLCBhcnJheV9tYXAoZnVuY3Rpb24gKCRmaWVsZCkgew0KCQkJCQkJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIG5hbWUgZml4IGFwcGxpZWQNCgkJCQkJCQkkdGhpcy0+Zml4TmFtZSgkZmllbGQpOw0KDQoJCQkJCQkJcmV0dXJuICRmaWVsZDsNCgkJCQkJCX0sICRmaWVsZHMpKTsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCg0KCQkJcmV0dXJuIHRydWU7DQoJCX0NCg0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogRnVuY3Rpb24gdG8gbWFuYWdlIHBhcnNpbmcgb2YgZWFjaCBsaW5lDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRsaW5lICBUaGUgY29udGVudCBsaW5lIGZyb20gdGhlIGZpbGUNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wNCgkgKi8NCglwcm90ZWN0ZWQgZnVuY3Rpb24gcGFyc2VyKHN0cmluZyAkbGluZSk6IGJvb2wNCgl7DQoJCS8vIGVuZCBvZiBibG9jaw0KCQlpZiAoZW1wdHkodHJpbSgkbGluZSkpKQ0KCQl7DQoJCQkkdGhpcy0+ZmllbGQgPSBudWxsOw0KCQkJJHRoaXMtPnRhYmxlID0gbnVsbDsNCgkJCSR0aGlzLT5pbmRleCA9IGZhbHNlOw0KCQl9DQoJCS8vIGVuZCBvZiBmaWxlDQoJCWVsc2VpZiAodHJpbSgkbGluZSkgPT0gJy4nKQ0KCQl7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJLy8gbmV3IHRhYmxlDQoJCWVsc2VpZiAoc3RycG9zKCRsaW5lLCAnQUREIFRBQkxFJykgIT09IGZhbHNlKQ0KCQl7DQoJCQlyZXR1cm4gJHRoaXMtPnNldFRhYmxlKCRsaW5lKTsNCgkJfQ0KCQkvLyBuZXcgZmllbGQNCgkJZWxzZWlmIChzdHJwb3MoJGxpbmUsICdBREQgRklFTEQnKSAhPT0gZmFsc2UpDQoJCXsNCgkJCXJldHVybiAkdGhpcy0+c2V0RmllbGQoJGxpbmUpOw0KCQl9DQoJCS8vIG5ldyB0YWJsZSBpbmRleA0KCQllbHNlaWYgKHN0cnBvcygkbGluZSwgJ0FERCBJTkRFWCcpICE9PSBmYWxzZSkNCgkJew0KCQkJcmV0dXJuICR0aGlzLT5zZXRUYWJsZUluZGV4KCRsaW5lKTsNCgkJfQ0KCQkvLyBuZXcgdGFibGUgcHJvcGVydHkNCgkJZWxzZWlmICghJHRoaXMtPmluZGV4ICYmIGlzc2V0KCR0aGlzLT50YWJsZSkgJiYgc3RybGVuKCR0aGlzLT50YWJsZSkgPiAzICYmIGlzX251bGwoJHRoaXMtPmZpZWxkKQ0KCQkJJiYgaXNzZXQoJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT5uYW1lKSkNCgkJew0KCQkJcmV0dXJuICR0aGlzLT5zZXRUYWJsZVByb3BlcnR5KCRsaW5lKTsNCgkJfQ0KCQkvLyBuZXcgaW5kZXggcHJvcGVydHkNCgkJZWxzZWlmICgkdGhpcy0+aW5kZXggJiYgaXNzZXQoJHRoaXMtPnRhYmxlKSAmJiBzdHJsZW4oJHRoaXMtPnRhYmxlKSA+IDMgJiYgIWlzX251bGwoJHRoaXMtPmZpZWxkKQ0KCQkJJiYgaXNzZXQoJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT5pbmRleFskdGhpcy0+ZmllbGRdKSkNCgkJew0KCQkJcmV0dXJuICR0aGlzLT5zZXRUYWJsZUluZGV4UHJvcGVydHkoJGxpbmUpOw0KCQl9DQoJCS8vIG5ldyBmaWVsZCBwcm9wZXJ0eQ0KCQllbHNlaWYgKCEkdGhpcy0+aW5kZXggJiYgaXNzZXQoJHRoaXMtPnRhYmxlKSAmJiBzdHJsZW4oJHRoaXMtPnRhYmxlKSA+IDMgJiYgIWlzX251bGwoJHRoaXMtPmZpZWxkKQ0KCQkJJiYgaXNzZXQoJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT5maWVsZHNbJHRoaXMtPmZpZWxkXSkpDQoJCXsNCgkJCXJldHVybiAkdGhpcy0+c2V0RmllbGRQcm9wZXJ0eSgkbGluZSk7DQoJCX0NCg0KCQlyZXR1cm4gdHJ1ZTsNCg0KCX0NCg0KCS8qKg0KCSAqIGFkZCBhIG5ldyBmaWVsZA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkbGluZSAgVGhlIGxpbmUgZnJvbSB0aGUgZmlsZQ0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldEZpZWxkKHN0cmluZyAkbGluZSk6IGJvb2wNCgl7DQoJCS8vIGdldCB0aGUgbmFtZQ0KCQlpZiAoKCR0aGlzLT50YWJsZSA9ICR0aGlzLT5nZXRCZXR3ZWVuKCRsaW5lLCAnIE9GICInLCAnIiBBUycsIG51bGwpKSAhPSBudWxsICYmDQoJCQkoJHRoaXMtPmZpZWxkID0gJHRoaXMtPmdldEJldHdlZW4oJGxpbmUsICdBREQgRklFTEQgIicsICciIE9GJywgbnVsbCkpICE9IG51bGwpDQoJCXsNCgkJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIG5hbWUgZml4IGFwcGxpZWQNCgkJCSR0aGlzLT5maXhOYW1lcygpOw0KDQoJCQkvLyBzZXQgZmllbGQgdmFsdWUNCgkJCXJldHVybiAkdGhpcy0+c2V0RmllbGRWYWx1ZSgnZmllbGRzJywgJHRoaXMtPmZpZWxkLCAnbmFtZScsICR0aGlzLT5maWVsZCkgJiYNCgkJCQkvLyBzZXQgZmllbGQgdmFsdWUNCgkJCQkkdGhpcy0+c2V0RmllbGRWYWx1ZSgnZmllbGRzJywgJHRoaXMtPmZpZWxkLCAnZGF0YV90eXBlJywNCgkJCQkJdHJpbShzdWJzdHIoJGxpbmUsIHN0cnJwb3MoJGxpbmUsICdBUycpICsgMikpKTsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBhZGQgYSBuZXcgZmllbGQgcHJvcGVydHkNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGxpbmUgIFRoZSBsaW5lIGZyb20gdGhlIGZpbGUNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wNCgkgKg0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBzZXRGaWVsZFByb3BlcnR5KHN0cmluZyAkbGluZSk6IGJvb2wNCgl7DQoJCS8vIGlmIGJvdGggdGFibGUgYW5kIGZpZWxkIGFyZSBzZXQsIHRoZW4gd2UgYXJlIGxvYWRpbmcgZmllbGQgdmFsdWVzDQoJCSRsaW5lX2FycmF5ID0gKGFycmF5KSBleHBsb2RlKCcgJywgdHJpbSgkbGluZSkpOw0KCQkvLyBnZXQgdGhlIG1haW4ga2V5DQoJCSRrZXkgPSBhcnJheV9zaGlmdCgkbGluZV9hcnJheSk7DQoJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIG5hbWUgZml4IGFwcGxpZWQNCgkJJHRoaXMtPmZpeE5hbWUoJGtleSk7DQoJCS8vIGlmIHdlIGhhdmUgbW9yZSB0aGFuIG9uZSB2YWx1ZQ0KCQlpZiAoJGtleSA9PSAnaGVscCcgfHwgJGtleSA9PSAnbGFiZWwnIHx8ICRrZXkgPT0gJ2NvbHVtbl9sYWJlbCcpDQoJCXsNCgkJCS8vIHNldCBmaWVsZCB2YWx1ZQ0KCQkJcmV0dXJuICR0aGlzLT5zZXRGaWVsZFZhbHVlKCdmaWVsZHMnLCAkdGhpcy0+ZmllbGQsICRrZXksIGltcGxvZGUoJyAnLCBhcnJheV9tYXAoZnVuY3Rpb24gKCR2YWwpIHsNCgkJCQlyZXR1cm4gdHJpbSgkdmFsLCAnIicpOw0KCQkJfSwgJGxpbmVfYXJyYXkpKSk7DQoJCX0NCgkJZWxzZWlmIChjb3VudCgkbGluZV9hcnJheSkgPiAxKQ0KCQl7DQoJCQkvLyBzZXQgZmllbGQgdmFsdWUNCgkJCXJldHVybiAkdGhpcy0+c2V0RmllbGRWYWx1ZSgnZmllbGRzJywgJHRoaXMtPmZpZWxkLCAka2V5LCBhcnJheV9tYXAoZnVuY3Rpb24gKCR2YWwpIHsNCgkJCQlyZXR1cm4gdHJpbSgkdmFsLCAnIicpOw0KCQkJfSwgJGxpbmVfYXJyYXkpKTsNCgkJfQ0KCQllbHNlaWYgKGNvdW50KCRsaW5lX2FycmF5KSA9PSAxKQ0KCQl7DQoJCQkvLyBzZXQgZmllbGQgdmFsdWUNCgkJCXJldHVybiAkdGhpcy0+c2V0RmllbGRWYWx1ZSgnZmllbGRzJywgJHRoaXMtPmZpZWxkLCAka2V5LCB0cmltKGFycmF5X3NoaWZ0KCRsaW5lX2FycmF5KSwgJyInKSk7DQoJCX0NCg0KCQkvLyBzZXQgZmllbGQgdmFsdWUNCgkJcmV0dXJuICR0aGlzLT5zZXRGaWVsZFZhbHVlKCdmaWVsZHMnLCAkdGhpcy0+ZmllbGQsICRrZXksIHRydWUpOw0KCX0NCg0KCS8qKg0KCSAqIHNldCBmaWVsZCB2YWx1ZQ0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkdHlwZSAgICAgVGhlIGZpZWxkIHR5cGUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRrZXkgICAgICBUaGUgdmFsdWUgb2JqZWN0IGtleQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHBvaW50ZXIgIFRoZSB2YWx1ZSBrZXkvcG9pbnRlcg0KCSAqIEBwYXJhbSAgIG1peGVkICAgJHZhbHVlICAgIFRoZSB2YWx1ZQ0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldEZpZWxkVmFsdWUoc3RyaW5nICR0eXBlLCBzdHJpbmcgJGtleSwgc3RyaW5nICRwb2ludGVyLCAkdmFsdWUpOiBib29sDQoJew0KCQkvLyBtYWtlIHN1cmUgdGhlIHRhYmxlIGlzIHJlYWR5DQoJCWlmIChlbXB0eSgkdGhpcy0+dGFibGUpIHx8ICEkdGhpcy0+c2V0VGFibGVOYW1lKCkpDQoJCXsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQkvLyBtYWtlIHN1cmUgd2UgaGF2ZSBuYW1lIGZpeCBhcHBsaWVkDQoJCSR0aGlzLT5maXhOYW1lcygpOw0KCQkvLyBtYWtlIHN1cmUgdGhlIGZpZWxkcyB0eXBlIGFycmF5IGlzIHNldA0KCQlpZiAoIWlzc2V0KCR0aGlzLT57JHRoaXMtPmFjdGlvbn1bJHRoaXMtPm1vZHVsZV1bJHRoaXMtPnRhYmxlXS0+eyR0eXBlfSkpDQoJCXsNCgkJCS8vIHNldCB0aGUgZmllbGQgdHlwZQ0KCQkJJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT57JHR5cGV9ID0gYXJyYXkoKTsNCgkJfQ0KCQkvLyBzZXQgdGhlIHZhbHVlIGlmIG5vdCBhbHJlYWR5IHNldA0KCQlpZiAoIWlzc2V0KCR0aGlzLT57JHRoaXMtPmFjdGlvbn1bJHRoaXMtPm1vZHVsZV1bJHRoaXMtPnRhYmxlXS0+eyR0eXBlfVska2V5XSkpDQoJCXsNCgkJCSR0aGlzLT57JHRoaXMtPmFjdGlvbn1bJHRoaXMtPm1vZHVsZV1bJHRoaXMtPnRhYmxlXS0+eyR0eXBlfVska2V5XSA9IG5ldyBzdGRDbGFzcygpOw0KCQl9DQoJCS8vIHNldCB0aGUgdmFsdWUgaWYgbm90IGFscmVhZHkgc2V0DQoJCWlmICghaXNzZXQoJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT57JHR5cGV9WyRrZXldLT57JHBvaW50ZXJ9KSkNCgkJew0KCQkJJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT57JHR5cGV9WyRrZXldLT57JHBvaW50ZXJ9ID0gJHZhbHVlOw0KCQl9DQoNCgkJcmV0dXJuIHRydWU7DQoJfQ0KDQoJLyoqDQoJICogYWRkIGEgbmV3IHRhYmxlDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRsaW5lICBUaGUgbGluZSBmcm9tIHRoZSBmaWxlDQoJICoNCgkgKiBAcmV0dXJuICBib29sDQoJICoNCgkgKi8NCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0VGFibGUoc3RyaW5nICRsaW5lKTogYm9vbA0KCXsNCgkJLy8gZ2V0IHRoZSBuYW1lDQoJCWlmICgoJHRoaXMtPnRhYmxlID0gJHRoaXMtPmdldEJldHdlZW4oJGxpbmUsICdBREQgVEFCTEUgIicsICciJywgbnVsbCkpICE9IG51bGwpDQoJCXsNCgkJCS8vIHNldCB0YWJsZQ0KCQkJcmV0dXJuICR0aGlzLT5zZXRUYWJsZU5hbWUoKTsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBzZXQgdGFibGUgbmFtZQ0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldFRhYmxlTmFtZSgpOiBib29sDQoJew0KCQkvLyBtYWtlIHN1cmUgd2UgaGF2ZSBuYW1lIGZpeCBhcHBsaWVkDQoJCSR0aGlzLT5maXhOYW1lcygpOw0KCQkvLyBub3cgY2hlY2sgaWYgaXRzIHNldCBhbHJlYWR5DQoJCWlmIChpc3NldCgkdGhpcy0+dGFibGUpICYmIGlzc2V0KCR0aGlzLT57JHRoaXMtPmFjdGlvbn1bJHRoaXMtPm1vZHVsZV1bJHRoaXMtPnRhYmxlXSkpDQoJCXsNCgkJCXJldHVybiB0cnVlOw0KCQl9DQoNCgkJLy8gc2V0IHRoZSB0YWJsZSBuYW1lDQoJCXJldHVybiAkdGhpcy0+c2V0VGFibGVWYWx1ZSgnbmFtZScsICR0aGlzLT50YWJsZSk7DQoJfQ0KDQoJLyoqDQoJICogc2V0IHRhYmxlIHZhbHVlDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRrZXkgICAgVGhlIHZhbHVlIG9iamVjdCBrZXkNCgkgKiBAcGFyYW0gICBtaXhlZCAgICR2YWx1ZSAgVGhlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuICBib29sDQoJICoNCgkgKi8NCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0VGFibGVWYWx1ZShzdHJpbmcgJGtleSwgJHZhbHVlKTogYm9vbA0KCXsNCgkJLy8gY2hlY2sgaWYgdGhlIHRhYmxlIHZhbHVlIGlzIHNldA0KCQlpZiAoZW1wdHkoJHRoaXMtPnRhYmxlKSkNCgkJew0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIG5hbWUgZml4IGFwcGxpZWQNCgkJJHRoaXMtPmZpeE5hbWVzKCk7DQoJCS8vIGNoZWNrIGlmIHRhYmxlIG9iamVjdCBleGlzdA0KCQlpZiAoIWlzc2V0KCR0aGlzLT57JHRoaXMtPmFjdGlvbn1bJHRoaXMtPm1vZHVsZV1bJHRoaXMtPnRhYmxlXSkpDQoJCXsNCgkJCS8vIHNldCB0aGUgdGFibGUgb2JqZWN0DQoJCQkkdGhpcy0+eyR0aGlzLT5hY3Rpb259WyR0aGlzLT5tb2R1bGVdWyR0aGlzLT50YWJsZV0gPSBuZXcgc3RkQ2xhc3MoKTsNCgkJfQ0KCQkvLyBjaGVjayBpZiB0aGUga2V5IHZhbHVlIGV4aXN0DQoJCWlmICghaXNzZXQoJHRoaXMtPnskdGhpcy0+YWN0aW9ufVskdGhpcy0+bW9kdWxlXVskdGhpcy0+dGFibGVdLT57JGtleX0pKQ0KCQl7DQoJCQkvLyBzZXQgdGhlIHRhYmxlIHZhbHVlDQoJCQkkdGhpcy0+eyR0aGlzLT5hY3Rpb259WyR0aGlzLT5tb2R1bGVdWyR0aGlzLT50YWJsZV0tPnska2V5fSA9ICR2YWx1ZTsNCgkJfQ0KDQoJCXJldHVybiB0cnVlOw0KCX0NCg0KCS8qKg0KCSAqIGFkZCBhIG5ldyB0YWJsZSBwcm9wZXJ0eQ0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkbGluZSAgVGhlIGxpbmUgZnJvbSB0aGUgZmlsZQ0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldFRhYmxlUHJvcGVydHkoc3RyaW5nICRsaW5lKTogYm9vbA0KCXsNCgkJLy8gaWYgb25seSB0YWJsZSBpcyBzZXQsIHRoZW4gd2UgYXJlIGxvYWRpbmcgdGFibGUgdmFsdWVzDQoJCSRsaW5lX2FycmF5ID0gKGFycmF5KSBleHBsb2RlKCcgJywgdHJpbSgkbGluZSkpOw0KCQkvLyBnZXQgdGhlIG1haW4ga2V5DQoJCSRrZXkgPSBhcnJheV9zaGlmdCgkbGluZV9hcnJheSk7DQoJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIG5hbWUgZml4IGFwcGxpZWQNCgkJJHRoaXMtPmZpeE5hbWUoJGtleSk7DQoJCS8vIGlmIHdlIGhhdmUgbW9yZSB0aGFuIG9uZSB2YWx1ZQ0KCQlpZiAoJGtleSA9PSAnbGFiZWwnKQ0KCQl7DQoJCQlyZXR1cm4gJHRoaXMtPnNldFRhYmxlVmFsdWUoJGtleSwgaW1wbG9kZSgnICcsIGFycmF5X21hcChmdW5jdGlvbiAoJHZhbCkgew0KCQkJCXJldHVybiB0cmltKCR2YWwsICciJyk7DQoJCQl9LCAkbGluZV9hcnJheSkpKTsNCgkJfQ0KCQllbHNlaWYgKGNvdW50KCRsaW5lX2FycmF5KSA+IDEpDQoJCXsNCgkJCXJldHVybiAkdGhpcy0+c2V0VGFibGVWYWx1ZSgka2V5LCBhcnJheV9tYXAoZnVuY3Rpb24gKCR2YWwpIHsNCgkJCQlyZXR1cm4gdHJpbSgkdmFsLCAnIicpOw0KCQkJfSwgJGxpbmVfYXJyYXkpKTsNCgkJfQ0KCQllbHNlaWYgKGNvdW50KCRsaW5lX2FycmF5KSA9PSAxKQ0KCQl7DQoJCQlyZXR1cm4gJHRoaXMtPnNldFRhYmxlVmFsdWUoJGtleSwgdHJpbShhcnJheV9zaGlmdCgkbGluZV9hcnJheSksICciJykpOw0KCQl9DQoNCgkJcmV0dXJuICR0aGlzLT5zZXRUYWJsZVZhbHVlKCRrZXksIHRydWUpOw0KCX0NCg0KCS8qKg0KCSAqIGFkZCBhIG5ldyB0YWJsZSBpbmRleA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkbGluZSAgVGhlIGxpbmUgZnJvbSB0aGUgZmlsZQ0KCSAqDQoJICogQHJldHVybiAgYm9vbA0KCSAqDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIHNldFRhYmxlSW5kZXgoc3RyaW5nICRsaW5lKTogYm9vbA0KCXsNCgkJLy8gZ2V0IHRoZSBuYW1lDQoJCWlmICgoJHRoaXMtPnRhYmxlID0gJHRoaXMtPmdldEJldHdlZW4oJGxpbmUsICcgT04gIicsICciJywgbnVsbCkpICE9IG51bGwgJiYNCgkJCSgkdGhpcy0+ZmllbGQgPSAkdGhpcy0+Z2V0QmV0d2VlbigkbGluZSwgJ0FERCBJTkRFWCAiJywgJyIgT04nLCBudWxsKSkgIT0gbnVsbCkNCgkJew0KCQkJLy8gd2UgYXJlIGluIGluZGV4IGNvdW50cnkNCgkJCSR0aGlzLT5pbmRleCA9IHRydWU7DQoJCQkvLyBtYWtlIHN1cmUgd2UgaGF2ZSBuYW1lIGZpeCBhcHBsaWVkDQoJCQkkdGhpcy0+Zml4TmFtZXMoKTsNCg0KCQkJLy8gc2V0IGZpZWxkIHZhbHVlDQoJCQlyZXR1cm4gJHRoaXMtPnNldEZpZWxkVmFsdWUoJ2luZGV4JywgJHRoaXMtPmZpZWxkLCAnbmFtZScsICR0aGlzLT5maWVsZCk7DQoJCX0NCg0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogYWRkIGEgbmV3IHRhYmxlIGluZGV4IHByb3BlcnR5DQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRsaW5lICBUaGUgbGluZSBmcm9tIHRoZSBmaWxlDQoJICoNCgkgKiBAcmV0dXJuICBib29sDQoJICoNCgkgKi8NCglwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0VGFibGVJbmRleFByb3BlcnR5KHN0cmluZyAkbGluZSk6IGJvb2wNCgl7DQoJCS8vIGlmIGJvdGggdGFibGUgYW5kIGZpZWxkIGFyZSBzZXQsIHRoZW4gd2UgYXJlIGxvYWRpbmcgZmllbGQgdmFsdWVzDQoJCSRsaW5lX2FycmF5ID0gKGFycmF5KSBleHBsb2RlKCcgJywgdHJpbSgkbGluZSkpOw0KCQkvLyBnZXQgdGhlIG1haW4ga2V5DQoJCSRrZXkgPSBhcnJheV9zaGlmdCgkbGluZV9hcnJheSk7DQoJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIG5hbWUgZml4IGFwcGxpZWQNCgkJJHRoaXMtPmZpeE5hbWUoJGtleSk7DQoJCS8vIGlmIHRoaXMgaXMgYW4gaW5kZXggZmllbGQNCgkJaWYgKCRrZXkgPT0gJ2luZGV4X2ZpZWxkJykNCgkJew0KCQkJLy8gZ2V0IHRoZSBmaWVsZCBuYW1lDQoJCQkkZmllbGRfbmFtZSA9IHRyaW0oJGxpbmVfYXJyYXlbMF0sICciJyk7DQoJCQkvLyBmaXhlIHRoZSBmaWVsZA0KCQkJJHRoaXMtPmZpeE5hbWUoJGZpZWxkX25hbWUpOw0KCQkJLy8gc2V0IGluZGV4IGZpZWxkIHZhbHVlDQoJCQkkdGhpcy0+dG1wWydpbmRleCddWyR0aGlzLT5tb2R1bGVdWyR0aGlzLT50YWJsZV1bJHRoaXMtPmZpZWxkXVtdID0gJGZpZWxkX25hbWU7DQoNCgkJCS8vIHdlIGhhdmUgb3VyIGRhdGEsIHNvIHdlIHJldHVybiB0cnVlDQoJCQlyZXR1cm4gdHJ1ZTsNCgkJfQ0KCQllbHNlaWYgKGNvdW50KCRsaW5lX2FycmF5KSA+IDEpDQoJCXsNCgkJCS8vIHNldCBmaWVsZCB2YWx1ZQ0KCQkJcmV0dXJuICR0aGlzLT5zZXRGaWVsZFZhbHVlKCdpbmRleCcsICR0aGlzLT5maWVsZCwgJGtleSwgYXJyYXlfbWFwKGZ1bmN0aW9uICgkdmFsKSB7DQoJCQkJcmV0dXJuIHRyaW0oJHZhbCwgJyInKTsNCgkJCX0sICRsaW5lX2FycmF5KSk7DQoJCX0NCgkJZWxzZWlmIChjb3VudCgkbGluZV9hcnJheSkgPT0gMSkNCgkJew0KCQkJLy8gc2V0IGZpZWxkIHZhbHVlDQoJCQlyZXR1cm4gJHRoaXMtPnNldEZpZWxkVmFsdWUoJ2luZGV4JywgJHRoaXMtPmZpZWxkLCAka2V5LCB0cmltKGFycmF5X3NoaWZ0KCRsaW5lX2FycmF5KSwgJyInKSk7DQoJCX0NCg0KCQkvLyBzZXQgZmllbGQgdmFsdWUNCgkJcmV0dXJuICR0aGlzLT5zZXRGaWVsZFZhbHVlKCdpbmRleCcsICR0aGlzLT5maWVsZCwgJGtleSwgdHJ1ZSk7DQoJfQ0KDQoJLyoqDQoJICogZml4IGFsbCBrZXkgbmFtZXMNCgkgKg0KCSAqIEByZXR1cm4gIHZvaWQNCgkgKg0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBmaXhOYW1lcygpDQoJew0KCQkvLyBmaXggdGhlIHRhYmxlIG5hbWUNCgkJaWYgKGlzc2V0KCR0aGlzLT50YWJsZSkpDQoJCXsNCgkJCS8vIGZpeCB0YWJsZSBuYW1lcw0KCQkJJHRoaXMtPmZpeE5hbWUoJHRoaXMtPnRhYmxlKTsNCgkJfQ0KCQkvLyBmaXggdGhlIHRhYmxlIG5hbWUNCgkJaWYgKGlzc2V0KCR0aGlzLT5maWVsZCkpDQoJCXsNCgkJCS8vIGZpeCB0YWJsZSBuYW1lcw0KCQkJJHRoaXMtPmZpeE5hbWUoJHRoaXMtPmZpZWxkKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIGZpeCBhbGwga2V5IG5hbWVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRuYW1lICBUaGUgc3RyaW5nIHRvIGZpeA0KCSAqDQoJICogQHJldHVybiAgdm9pZA0KCSAqDQoJICovDQoJcHJvdGVjdGVkIGZ1bmN0aW9uIGZpeE5hbWUoc3RyaW5nICYkbmFtZSkNCgl7DQoJCS8vIGZpeCBuYW1lDQoJCSRuYW1lID0gc3RyX3JlcGxhY2UoJy0nLCAnXycsIHN0cnRvbG93ZXIoJG5hbWUpKTsNCgl9DQoNCgkvKioNCgkgKiBnZXQgdGhlIG1vZHVsZSBrZXkgd2hlcmUgdGhpcyB0YWJsZSBpcyBmb3VuZA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkdGFibGUgIFRoZSBzdHJpbmcgdG8gZml4DQoJICoNCgkgKiBAcmV0dXJuICBtaXhlZCAgVGhlIG1vZHVsZSB3aGVyZSB0aGlzIHRhYmxlIGlzIGZvdW5kDQoJICoNCgkgKi8NCglwcm90ZWN0ZWQgZnVuY3Rpb24gZ2V0TW9kTmFtZShzdHJpbmcgJHRhYmxlKQ0KCXsNCgkJLy8gd2UgZmlyc3QgdHJ5IHRvIGdldCB0aGUgbW9kIG5hbWUgZnJvbSB0aGUgdGFibGUgbmFtZQ0KCQkkdGFibGVfYXJyYXkgPSBleHBsb2RlKCdfJywgJHRhYmxlKTsNCgkJLy8gY2hlY2sgaWYgdGFibGUgZXhpc3QgaW4gdGhpcyBtb2QgZ3JvdXANCgkJaWYgKGlzc2V0KCR0aGlzLT50YWJsZXNbJHRhYmxlX2FycmF5WzBdXVskdGFibGVdKSkNCgkJew0KCQkJcmV0dXJuICR0YWJsZV9hcnJheVswXTsNCgkJfQ0KCQkvLyBub3cgd2UgZG8gdGhlIGJydXRlZm9yY2Ugd2F5DQoJCWZvcmVhY2ggKCR0aGlzLT50YWJsZXMgYXMgJG1vZCA9PiAkbW9kcykNCgkJew0KCQkJaWYgKGlzc2V0KCRtb2RzWyR0YWJsZV0pKQ0KCQkJew0KCQkJCXJldHVybiAkbW9kOw0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg==', '{}', 'ExtrudeTables', '[[[COMPANY]]]\\[[[Component]]]\\ExtrudeTables', '1.0.0', '{}', 'Lila Extrude Tables', 'class', '{\"use_selection0\":{\"use\":\"79d765b3-7319-4988-9730-446c7f347020\"}}', '', 1, '2021-11-06 14:28:17', '2021-11-13 16:34:22', 33, 2), -(3, '', '', '', '', '7e6e7fe8-725d-411e-889a-4f1618c11840', '', '', '', '', 'Ly8gaGVscA==', '{}', 'TestingInterface', '[[[Component]]]\\Power\\TestingInterface', '1.0.0', '{}', 'Testing Interface', 'interface', '{}', '', 1, '2021-11-07 15:54:41', '2021-11-09 04:37:44', 7, 3), -(4, '', 'To store tables structures from lila', '', '', 'c4469632-3914-400e-b861-972b2d463963', '', '', '', '', 'CS8qKg0KCSAqIEFkZGluZyB0aGUgdXRpbGl0aWVzIHRyYWl0IHRvIHRoaXMgY2xhc3MNCgkgKiBTaW5jZSB3ZSBuZWVkIHNvbWUgb2YgaXRzIGZ1bmN0aW9ucw0KCSAqLw0KCXVzZSBVdGlsOw0KDQoJLyoqDQoJICogVGhlIGRhdGENCgkgKg0KCSAqIEB2YXIgRXh0cnVkZQ0KCSAqLw0KCXByb3RlY3RlZCAkZGF0YTsNCg0KCS8qKg0KCSAqIENvbnN0cnVjdG9yDQoJICoNCgkgKiBAcGFyYW0gICBFeHRydWRlICAkZGF0YSAgVGhlIGV4dHJ1ZGVkIGRhdGENCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoRXh0cnVkZVRhYmxlcyAkZGF0YSkNCgl7DQoJCSR0aGlzLT5kYXRhID0gJGRhdGE7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IHRoZSBwYXJhbWV0ZXJzIG9mIGVhY2ggYXJlYSBpbiB0aGUgZGF0YSBzZXQNCgkgKg0KCSAqIEBwYXJhbSAgIG1peGVkICAkYXJlYSAgVGhlIGFyZWEgb2YgcGFyYW1zDQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCA9IGFsbA0KCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlDQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRzDQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgNCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rcw0KCSAqDQoJICogQHJldHVybiAgYXJyYXkNCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0UGFyYW1zKCRhcmVhID0gbnVsbCk6IGFycmF5DQoJew0KCQkvLyBsZXRzIGdldCBhbGwgdGhlIHRhYmxlIHBhcmFtcw0KCQkkcGFyYW1zWyd0YWJsZSddID0gYXJyYXkoKTsNCgkJLy8gbGV0cyBnZXQgYWxsIHRoZSBmaWVsZCBwYXJhbXMNCgkJJHBhcmFtc1snZmllbGRzJ10gPSBhcnJheSgpOw0KCQkvLyBsZXRzIGdldCBhbGwgdGhlIGluZGV4IHBhcmFtcw0KCQkkcGFyYW1zWydpbmRleCddID0gYXJyYXkoKTsNCgkJLy8gbGV0cyBnZXQgYWxsIHRoZSBsaW5rcyBwYXJhbXMNCgkJJHBhcmFtc1snbGlua3MnXSA9IGFycmF5KCk7DQoJCS8vIGxvb3Agb3ZlciB0aGUgZnVsbCBkYXRhc2V0DQoJCWZvcmVhY2ggKCR0aGlzLT5kYXRhLT50YWJsZXMgYXMgJG1vZCA9PiAkdGFibGVzKQ0KCQl7DQoJCQlmb3JlYWNoICgkdGFibGVzIGFzICR0YWJsZV92YWx1ZXMpDQoJCQl7DQoJCQkJZm9yZWFjaCAoJHRhYmxlX3ZhbHVlcyBhcyAkdGFibGVfcGFyYW0gPT4gJHZhbHVlcykNCgkJCQl7DQoJCQkJCS8vIGxldHMgZ2V0IGFsbCB0aGUgZmllbGQgcGFyYW1zDQoJCQkJCS8vIGxldHMgZ2V0IGFsbCB0aGUgaW5kZXggcGFyYW1zDQoJCQkJCS8vIGxldHMgZ2V0IGFsbCB0aGUgbGlua3MgcGFyYW1zDQoJCQkJCWlmICgkdGFibGVfcGFyYW0gPT09ICdmaWVsZHMnIHx8ICR0YWJsZV9wYXJhbSA9PT0gJ2luZGV4JyB8fCAkdGFibGVfcGFyYW0gPT09ICdsaW5rcycpDQoJCQkJCXsNCgkJCQkJCWZvcmVhY2ggKCR2YWx1ZXMgYXMgJGZpZWxkcykNCgkJCQkJCXsNCgkJCQkJCQlmb3JlYWNoICgkZmllbGRzIGFzICRwYXJhbSA9PiAkdmFsdWUpDQoJCQkJCQkJew0KCQkJCQkJCQkkcGFyYW1zWyR0YWJsZV9wYXJhbV1bJHBhcmFtXSA9ICRwYXJhbTsNCgkJCQkJCQl9DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQkJLy8gbGV0cyBnZXQgYWxsIHRoZSB0YWJsZSBwYXJhbXMNCgkJCQkJZWxzZQ0KCQkJCQl7DQoJCQkJCQkkcGFyYW1zWyd0YWJsZSddWyR0YWJsZV9wYXJhbV0gPSAkdGFibGVfcGFyYW07DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCX0NCgkJLy8gY2hlY2sgaWYgYW4gYXJlYSBpcyBjYWxsZWQgYW5kIGZvdW5kDQoJCWlmICgkYXJlYSAmJiBpc3NldCgkcGFyYW1zWyRhcmVhXSkpDQoJCXsNCgkJCXJldHVybiAkcGFyYW1zWyRhcmVhXTsNCgkJfQ0KCQkvLyBpZiBhcmVhIGlzIGNhbGxlZCB0aGF0IGRvZXMgbm90IGV4aXN0DQoJCWVsc2VpZiAoJGFyZWEpDQoJCXsNCgkJCXJldHVybiBhcnJheSgpOw0KCQl9DQoJCS8vIHJldHVybiBhbGwgb24gbnVsbCBhcmVhDQoJCXJldHVybiAkcGFyYW1zOw0KCX0NCg==', '{}', 'StoreTables', '[[[COMPANY]]]\\[[[Component]]]\\StoreTables', '1.0.0', '{}', 'Lila Store Tables', 'class', '{\"use_selection0\":{\"use\":\"79d765b3-7319-4988-9730-446c7f347020\"}}', '', 1, '2021-11-13 17:52:23', '2021-11-13 22:21:46', 14, 2), -(5, 1, '', '', '', 'db4a1e4d-be59-4e87-8b4d-c40512752232', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwRmFjdG9yeTsNCnVzZSBKb29tbGFcUmVnaXN0cnlcUmVnaXN0cnk7', '', '', '{\"load_selection0\":{\"load\":\"aa253bac-f4b4-41b4-8ace-071a73fc4d96\"},\"load_selection1\":{\"load\":\"c65aaf1f-817c-49a2-8202-282e3904f5b1\"},\"load_selection2\":{\"load\":\"51195163-1e87-4251-b755-a03c376798a6\"},\"load_selection3\":{\"load\":\"ef011ee1-64f0-4048-b013-777473b727dd\"},\"load_selection4\":{\"load\":\"c4a188de-ad78-4a6d-9d5b-01866846d701\"}}', 'CS8qKg0KCSAqIE9wdGlvbnMgZm9yIHRoZSBHaXRlYSBvYmplY3QuDQoJICoNCgkgKiBAdmFyICAgIGFycmF5DQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJG9wdGlvbnM7DQoNCgkvKioNCgkgKiBUaGUgSFRUUCBjbGllbnQgb2JqZWN0IHRvIHVzZSBpbiBzZW5kaW5nIEhUVFAgcmVxdWVzdHMuDQoJICoNCgkgKiBAdmFyICAgIEJhc2VIdHRwDQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJGNsaWVudDsNCg0KCS8qKg0KCSAqIENvbnN0cnVjdG9yLg0KCSAqDQoJICogQHBhcmFtICAgUmVnaXN0cnkgICRvcHRpb25zICBHaXRlYSBvcHRpb25zIG9iamVjdC4NCgkgKiBAcGFyYW0gICBIdHRwICAgICAgJGNsaWVudCAgIFRoZSBIVFRQIGNsaWVudCBvYmplY3QuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVnaXN0cnkgJG9wdGlvbnMgPSBudWxsLCBCYXNlSHR0cCAkY2xpZW50ID0gbnVsbCkNCgl7DQoJCSR0aGlzLT5vcHRpb25zID0gJG9wdGlvbnMgPzogbmV3IFJlZ2lzdHJ5Ow0KDQoJCS8vIFNldHVwIHRoZSBkZWZhdWx0IHVzZXIgYWdlbnQgaWYgbm90IGFscmVhZHkgc2V0Lg0KCQlpZiAoISR0aGlzLT5nZXRPcHRpb24oJ3VzZXJBZ2VudCcpKQ0KCQl7DQoJCQkkdGhpcy0+c2V0T3B0aW9uKCd1c2VyQWdlbnQnLCAnSkdpdGVhLzEuMCcpOw0KCQl9DQoNCgkJLy8gU2V0dXAgdGhlIGRlZmF1bHQgQVBJIHVybCBpZiBub3QgYWxyZWFkeSBzZXQuDQoJCWlmICghJHRoaXMtPmdldE9wdGlvbignYXBpLnVybCcpKQ0KCQl7DQoJCQkkdGhpcy0+c2V0T3B0aW9uKCdhcGkudXJsJywgJ1tbW2dpdGVhX2FwaV91cmxdXV0nKTsNCgkJfQ0KDQoJCSR0aGlzLT5jbGllbnQgPSAkY2xpZW50ID86IChuZXcgSHR0cEZhY3RvcnkpLT5nZXRIdHRwKCR0aGlzLT5vcHRpb25zKTsNCgl9DQoNCgkvKioNCgkgKiBNYWdpYyBtZXRob2QgdG8gbGF6aWx5IGNyZWF0ZSBBUEkgb2JqZWN0cw0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkbmFtZSAgTmFtZSBvZiBwcm9wZXJ0eSB0byByZXRyaWV2ZQ0KCSAqDQoJICogQHJldHVybiAgQWJzdHJhY3RHaXRlYU9iamVjdCAgR2l0ZWEgQVBJIG9iamVjdCAoaXNzdWVzLCBwdWxscywgZXRjKS4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqIEB0aHJvd3MgIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSWYgJG5hbWUgaXMgbm90IGEgdmFsaWQgc3ViIGNsYXNzLg0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkNCgl7DQoJCSRjbGFzcyA9ICdcXFZETVxcR2l0ZWFcXFBhY2thZ2VcXCcgLiB1Y2ZpcnN0KCRuYW1lKTsNCg0KCQlpZiAoY2xhc3NfZXhpc3RzKCRjbGFzcykpDQoJCXsNCgkJCWlmIChpc3NldCgkdGhpcy0+JG5hbWUpID09IGZhbHNlKQ0KCQkJew0KCQkJCSR0aGlzLT4kbmFtZSA9IG5ldyAkY2xhc3MoJHRoaXMtPm9wdGlvbnMsICR0aGlzLT5jbGllbnQpOw0KCQkJfQ0KDQoJCQlyZXR1cm4gJHRoaXMtPiRuYW1lOw0KCQl9DQoNCgkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQXJndW1lbnQgJXMgcHJvZHVjZWQgYW4gaW52YWxpZCBjbGFzcyBuYW1lOiAlcycsICRuYW1lLCAkY2xhc3MpKTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYW4gb3B0aW9uIGZyb20gdGhlIEdpdGVhIGluc3RhbmNlLg0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAka2V5ICBUaGUgbmFtZSBvZiB0aGUgb3B0aW9uIHRvIGdldC4NCgkgKg0KCSAqIEByZXR1cm4gIG1peGVkICBUaGUgb3B0aW9uIHZhbHVlLg0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbigka2V5KQ0KCXsNCgkJcmV0dXJuIGlzc2V0KCR0aGlzLT5vcHRpb25zWyRrZXldKSA/ICR0aGlzLT5vcHRpb25zWyRrZXldIDogbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBTZXQgYW4gb3B0aW9uIGZvciB0aGUgR2l0ZWEgaW5zdGFuY2UuDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRrZXkgICAgVGhlIG5hbWUgb2YgdGhlIG9wdGlvbiB0byBzZXQuDQoJICogQHBhcmFtICAgbWl4ZWQgICAkdmFsdWUgIFRoZSBvcHRpb24gdmFsdWUgdG8gc2V0Lg0KCSAqDQoJICogQHJldHVybiAgR2l0ZWEgIFRoaXMgb2JqZWN0IGZvciBtZXRob2QgY2hhaW5pbmcuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRrZXksICR2YWx1ZSkNCgl7DQoJCSR0aGlzLT5vcHRpb25zWyRrZXldID0gJHZhbHVlOw0KDQoJCXJldHVybiAkdGhpczsNCgl9DQo=', '{}', 'Gitea', 'VDM\\Gitea\\Gitea', '1.0.0', '{}', 'Gitea', 'class', '{}', '', 1, '2021-12-03 14:18:38', '2022-07-09 13:56:22', 27, 4), -(6, 1, '', '', '', 'aa253bac-f4b4-41b4-8ace-071a73fc4d96', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwRmFjdG9yeTsNCnVzZSBKb29tbGFcQ01TXEh0dHBcUmVzcG9uc2U7DQp1c2UgSm9vbWxhXFJlZ2lzdHJ5XFJlZ2lzdHJ5Ow0KdXNlIEpvb21sYVxVcmlcVXJpOw==', '', '', '{}', 'CS8qKg0KCSAqIE9wdGlvbnMgZm9yIHRoZSBHaXRlYSBvYmplY3QuDQoJICoNCgkgKiBAdmFyICAgIFJlZ2lzdHJ5DQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJG9wdGlvbnM7DQoNCgkvKioNCgkgKiBUaGUgSFRUUCBjbGllbnQgb2JqZWN0IHRvIHVzZSBpbiBzZW5kaW5nIEhUVFAgcmVxdWVzdHMuDQoJICoNCgkgKiBAdmFyICAgIEJhc2VIdHRwDQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJGNsaWVudDsNCg0KCS8qKg0KCSAqIFRoZSBwYWNrYWdlIHRoZSBvYmplY3QgcmVzaWRlcyBpbg0KCSAqDQoJICogQHZhciAgICBzdHJpbmcNCgkgKiBAc2luY2UgIDEuMA0KCSAqLw0KCXByb3RlY3RlZCAkcGFja2FnZSA9ICcnOw0KDQoJLyoqDQoJICogQ29uc3RydWN0b3IuDQoJICoNCgkgKiBAcGFyYW0gICBSZWdpc3RyeSAgJG9wdGlvbnMgIEdpdGVhIG9wdGlvbnMgb2JqZWN0Lg0KCSAqIEBwYXJhbSAgIEJhc2VIdHRwICAkY2xpZW50ICAgVGhlIEhUVFAgY2xpZW50IG9iamVjdC4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZWdpc3RyeSAkb3B0aW9ucyA9IG51bGwsIEJhc2VIdHRwICRjbGllbnQgPSBudWxsKQ0KCXsNCgkJJHRoaXMtPm9wdGlvbnMgPSAkb3B0aW9ucyA/OiBuZXcgUmVnaXN0cnk7DQoJCSR0aGlzLT5jbGllbnQgID0gJGNsaWVudCA/OiAobmV3IEh0dHBGYWN0b3J5KS0+Z2V0SHR0cCgkdGhpcy0+b3B0aW9ucyk7DQoNCgkJJHRoaXMtPnBhY2thZ2UgPSBcZ2V0X2NsYXNzKCR0aGlzKTsNCgkJJHRoaXMtPnBhY2thZ2UgPSBzdWJzdHIoJHRoaXMtPnBhY2thZ2UsIHN0cnJwb3MoJHRoaXMtPnBhY2thZ2UsICdcXCcpICsgMSk7DQoJfQ0KDQoJLyoqDQoJICogTWV0aG9kIHRvIGJ1aWxkIGFuZCByZXR1cm4gYSBmdWxsIHJlcXVlc3QgVVJMIGZvciB0aGUgcmVxdWVzdC4gIFRoaXMgbWV0aG9kIHdpbGwNCgkgKiBhZGQgYXBwcm9wcmlhdGUgcGFnaW5hdGlvbiBkZXRhaWxzIGlmIG5lY2Vzc2FyeSBhbmQgYWxzbyBwcmVwZW5kIHRoZSBBUEkgdXJsDQoJICogdG8gaGF2ZSBhIGNvbXBsZXRlIFVSTCBmb3IgdGhlIHJlcXVlc3QuDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkcGF0aCAgIFVSTCB0byBpbmZsZWN0DQoJICogQHBhcmFtICAgaW50ZWdlciAgJHBhZ2UgICBQYWdlIHRvIHJlcXVlc3QNCgkgKiBAcGFyYW0gICBpbnRlZ2VyICAkbGltaXQgIE51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybiBwZXIgcGFnZQ0KCSAqDQoJICogQHJldHVybiAgVXJpDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgZnVuY3Rpb24gZmV0Y2hVcmwoJHBhdGgsICRwYWdlID0gMCwgJGxpbWl0ID0gMCkNCgl7DQoJCS8vIEdldCBhIG5ldyBVcmkgb2JqZWN0IGZvY3VzaW5nIHRoZSBhcGkgdXJsIGFuZCBnaXZlbiBwYXRoLg0KCQkkdXJpID0gbmV3IFVyaSgkdGhpcy0+b3B0aW9ucy0+Z2V0KCdhcGkudXJsJykgLiAkcGF0aCk7DQoNCgkJaWYgKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FjY2Vzcy50b2tlbicsIGZhbHNlKSkNCgkJew0KCQkJLy8gVXNlIG9BdXRoIGF1dGhlbnRpY2F0aW9uDQoJCQkkaGVhZGVycyA9ICR0aGlzLT5jbGllbnQtPmdldE9wdGlvbignaGVhZGVycycsIGFycmF5KCkpOw0KDQoJCQlpZiAoIWlzc2V0KCRoZWFkZXJzWydBdXRob3JpemF0aW9uJ10pKQ0KCQkJew0KCQkJCSRoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSAndG9rZW4gJyAuICR0aGlzLT5vcHRpb25zLT5nZXQoJ2FjY2Vzcy50b2tlbicpOw0KCQkJCSR0aGlzLT5jbGllbnQtPnNldE9wdGlvbignaGVhZGVycycsICRoZWFkZXJzKTsNCgkJCX0NCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8vIFVzZSBiYXNpYyBhdXRoZW50aWNhdGlvbg0KCQkJaWYgKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS51c2VybmFtZScsIGZhbHNlKSkNCgkJCXsNCgkJCQkkdXJpLT5zZXRVc2VyKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS51c2VybmFtZScpKTsNCgkJCX0NCg0KCQkJaWYgKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS5wYXNzd29yZCcsIGZhbHNlKSkNCgkJCXsNCgkJCQkkdXJpLT5zZXRQYXNzKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS5wYXNzd29yZCcpKTsNCgkJCX0NCgkJfQ0KDQoJCS8vIElmIHdlIGhhdmUgYSBkZWZpbmVkIHBhZ2UgbnVtYmVyIGFkZCBpdCB0byB0aGUgSlVyaSBvYmplY3QuDQoJCWlmICgkcGFnZSA+IDApDQoJCXsNCgkJCSR1cmktPnNldFZhcigncGFnZScsIChpbnQpICRwYWdlKTsNCgkJfQ0KDQoJCS8vIElmIHdlIGhhdmUgYSBkZWZpbmVkIGl0ZW1zIHBlciBwYWdlIGFkZCBpdCB0byB0aGUgSlVyaSBvYmplY3QuDQoJCWlmICgkbGltaXQgPiAwKQ0KCQl7DQoJCQkkdXJpLT5zZXRWYXIoJ2xpbWl0JywgKGludCkgJGxpbWl0KTsNCgkJfQ0KDQoJCXJldHVybiAkdXJpOw0KCX0NCg0KCS8qKg0KCSAqIFByb2Nlc3MgdGhlIHJlc3BvbnNlIGFuZCBkZWNvZGUgaXQuDQoJICoNCgkgKiBAcGFyYW0gICBSZXNwb25zZSAgJHJlc3BvbnNlICAgICAgVGhlIHJlc3BvbnNlLg0KCSAqIEBwYXJhbSAgIGludGVnZXIgICAkZXhwZWN0ZWRDb2RlICBUaGUgZXhwZWN0ZWQgImdvb2QiIGNvZGUuDQoJICoNCgkgKiBAcmV0dXJuICBtaXhlZA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICogQHRocm93cyAgUnVudGltZUV4Y2VwdGlvbg0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UoUmVzcG9uc2UgJHJlc3BvbnNlLCAkZXhwZWN0ZWRDb2RlID0gMjAwKQ0KCXsNCgkJLy8gVmFsaWRhdGUgdGhlIHJlc3BvbnNlIGNvZGUuDQoJCWlmICgkcmVzcG9uc2UtPmNvZGUgIT0gJGV4cGVjdGVkQ29kZSkNCgkJew0KCQkJLy8gRGVjb2RlIHRoZSBlcnJvciByZXNwb25zZSBhbmQgdGhyb3cgYW4gZXhjZXB0aW9uLg0KCQkJJGVycm9yICAgPSBqc29uX2RlY29kZSgkcmVzcG9uc2UtPmJvZHkpOw0KCQkJJG1lc3NhZ2UgPSBpc3NldCgkZXJyb3ItPm1lc3NhZ2UpID8gJGVycm9yLT5tZXNzYWdlIDogJ0ludmFsaWQgcmVzcG9uc2UgcmVjZWl2ZWQgZnJvbSBHaXRlYS4nOw0KDQoJCQl0aHJvdyBuZXcgXERvbWFpbkV4Y2VwdGlvbigkbWVzc2FnZSwgJHJlc3BvbnNlLT5jb2RlKTsNCgkJfQ0KDQoJCWlmIChKc29uSGVscGVyOjpjaGVjaygkcmVzcG9uc2UtPmJvZHkpKQ0KCQl7DQoJCQkkYm9keSA9IGpzb25fZGVjb2RlKCRyZXNwb25zZS0+Ym9keSk7DQoNCgkJCWlmIChpc3NldCgkYm9keS0+Y29udGVudF9iYXNlNjQpKQ0KCQkJew0KCQkJCSRib2R5LT5jb250ZW50ID0gYmFzZTY0X2RlY29kZSgkYm9keS0+Y29udGVudF9iYXNlNjQpOw0KCQkJfQ0KCQl9DQoJCWVsc2UNCgkJew0KCQkJJGJvZHkgPSAkcmVzcG9uc2UtPmJvZHk7DQoJCX0NCg0KCQlyZXR1cm4gJGJvZHk7DQoJfQ0K', '{}', 'AbstractGiteaObject', 'VDM\\Gitea\\AbstractGiteaObject', '1.0.0', '{}', 'Abstract Gitea Object', 'abstract class', '{\"use_selection0\":{\"use\":\"4b225c51-d293-48e4-b3f6-5136cf5c3f18\",\"as\":\"default\"}}', '', 1, '2021-12-03 16:00:26', '2022-07-09 12:15:49', 20, 4), -(7, 1, '', 'aa253bac-f4b4-41b4-8ace-071a73fc4d96', '', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIENvbnN0cnVjdG9yLg0KCSAqDQoJICogQHBhcmFtICAgUmVnaXN0cnkgICRvcHRpb25zICBHaXRlYSBvcHRpb25zIG9iamVjdC4NCgkgKiBAcGFyYW0gICBIdHRwICAgICAgJGNsaWVudCAgIFRoZSBIVFRQIGNsaWVudCBvYmplY3QuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVnaXN0cnkgJG9wdGlvbnMgPSBudWxsLCBCYXNlSHR0cCAkY2xpZW50ID0gbnVsbCkNCgl7DQoJCXBhcmVudDo6X19jb25zdHJ1Y3QoJG9wdGlvbnMsICRjbGllbnQpOw0KDQoJCSR0aGlzLT5wYWNrYWdlID0gXGdldF9jbGFzcygkdGhpcyk7DQoJCSR0aGlzLT5wYWNrYWdlID0gc3Vic3RyKCR0aGlzLT5wYWNrYWdlLCBzdHJycG9zKCR0aGlzLT5wYWNrYWdlLCAnXFwnKSArIDEpOw0KCX0NCg0KCS8qKg0KCSAqIE1hZ2ljIG1ldGhvZCB0byBsYXppbHkgY3JlYXRlIEFQSSBvYmplY3RzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRuYW1lICBOYW1lIG9mIHByb3BlcnR5IHRvIHJldHJpZXZlDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24NCgkgKg0KCSAqIEByZXR1cm4gIEFic3RyYWN0UGFja2FnZSAgR2l0ZWEgQVBJIHBhY2thZ2Ugb2JqZWN0Lg0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkNCgl7DQoJCSRjbGFzcyA9ICdcXFZETVxcR2l0ZWFcXFBhY2thZ2VcXCcgLiAkdGhpcy0+cGFja2FnZSAuICdcXCcgLiB1Y2ZpcnN0KCRuYW1lKTsNCg0KCQlpZiAoY2xhc3NfZXhpc3RzKCRjbGFzcykgPT0gZmFsc2UpDQoJCXsNCgkJCXRocm93IG5ldyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uKA0KCQkJCXNwcmludGYoDQoJCQkJCSdBcmd1bWVudCAlMSRzIHByb2R1Y2VkIGFuIGludmFsaWQgY2xhc3MgbmFtZTogJTIkcyBpbiBwYWNrYWdlICUzJHMnLA0KCQkJCQkkbmFtZSwgJGNsYXNzLCAkdGhpcy0+cGFja2FnZQ0KCQkJCSkNCgkJCSk7DQoJCX0NCg0KCQlpZiAoaXNzZXQoJHRoaXMtPiRuYW1lKSA9PSBmYWxzZSkNCgkJew0KCQkJJHRoaXMtPiRuYW1lID0gbmV3ICRjbGFzcygkdGhpcy0+b3B0aW9ucywgJHRoaXMtPmNsaWVudCk7DQoJCX0NCg0KCQlyZXR1cm4gJHRoaXMtPiRuYW1lOw0KCX0NCg==', '{}', 'AbstractPackage', 'VDM\\Gitea\\AbstractPackage', '1.0.0', '{}', 'Abstract Gitea Package', 'abstract class', '{}', '', 1, '2021-12-03 16:03:06', '2022-05-27 08:31:35', 15, 4), -(8, 1, '', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', '', '51195163-1e87-4251-b755-a03c376798a6', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIExpc3QgeW91ciByZXBvc2l0b3JpZXMuDQoJICoNCgkgKiBMaXN0IHJlcG9zaXRvcmllcyBmb3IgdGhlIGF1dGhlbnRpY2F0ZWQgdXNlci4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RPd24oKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHVyaSA9ICR0aGlzLT5mZXRjaFVybCgnL3VzZXIvcmVwb3MnKTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgkdGhpcy0+Y2xpZW50LT5nZXQoJHVyaSkpOw0KCX0NCg0KCS8qKg0KCSAqIExpc3QgdXNlciByZXBvc2l0b3JpZXMuDQoJICoNCgkgKiBMaXN0IHB1YmxpYyByZXBvc2l0b3JpZXMgZm9yIHRoZSBzcGVjaWZpZWQgdXNlci4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHVzZXIgICAgICAgVGhlIHVzZXIgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RVc2VyKCR1c2VyKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHVyaSA9ICR0aGlzLT5mZXRjaFVybCgnL3VzZXJzLycgLiAkdXNlciAuICcvcmVwb3MnKTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgkdGhpcy0+Y2xpZW50LT5nZXQoJHVyaSkpOw0KCX0NCg0KCS8qKg0KCSAqIExpc3Qgb3JnYW5pemF0aW9uIHJlcG9zaXRvcmllcy4NCgkgKg0KCSAqIExpc3QgcmVwb3NpdG9yaWVzIGZvciB0aGUgc3BlY2lmaWVkIG9yZy4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG9yZyAgIFRoZSBuYW1lIG9mIHRoZSBvcmdhbml6YXRpb24uDQoJICoNCgkgKiBAcmV0dXJuICBvYmplY3QNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXRMaXN0T3JnKCRvcmcpDQoJew0KCQkvLyBCdWlsZCB0aGUgcmVxdWVzdCBwYXRoLg0KCQkkdXJpID0gJHRoaXMtPmZldGNoVXJsKCcvb3Jncy8nIC4gJG9yZyAuICcvcmVwb3MnKTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgkdGhpcy0+Y2xpZW50LT5nZXQoJHVyaSkpOw0KCX0NCg0KCS8qKg0KCSAqIENyZWF0ZS4NCgkgKg0KCSAqIENyZWF0ZSBhIG5ldyByZXBvc2l0b3J5IGZvciB0aGUgYXV0aGVudGljYXRlZCB1c2VyIG9yIGFuIG9yZ2FuaXphdGlvbi4gT0F1dGggdXNlcnMgbXVzdCBzdXBwbHkgcmVwbyBzY29wZS4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRuYW1lICAgICAgICAgICAgICAgVGhlIHJlcG9zaXRvcnkgbmFtZS4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3JnICAgICAgICAgICAgICAgIFRoZSBvcmdhbml6YXRpb24gbmFtZSAoaWYgbmVlZGVkKS4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkZGVzY3JpcHRpb24gICAgICAgIFRoZSByZXBvc2l0b3J5IGRlc2NyaXB0aW9uLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRyZWFkbWUgICAgICAgICAgICAgUmVhZG1lIG9mIHRoZSByZXBvc2l0b3J5IHRvIGNyZWF0ZS4NCgkgKiBAcGFyYW0gICBib29sZWFuICAkcHJpdmF0ZSAgICAgICAgICAgIFNldCB0cnVlIHRvIGNyZWF0ZSBhIHByaXZhdGUgcmVwb3NpdG9yeSwgZmFsc2UgdG8gY3JlYXRlIGEgcHVibGljIG9uZS4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkZGVmYXVsdEJyYW5jaCAgICAgIERlZmF1bHRCcmFuY2ggb2YgdGhlIHJlcG9zaXRvcnkgKHVzZWQgd2hlbiBpbml0aWFsaXplcyBhbmQgaW4gdGVtcGxhdGUpLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRsaWNlbnNlICAgICAgICAgICAgTGljZW5zZSB0byB1c2UuDQoJICogQHBhcmFtICAgYm9vbGVhbiAgJGF1dG9Jbml0ICAgICAgICAgICBXaGV0aGVyIHRoZSByZXBvc2l0b3J5IHNob3VsZCBhdXRvIGluaXQuDQoJICogQHBhcmFtICAgYm9vbGVhbiAgJHRlbXBsYXRlICAgICAgICAgICBXaGV0aGVyIHRoZSByZXBvc2l0b3J5IGlzIHRlbXBsYXRlLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRnaXRpZ25vcmVzICAgICAgICAgR2l0aWdub3JlcyB0byB1c2UuDQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IFsgSm9vbWxhLCBKZXRCcmFpbnMgXSBhbmQgbXVjaCBtb3JlLi4uDQoJICogQHBhcmFtICAgc3RyaW5nICAgJGlzc3VlTGFiZWxzICAgICAgICBMYWJlbC1TZXQgdG8gdXNlLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR0cnVzdE1vZGVsICAgICAgICAgVHJ1c3RNb2RlbCBvZiB0aGUgcmVwb3NpdG9yeS4NCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczogWyBkZWZhdWx0LCBjb2xsYWJvcmF0b3IsIGNvbW1pdHRlciwgY29sbGFib3JhdG9yY29tbWl0dGVyIF0NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSgkbmFtZSwgJG9yZyA9ICcnLCAkZGVzY3JpcHRpb24gPSAnJywgJHJlYWRtZSA9ICdEZWZhdWx0JywgJHByaXZhdGUgPSBmYWxzZSwgJGRlZmF1bHRCcmFuY2ggPSAnbWFzdGVyJywNCgkJJGxpY2Vuc2UgPSAnR1BMLTIuMC1vci1sYXRlcicsICRhdXRvSW5pdCA9IHRydWUsICR0ZW1wbGF0ZSA9IGZhbHNlLCAkdHJ1c3RNb2RlbCA9ICdkZWZhdWx0JywgJGdpdGlnbm9yZXMgPSAnJywgJGlzc3VlTGFiZWxzID0gJycNCgkpDQoJew0KCQkkcGF0aCA9ICgkb3JnKQ0KCQkJLy8gQ3JlYXRlIGEgcmVwb3NpdG9yeSBmb3IgYW4gb3JnYW5pemF0aW9uDQoJCQk/ICcvb3Jncy8nIC4gJG9yZyAuICcvcmVwb3MnDQoJCQkvLyBDcmVhdGUgYSByZXBvc2l0b3J5IGZvciBhIHVzZXINCgkJCTogJy91c2VyL3JlcG9zJzsNCg0KCQkkZGF0YSA9IFsNCgkJCSduYW1lJyAgICAgICAgICAgICAgID0+ICRuYW1lLA0KCQkJJ2Rlc2NyaXB0aW9uJyAgICAgICAgPT4gJGRlc2NyaXB0aW9uLA0KCQkJJ3JlYWRtZScgICAgICAgICAgICAgPT4gJHJlYWRtZSwNCgkJCSdwcml2YXRlJyAgICAgICAgICAgID0+ICRwcml2YXRlLA0KCQkJJ2F1dG9faW5pdCcgICAgICAgICAgPT4gJGF1dG9Jbml0LA0KCQkJJ2RlZmF1bHRfYnJhbmNoJyAgICAgPT4gJGRlZmF1bHRCcmFuY2gsDQoJCQknaXNzdWVfbGFiZWxzJyAgICAgICA9PiAkaXNzdWVMYWJlbHMsDQoJCQknbGljZW5zZScgICAgICAgICAgICA9PiAkbGljZW5zZSwNCgkJCSd0ZW1wbGF0ZScgICAgICAgICAgID0+ICR0ZW1wbGF0ZSwNCgkJCSdnaXRpZ25vcmVzJyAgICAgICAgID0+ICRnaXRpZ25vcmVzLA0KCQkJJ3RydXN0X21vZGVsJyAgICAgICAgPT4gJHRydXN0TW9kZWwNCgkJXTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPnBvc3QoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSwganNvbl9lbmNvZGUoJGRhdGEpKSwNCgkJCTIwMQ0KCQkpOw0KCX0NCg0KCS8qKg0KCSAqIEdldC4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG93bmVyICBSZXBvc2l0b3J5IG93bmVyLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHJlcG8gICBSZXBvc2l0b3J5IG5hbWUuDQoJICoNCgkgKiBAcmV0dXJuICBvYmplY3QNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXQoJG93bmVyLCAkcmVwbykNCgl7DQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSRwYXRoID0gJy9yZXBvcy8nIC4gJG93bmVyIC4gJy8nIC4gJHJlcG87DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBMaXN0IGNvbnRyaWJ1dG9ycy4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRvd25lciAgUmVwb3NpdG9yeSBvd25lci4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkcmVwbyAgIFJlcG9zaXRvcnkgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RDb250cmlidXRvcnMoJG93bmVyLCAkcmVwbykNCgl7DQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSR1cmkgPSAkdGhpcy0+ZmV0Y2hVcmwoJy9yZXBvcy8nIC4gJG93bmVyIC4gJy8nIC4gJHJlcG8gLiAnL2NvbnRyaWJ1dG9ycycpOw0KDQoJCS8vIFNlbmQgdGhlIHJlcXVlc3QuDQoJCXJldHVybiAkdGhpcy0+cHJvY2Vzc1Jlc3BvbnNlKCR0aGlzLT5jbGllbnQtPmdldCgkdXJpKSk7DQoJfQ0KDQoJLyoqDQoJICogTGlzdCBsYW5ndWFnZXMuDQoJICoNCgkgKiBMaXN0IGxhbmd1YWdlcyBmb3IgdGhlIHNwZWNpZmllZCByZXBvc2l0b3J5LiBUaGUgdmFsdWUgb24gdGhlIHJpZ2h0IG9mIGEgbGFuZ3VhZ2UgaXMgdGhlIG51bWJlciBvZiBieXRlcyBvZiBjb2RlDQoJICogd3JpdHRlbiBpbiB0aGF0IGxhbmd1YWdlLg0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkb3duZXIgIFJlcG9zaXRvcnkgb3duZXIuDQoJICogQHBhcmFtICAgc3RyaW5nICAkcmVwbyAgIFJlcG9zaXRvcnkgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RMYW5ndWFnZXMoJG93bmVyLCAkcmVwbykNCgl7DQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSRwYXRoID0gJy9yZXBvcy8nIC4gJG93bmVyIC4gJy8nIC4gJHJlcG8gLiAnL2xhbmd1YWdlcyc7DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBMaXN0IFRlYW1zDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRvd25lciAgUmVwb3NpdG9yeSBvd25lci4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICRyZXBvICAgUmVwb3NpdG9yeSBuYW1lLg0KCSAqDQoJICogQHJldHVybiAgb2JqZWN0DQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0TGlzdFRlYW1zKCRvd25lciwgJHJlcG8pDQoJew0KCQkvLyBCdWlsZCB0aGUgcmVxdWVzdCBwYXRoLg0KCQkkcGF0aCA9ICcvcmVwb3MvJyAuICRvd25lciAuICcvJyAuICRyZXBvIC4gJy90ZWFtcyc7DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBMaXN0IFRhZ3MuDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3duZXIgIFJlcG9zaXRvcnkgb3duZXIuDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHJlcG8gICBSZXBvc2l0b3J5IG5hbWUuDQoJICogQHBhcmFtICAgaW50ZWdlciAgJHBhZ2UgICBQYWdlIHRvIHJlcXVlc3QNCgkgKiBAcGFyYW0gICBpbnRlZ2VyICAkbGltaXQgIE51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybiBwZXIgcGFnZQ0KCSAqDQoJICogQHJldHVybiAgb2JqZWN0DQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0TGlzdFRhZ3MoJG93bmVyLCAkcmVwbywgJHBhZ2UgPSAwLCAkbGltaXQgPSAwKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHBhdGggPSAnL3JlcG9zLycgLiAkb3duZXIgLiAnLycgLiAkcmVwbyAuICcvdGFncyc7DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoLCAkcGFnZSwgJGxpbWl0KSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBEZWxldGUgYSBSZXBvc2l0b3J5Lg0KCSAqDQoJICogRGVsZXRpbmcgYSByZXBvc2l0b3J5IHJlcXVpcmVzIGFkbWluIGFjY2Vzcy4gSWYgT0F1dGggaXMgdXNlZCwgdGhlIGRlbGV0ZV9yZXBvIHNjb3BlIGlzIHJlcXVpcmVkLg0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkb3duZXIgIFJlcG9zaXRvcnkgb3duZXIuDQoJICogQHBhcmFtICAgc3RyaW5nICAkcmVwbyAgIFJlcG9zaXRvcnkgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSgkb3duZXIsICRyZXBvKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHBhdGggPSAnL3JlcG9zLycgLiAkb3duZXIgLiAnLycgLiAkcmVwbzsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPmRlbGV0ZSgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpKQ0KCQkpOw0KCX0NCg==', '{}', 'Repo', 'VDM\\Gitea\\Package.Repo', '1.0.0', '{}', 'Gitea Repo', 'class', '{}', '', 1, '2021-12-03 16:37:20', '2022-07-09 10:28:45', 13, 4), -(9, 1, '', '', '', '011813ba-8dd2-4beb-98f9-50ab3f3665d1', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwRmFjdG9yeTsNCnVzZSBKb29tbGFcUmVnaXN0cnlcUmVnaXN0cnk7', '', '', '{\"load_selection0\":{\"load\":\"aa253bac-f4b4-41b4-8ace-071a73fc4d96\"},\"load_selection1\":{\"load\":\"c65aaf1f-817c-49a2-8202-282e3904f5b1\"},\"load_selection2\":{\"load\":\"51195163-1e87-4251-b755-a03c376798a6\"}}', 'CS8qKg0KCSAqIE9wdGlvbnMgZm9yIHRoZSBbW1tBcGldXV0gb2JqZWN0Lg0KCSAqDQoJICogQHZhciAgICBhcnJheQ0KCSAqIEBzaW5jZSAgMS4wDQoJICovDQoJcHJvdGVjdGVkICRvcHRpb25zOw0KDQoJLyoqDQoJICogVGhlIEhUVFAgY2xpZW50IG9iamVjdCB0byB1c2UgaW4gc2VuZGluZyBIVFRQIHJlcXVlc3RzLg0KCSAqDQoJICogQHZhciAgICBCYXNlSHR0cA0KCSAqIEBzaW5jZSAgMS4wDQoJICovDQoJcHJvdGVjdGVkICRjbGllbnQ7DQoNCgkvKioNCgkgKiBDb25zdHJ1Y3Rvci4NCgkgKg0KCSAqIEBwYXJhbSAgIFJlZ2lzdHJ5ICAkb3B0aW9ucyAgW1tbQXBpXV1dIG9wdGlvbnMgb2JqZWN0Lg0KCSAqIEBwYXJhbSAgIEh0dHAgICAgICAkY2xpZW50ICAgVGhlIEhUVFAgY2xpZW50IG9iamVjdC4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZWdpc3RyeSAkb3B0aW9ucyA9IG51bGwsIEJhc2VIdHRwICRjbGllbnQgPSBudWxsKQ0KCXsNCgkJJHRoaXMtPm9wdGlvbnMgPSAkb3B0aW9ucyA/OiBuZXcgUmVnaXN0cnk7DQoNCgkJLy8gU2V0dXAgdGhlIGRlZmF1bHQgdXNlciBhZ2VudCBpZiBub3QgYWxyZWFkeSBzZXQuDQoJCWlmICghJHRoaXMtPmdldE9wdGlvbigndXNlckFnZW50JykpDQoJCXsNCgkJCSR0aGlzLT5zZXRPcHRpb24oJ3VzZXJBZ2VudCcsICdKW1tbQXBpXV1dLzEuMCcpOw0KCQl9DQoNCgkJLy8gU2V0dXAgdGhlIGRlZmF1bHQgQVBJIHVybCBpZiBub3QgYWxyZWFkeSBzZXQuDQoJCWlmICghJHRoaXMtPmdldE9wdGlvbignYXBpLnVybCcpKQ0KCQl7DQoJCQkkdGhpcy0+c2V0T3B0aW9uKCdhcGkudXJsJywgJ1tbW3Jvb3RfYXBpX3VybF1dXScpOw0KCQl9DQoNCgkJJHRoaXMtPmNsaWVudCA9ICRjbGllbnQgPzogKG5ldyBIdHRwRmFjdG9yeSktPmdldEh0dHAoJHRoaXMtPm9wdGlvbnMpOw0KCX0NCg0KCS8qKg0KCSAqIE1hZ2ljIG1ldGhvZCB0byBsYXppbHkgY3JlYXRlIEFQSSBvYmplY3RzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRuYW1lICBOYW1lIG9mIHByb3BlcnR5IHRvIHJldHJpZXZlDQoJICoNCgkgKiBAcmV0dXJuICBBYnN0cmFjdFtbW0FwaV1dXU9iamVjdCAgW1tbQXBpXV1dIEFQSSBvYmplY3QgKGlzc3VlcywgcHVsbHMsIGV0YykuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKiBAdGhyb3dzICBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIElmICRuYW1lIGlzIG5vdCBhIHZhbGlkIHN1YiBjbGFzcy4NCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19nZXQoJG5hbWUpDQoJew0KCQkkY2xhc3MgPSAnXFxbW1tDT01QQU5ZXV1dXFxbW1tBcGldXV1cXFBhY2thZ2VcXCcgLiB1Y2ZpcnN0KCRuYW1lKTsNCg0KCQlpZiAoY2xhc3NfZXhpc3RzKCRjbGFzcykpDQoJCXsNCgkJCWlmIChpc3NldCgkdGhpcy0+JG5hbWUpID09IGZhbHNlKQ0KCQkJew0KCQkJCSR0aGlzLT4kbmFtZSA9IG5ldyAkY2xhc3MoJHRoaXMtPm9wdGlvbnMsICR0aGlzLT5jbGllbnQpOw0KCQkJfQ0KDQoJCQlyZXR1cm4gJHRoaXMtPiRuYW1lOw0KCQl9DQoNCgkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQXJndW1lbnQgJXMgcHJvZHVjZWQgYW4gaW52YWxpZCBjbGFzcyBuYW1lOiAlcycsICRuYW1lLCAkY2xhc3MpKTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYW4gb3B0aW9uIGZyb20gdGhlIFtbW0FwaV1dXSBpbnN0YW5jZS4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGtleSAgVGhlIG5hbWUgb2YgdGhlIG9wdGlvbiB0byBnZXQuDQoJICoNCgkgKiBAcmV0dXJuICBtaXhlZCAgVGhlIG9wdGlvbiB2YWx1ZS4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb24oJGtleSkNCgl7DQoJCXJldHVybiBpc3NldCgkdGhpcy0+b3B0aW9uc1ska2V5XSkgPyAkdGhpcy0+b3B0aW9uc1ska2V5XSA6IG51bGw7DQoJfQ0KDQoJLyoqDQoJICogU2V0IGFuIG9wdGlvbiBmb3IgdGhlIFtbW0FwaV1dXSBpbnN0YW5jZS4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGtleSAgICBUaGUgbmFtZSBvZiB0aGUgb3B0aW9uIHRvIHNldC4NCgkgKiBAcGFyYW0gICBtaXhlZCAgICR2YWx1ZSAgVGhlIG9wdGlvbiB2YWx1ZSB0byBzZXQuDQoJICoNCgkgKiBAcmV0dXJuICBbW1tBcGldXV0gIFRoaXMgb2JqZWN0IGZvciBtZXRob2QgY2hhaW5pbmcuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRrZXksICR2YWx1ZSkNCgl7DQoJCSR0aGlzLT5vcHRpb25zWyRrZXldID0gJHZhbHVlOw0KDQoJCXJldHVybiAkdGhpczsNCgl9DQo=', '{}', '[[[Api]]]', '[[[COMPANY]]]\\[[[Api]]]\\[[[Api]]]', '1.0.0', '{}', 'API', 'class', '{}', '', 1, '2022-01-05 00:44:15', '2022-03-09 01:43:33', 5, 4), -(10, 1, 'Control the naming of a field\r\n\r\n@since 3.0.9', '', '', '9ef0eb24-aae4-4f5a-99af-d724db44808f', 'dXNlIEpvb21sYVxDTVNcQ29tcG9uZW50XENvbXBvbmVudEhlbHBlcjs=', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBmaWVsZCBidWlsZGVyIHN3aXRjaA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRidWlsZGVyID0gZmFsc2U7DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgbmFtZXMgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgc3RyaW5nIHlvdSB3b3VsZCBsaWtlIHRvIG1ha2Ugc2FmZQ0KCSAqIEBpbnB1dAlib29sZWFuICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYW4gQUxMIFVQUEVSIENBU0Ugc3RyaW5nDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgc3RyaW5nIHRvIHVzZSBpbiB3aGl0ZSBzcGFjZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlKCRzdHJpbmcsICRhbGxjYXAgPSBmYWxzZSwgJHNwYWNlciA9ICdfJykNCgl7DQoJCS8vIGdldCBnbG9iYWwgdmFsdWUNCgkJaWYgKHNlbGY6OiRidWlsZGVyID09PSBmYWxzZSkNCgkJew0KCQkJc2VsZjo6JGJ1aWxkZXIgPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJ2ZpZWxkX25hbWVfYnVpbGRlcicsIDEpOw0KCQl9DQoNCgkJLy8gdXNlIHRoZSBuZXcgY29udmVudGlvbg0KCQlpZiAoMiA9PSBzZWxmOjokYnVpbGRlcikNCgkJew0KCQkJLy8gMG5seSBjb250aW51ZSBpZiB3ZSBoYXZlIGEgc3RyaW5nDQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKSkNCgkJCXsNCgkJCQkvLyBjaGVjayB0aGF0IHRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgbm90IGEgbnVtYmVyDQoJCQkJaWYgKGlzX251bWVyaWMoc3Vic3RyKCRzdHJpbmcsIDAsIDEpKSkNCgkJCQl7DQoJCQkJCSRzdHJpbmcgPSBTdHJpbmdIZWxwZXI6Om51bWJlcnMoJHN0cmluZyk7DQoJCQkJfQ0KDQoJCQkJLy8gcmVtb3ZlIGFsbCBvdGhlciBzdHJhbmdlIGNoYXJhY3RlcnMNCgkJCQkkc3RyaW5nID0gdHJpbSgkc3RyaW5nKTsNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvJy4kc3BhY2VyLicrLycsICcgJywgJHN0cmluZyk7DQoJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAnICcsICRzdHJpbmcpOw0KDQoJCQkJLy8gVHJhbnNsaXRlcmF0ZSBzdHJpbmcNCgkJCQkkc3RyaW5nID0gU3RyaW5nSGVscGVyOjp0cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KDQoJCQkJLy8gcmVtb3ZlIGFsbCBhbmQga2VlcCBvbmx5IGNoYXJhY3RlcnMgYW5kIG51bWJlcnMNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCIvW15BLVphLXowLTkgXS8iLCAnJywgJHN0cmluZyk7DQoNCgkJCQkvLyByZXBsYWNlIHdoaXRlIHNwYWNlIHdpdGggdW5kZXJzY29yZSAoU0FGRVNUIE9QVElPTikNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvXHMrLycsICRzcGFjZXIsICRzdHJpbmcpOw0KDQoJCQkJLy8gcmV0dXJuIGFsbCBjYXBzDQoJCQkJaWYgKCRhbGxjYXApDQoJCQkJew0KCQkJCQlyZXR1cm4gc3RydG91cHBlcigkc3RyaW5nKTsNCgkJCQl9DQoNCgkJCQkvLyBkZWZhdWx0IGlzIHRvIHJldHVybiBsb3dlcg0KCQkJCXJldHVybiBzdHJ0b2xvd2VyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8gbm90IGEgc3RyaW5nDQoJCQlyZXR1cm4gJyc7DQoJCX0NCg0KCQkvLyByZXR1cm4gYWxsIGNhcHMNCgkJaWYgKCRhbGxjYXApDQoJCXsNCgkJCXJldHVybiBTdHJpbmdIZWxwZXI6OnNhZmUoJHN0cmluZywgJ1UnKTsNCgkJfQ0KDQoJCS8vIHVzZSB0aGUgZGVmYXVsdCAob3JpZ2luYWwgYmVoYXZpb3IvY29udmVudGlvbikNCgkJcmV0dXJuIFN0cmluZ0hlbHBlcjo6c2FmZSgkc3RyaW5nKTsNCgl9DQo=', '{}', 'FieldHelper', 'VDM\\Joomla\\Utilities.String.FieldHelper', '1.0.0', '{}', 'String Field Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"},\"use_selection1\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\"}}', '', 1, '2022-03-08 20:46:56', '2022-05-21 13:27:39', 20, 5), -(11, '', 'The json checker\r\n\r\n@since 3.0.9', '', '', '4b225c51-d293-48e4-b3f6-5136cf5c3f18', '', '', '', '{\"load_selection0\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"},\"load_selection1\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection2\":{\"load\":\"db87c339-5bb6-4291-a7ef-2c48ea1b06bc\"}}', 'CS8qKg0KCSAqIENoZWNrIGlmIHlvdSBoYXZlIGEganNvbiBzdHJpbmcNCgkgKg0KCSAqIEBpbnB1dCAgICBzdHJpbmcgICRzdHJpbmcgIFRoZSBqc29uIHN0cmluZyB0byBjaGVjaw0KCSAqDQoJICogQHJldHVybnMgYm9vbCB0cnVlIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVjaygkc3RyaW5nKTogYm9vbA0KCXsNCgkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJHN0cmluZykpDQoJCXsNCgkJCWpzb25fZGVjb2RlKCRzdHJpbmcpOw0KCQkJcmV0dXJuIChqc29uX2xhc3RfZXJyb3IoKSA9PT0gSlNPTl9FUlJPUl9OT05FKTsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBDb252ZXJ0IGEganNvbiBvYmplY3QgdG8gYSBzdHJpbmcNCgkgKg0KCSAqIEBpbnB1dCAgICBzdHJpbmcgICR2YWx1ZSAgVGhlIGpzb24gc3RyaW5nIHRvIGNvbnZlcnQNCgkgKg0KCSAqIEByZXR1cm5zIGEgc3RyaW5nDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3RyaW5nKCR2YWx1ZSwgJHNlcGFyYXRvciA9ICIsICIsICR0YWJsZSA9IG51bGwsICRpZCA9ICdpZCcsICRuYW1lID0gJ25hbWUnKQ0KCXsNCgkJLy8gZG8gc29tZSB0YWJsZSBmb290IHdvcmsNCgkJJGV4dGVybmFsID0gZmFsc2U7DQoJCWlmIChzdHJwb3MoJHRhYmxlLCAnI19fJykgIT09IGZhbHNlKQ0KCQl7DQoJCQkkZXh0ZXJuYWwgPSB0cnVlOw0KCQkJJHRhYmxlID0gc3RyX3JlcGxhY2UoJyNfXycsICcnLCAkdGFibGUpOw0KCQl9DQoNCgkJLy8gY2hlY2sgaWYgc3RyaW5nIGlzIEpTT04NCgkJJHJlc3VsdCA9IGpzb25fZGVjb2RlKCR2YWx1ZSwgdHJ1ZSk7DQoJCWlmIChqc29uX2xhc3RfZXJyb3IoKSA9PT0gSlNPTl9FUlJPUl9OT05FKQ0KCQl7DQoJCQkvLyBpcyBKU09ODQoJCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCRyZXN1bHQpKQ0KCQkJew0KCQkJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCR0YWJsZSkpDQoJCQkJew0KCQkJCQkkbmFtZXMgPSBhcnJheSgpOw0KCQkJCQlmb3JlYWNoICgkcmVzdWx0IGFzICR2YWwpDQoJCQkJCXsNCgkJCQkJCWlmICgkZXh0ZXJuYWwpDQoJCQkJCQl7DQoJCQkJCQkJaWYgKCRfbmFtZSA9IEdldEhlbHBlcjo6dmFyKG51bGwsICR2YWwsICRpZCwgJG5hbWUsICc9JywgJHRhYmxlKSkNCgkJCQkJCQl7DQoJCQkJCQkJCSRuYW1lc1tdID0gJF9uYW1lOw0KCQkJCQkJCX0NCgkJCQkJCX0NCgkJCQkJCWVsc2UNCgkJCQkJCXsNCgkJCQkJCQlpZiAoJF9uYW1lID0gR2V0SGVscGVyOjp2YXIoJHRhYmxlLCAkdmFsLCAkaWQsICRuYW1lKSkNCgkJCQkJCQl7DQoJCQkJCQkJCSRuYW1lc1tdID0gJF9uYW1lOw0KCQkJCQkJCX0NCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCRuYW1lcykpDQoJCQkJCXsNCgkJCQkJCXJldHVybiAoc3RyaW5nKSBpbXBsb2RlKCRzZXBhcmF0b3IsICRuYW1lcyk7DQoJCQkJCX0JDQoJCQkJfQ0KCQkJCXJldHVybiAoc3RyaW5nKSBpbXBsb2RlKCRzZXBhcmF0b3IsICRyZXN1bHQpOw0KCQkJfQ0KCQkJcmV0dXJuIChzdHJpbmcpIGpzb25fZGVjb2RlKCR2YWx1ZSk7DQoJCX0NCgkJcmV0dXJuICR2YWx1ZTsNCgl9DQo=', '{}', 'JsonHelper', 'VDM\\Joomla\\Utilities.JsonHelper', '1.0.0', '{}', 'Utilities Json Helper', 'abstract class', '{}', '', 1, '2022-03-08 21:03:54', '2022-05-21 13:27:39', 18, 6), -(12, 1, 'Some string tricks\r\n\r\n@since 3.0.9', '', '', '1f28cb53-60d9-4db1-b517-3c7dc6b429ef', 'dXNlIEpvb21sYVxDTVNcRmlsdGVyXElucHV0RmlsdGVyOw0KdXNlIEpvb21sYVxDTVNcTGFuZ3VhZ2VcTGFuZ3VhZ2U7', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"}}', 'CS8qKg0KCSAqIFRoZSBNYWluIEFjdGl2ZSBMYW5ndWFnZQ0KCSAqIA0KCSAqIEB2YXIgICAgICBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyAkbGFuZ1RhZzsNCg0KCS8qKg0KCSAqIENoZWNrIGlmIHdlIGhhdmUgYSBzdHJpbmcgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyBUaGUgc3RyaW5nIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrKCRzdHJpbmcpOiBib29sDQoJew0KCQlpZiAoaXNfc3RyaW5nKCRzdHJpbmcpICYmIHN0cmxlbigkc3RyaW5nKSA+IDApDQoJCXsNCgkJCXJldHVybiB0cnVlOw0KCQl9DQoNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIFNob3J0ZW4gYSBzdHJpbmcNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICBUaGUgeW91IHdvdWxkIGxpa2UgdG8gc2hvcnRlbg0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzaG9ydGVuKCRzdHJpbmcsICRsZW5ndGggPSA0MCwgJGFkZFRpcCA9IHRydWUpDQoJew0KCQlpZiAoc2VsZjo6Y2hlY2soJHN0cmluZykpDQoJCXsNCgkJCSRpbml0aWFsID0gc3RybGVuKCRzdHJpbmcpOw0KCQkJJHdvcmRzID0gcHJlZ19zcGxpdCgnLyhbXHNcblxyXSspLycsICRzdHJpbmcsIG51bGwsIFBSRUdfU1BMSVRfREVMSU1fQ0FQVFVSRSk7DQoJCQkkd29yZHNfY291bnQgPSBjb3VudCgoYXJyYXkpJHdvcmRzKTsNCg0KCQkJJHdvcmRfbGVuZ3RoID0gMDsNCgkJCSRsYXN0X3dvcmQgPSAwOw0KCQkJZm9yICg7ICRsYXN0X3dvcmQgPCAkd29yZHNfY291bnQ7ICsrJGxhc3Rfd29yZCkNCgkJCXsNCgkJCQkkd29yZF9sZW5ndGggKz0gc3RybGVuKCR3b3Jkc1skbGFzdF93b3JkXSk7DQoJCQkJaWYgKCR3b3JkX2xlbmd0aCA+ICRsZW5ndGgpDQoJCQkJew0KCQkJCQlicmVhazsNCgkJCQl9DQoJCQl9DQoNCgkJCSRuZXdTdHJpbmcJPSBpbXBsb2RlKGFycmF5X3NsaWNlKCR3b3JkcywgMCwgJGxhc3Rfd29yZCkpOw0KCQkJJGZpbmFsCT0gc3RybGVuKCRuZXdTdHJpbmcpOw0KCQkJaWYgKCRpbml0aWFsICE9ICRmaW5hbCAmJiAkYWRkVGlwKQ0KCQkJew0KCQkJCSR0aXRsZSA9IHNlbGY6OnNob3J0ZW4oJHN0cmluZywgNDAwICwgZmFsc2UpOw0KCQkJCXJldHVybiAnPHNwYW4gY2xhc3M9Imhhc1RpcCIgdGl0bGU9IicgLiAkdGl0bGUgLiAnIiBzdHlsZT0iY3Vyc29yOmhlbHAiPicgLiB0cmltKCRuZXdTdHJpbmcpIC4gJy4uLjwvc3Bhbj4nOw0KCQkJfQ0KCQkJZWxzZWlmICgkaW5pdGlhbCAhPSAkZmluYWwgJiYgISRhZGRUaXApDQoJCQl7DQoJCQkJcmV0dXJuIHRyaW0oJG5ld1N0cmluZykgLiAnLi4uJzsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gJHN0cmluZzsNCgl9DQoNCgkvKioNCgkgKiBNYWtpbmcgc3RyaW5ncyBzYWZlICh2YXJpb3VzIHdheXMpDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgVGhlIHlvdSB3b3VsZCBsaWtlIHRvIG1ha2Ugc2FmZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlKCRzdHJpbmcsICR0eXBlID0gJ0wnLCAkc3BhY2VyID0gJ18nLCAkcmVwbGFjZU51bWJlcnMgPSB0cnVlLCAka2VlcE9ubHlDaGFyYWN0ZXJzID0gdHJ1ZSkNCgl7DQoJCWlmICgkcmVwbGFjZU51bWJlcnMgPT09IHRydWUpDQoJCXsNCgkJCS8vIHJlbW92ZSBhbGwgbnVtYmVycyBhbmQgcmVwbGFjZSB3aXRoIEVuZ2xpc2ggdGV4dCB2ZXJzaW9uICh3b3JrcyB3ZWxsIG9ubHkgdXAgdG8gbWlsbGlvbnMpDQoJCQkkc3RyaW5nID0gc2VsZjo6bnVtYmVycygkc3RyaW5nKTsNCgkJfQ0KCQkvLyAwbmx5IGNvbnRpbnVlIGlmIHdlIGhhdmUgYSBzdHJpbmcNCgkJaWYgKHNlbGY6OmNoZWNrKCRzdHJpbmcpKQ0KCQl7DQoJCQkvLyBjcmVhdGUgZmlsZSBuYW1lIHdpdGhvdXQgdGhlIGV4dGVuc2lvbiB0aGF0IGlzIHNhZmUNCgkJCWlmICgkdHlwZSA9PT0gJ2ZpbGVuYW1lJykNCgkJCXsNCgkJCQkvLyBtYWtlIHN1cmUgVkRNIGlzIG5vdCBpbiB0aGUgc3RyaW5nDQoJCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCdWRE0nLCAndkRtJywgJHN0cmluZyk7DQoJCQkJLy8gUmVtb3ZlIGFueXRoaW5nIHdoaWNoIGlzbid0IGEgd29yZCwgd2hpdGVzcGFjZSwgbnVtYmVyDQoJCQkJLy8gb3IgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2FyYWN0ZXJzIC1fKCkNCgkJCQkvLyBJZiB5b3UgZG9uJ3QgbmVlZCB0byBoYW5kbGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzDQoJCQkJLy8geW91IGNhbiB1c2UgcHJlZ19yZXBsYWNlIHJhdGhlciB0aGFuIG1iX2VyZWdfcmVwbGFjZQ0KCQkJCS8vIFRoYW5rcyBAxYF1a2FzeiBSeXNpYWshDQoJCQkJLy8gJHN0cmluZyA9IG1iX2VyZWdfcmVwbGFjZSgiKFteXHdcc1xkXC1fXChcKV0pIiwgJycsICRzdHJpbmcpOw0KCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoIihbXlx3XHNcZFwtX1woXCldKSIsICcnLCAkc3RyaW5nKTsNCg0KCQkJCS8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIwMjE3MjkvMTQyOTY3Nw0KCQkJCXJldHVybiBwcmVnX3JlcGxhY2UoJy9ccysvJywgJyAnLCAkc3RyaW5nKTsNCgkJCX0NCgkJCS8vIHJlbW92ZSBhbGwgb3RoZXIgY2hhcmFjdGVycw0KCQkJJHN0cmluZyA9IHRyaW0oJHN0cmluZyk7DQoJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvJy4kc3BhY2VyLicrLycsICcgJywgJHN0cmluZyk7DQoJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvXHMrLycsICcgJywgJHN0cmluZyk7DQoJCQkvLyBUcmFuc2xpdGVyYXRlIHN0cmluZw0KCQkJJHN0cmluZyA9IHNlbGY6OnRyYW5zbGl0ZXJhdGUoJHN0cmluZyk7DQoJCQkvLyByZW1vdmUgYWxsIGFuZCBrZWVwIG9ubHkgY2hhcmFjdGVycw0KCQkJaWYgKCRrZWVwT25seUNoYXJhY3RlcnMpDQoJCQl7DQoJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgiL1teQS1aYS16IF0vIiwgJycsICRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8ga2VlcCBib3RoIG51bWJlcnMgYW5kIGNoYXJhY3RlcnMNCgkJCWVsc2UNCgkJCXsNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCIvW15BLVphLXowLTkgXS8iLCAnJywgJHN0cmluZyk7DQoJCQl9DQoJCQkvLyBzZWxlY3QgZmluYWwgYWRhcHRhdGlvbnMNCgkJCWlmICgkdHlwZSA9PT0gJ0wnIHx8ICR0eXBlID09PSAnc3RydG9sb3dlcicpDQoJCQl7DQoJCQkJLy8gcmVwbGFjZSB3aGl0ZSBzcGFjZSB3aXRoIHVuZGVyc2NvcmUNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvXHMrLycsICRzcGFjZXIsICRzdHJpbmcpOw0KCQkJCS8vIGRlZmF1bHQgaXMgdG8gcmV0dXJuIGxvd2VyDQoJCQkJcmV0dXJuIHN0cnRvbG93ZXIoJHN0cmluZyk7DQoJCQl9DQoJCQllbHNlaWYgKCR0eXBlID09PSAnVycpDQoJCQl7DQoJCQkJLy8gcmV0dXJuIGEgc3RyaW5nIHdpdGggYWxsIGZpcnN0IGxldHRlciBvZiBlYWNoIHdvcmQgdXBwZXJjYXNlKG5vIHVuZGVyc2NvcmUpDQoJCQkJcmV0dXJuIHVjd29yZHMoc3RydG9sb3dlcigkc3RyaW5nKSk7DQoJCQl9DQoJCQllbHNlaWYgKCR0eXBlID09PSAndycgfHwgJHR5cGUgPT09ICd3b3JkJykNCgkJCXsNCgkJCQkvLyByZXR1cm4gYSBzdHJpbmcgd2l0aCBhbGwgbG93ZXJjYXNlKG5vIHVuZGVyc2NvcmUpDQoJCQkJcmV0dXJuIHN0cnRvbG93ZXIoJHN0cmluZyk7DQoJCQl9DQoJCQllbHNlaWYgKCR0eXBlID09PSAnV3cnIHx8ICR0eXBlID09PSAnV29yZCcpDQoJCQl7DQoJCQkJLy8gcmV0dXJuIGEgc3RyaW5nIHdpdGggZmlyc3QgbGV0dGVyIG9mIHRoZSBmaXJzdCB3b3JkIHVwcGVyY2FzZSBhbmQgYWxsIHRoZSByZXN0IGxvd2VyY2FzZShubyB1bmRlcnNjb3JlKQ0KCQkJCXJldHVybiB1Y2ZpcnN0KHN0cnRvbG93ZXIoJHN0cmluZykpOw0KCQkJfQ0KCQkJZWxzZWlmICgkdHlwZSA9PT0gJ1dXJyB8fCAkdHlwZSA9PT0gJ1dPUkQnKQ0KCQkJew0KCQkJCS8vIHJldHVybiBhIHN0cmluZyB3aXRoIGFsbCB0aGUgdXBwZXJjYXNlKG5vIHVuZGVyc2NvcmUpDQoJCQkJcmV0dXJuIHN0cnRvdXBwZXIoJHN0cmluZyk7DQoJCQl9DQoJCQllbHNlaWYgKCR0eXBlID09PSAnVScgfHwgJHR5cGUgPT09ICdzdHJ0b3VwcGVyJykNCgkJCXsNCgkJCQkJLy8gcmVwbGFjZSB3aGl0ZSBzcGFjZSB3aXRoIHVuZGVyc2NvcmUNCgkJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAkc3BhY2VyLCAkc3RyaW5nKTsNCgkJCQkJLy8gcmV0dXJuIGFsbCB1cHBlcg0KCQkJCQlyZXR1cm4gc3RydG91cHBlcigkc3RyaW5nKTsNCgkJCX0NCgkJCWVsc2VpZiAoJHR5cGUgPT09ICdGJyB8fCAkdHlwZSA9PT0gJ3VjZmlyc3QnKQ0KCQkJew0KCQkJCQkvLyByZXBsYWNlIHdoaXRlIHNwYWNlIHdpdGggdW5kZXJzY29yZQ0KCQkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvXHMrLycsICRzcGFjZXIsICRzdHJpbmcpOw0KCQkJCQkvLyByZXR1cm4gd2l0aCBmaXJzdCBjaGFyYWN0ZXIgdG8gdXBwZXINCgkJCQkJcmV0dXJuIHVjZmlyc3Qoc3RydG9sb3dlcigkc3RyaW5nKSk7DQoJCQl9DQoJCQllbHNlaWYgKCR0eXBlID09PSAnY0EnIHx8ICR0eXBlID09PSAnY0FtZWwnIHx8ICR0eXBlID09PSAnY2FtZWxjYXNlJykNCgkJCXsNCgkJCQkvLyBjb252ZXJ0IGFsbCB3b3JkcyB0byBmaXJzdCBsZXR0ZXIgdXBwZXJjYXNlDQoJCQkJJHN0cmluZyA9IHVjd29yZHMoc3RydG9sb3dlcigkc3RyaW5nKSk7DQoJCQkJLy8gcmVtb3ZlIHdoaXRlIHNwYWNlDQoJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAnJywgJHN0cmluZyk7DQoJCQkJLy8gbm93IHJldHVybiBmaXJzdCBsZXR0ZXIgbG93ZXJjYXNlDQoJCQkJcmV0dXJuIGxjZmlyc3QoJHN0cmluZyk7DQoJCQl9DQoJCQkvLyByZXR1cm4gc3RyaW5nDQoJCQlyZXR1cm4gJHN0cmluZzsNCgkJfQ0KCQkvLyBub3QgYSBzdHJpbmcNCgkJcmV0dXJuICcnOw0KCX0NCg0KCS8qKg0KCSAqIENvbnZlcnQgbm9uZSBFbmdsaXNoIHN0cmluZ3MgdG8gY29kZSB1c2FibGUgc3RyaW5nDQoJICoNCgkgKiBAaW5wdXQJYW4gc3RyaW5nDQoJICoNCgkgKiBAcmV0dXJucyBhIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRyYW5zbGl0ZXJhdGUoJHN0cmluZykNCgl7DQoJCS8vIHNldCB0YWcgb25seSBvbmNlDQoJCWlmICghc2VsZjo6Y2hlY2soc2VsZjo6JGxhbmdUYWcpKQ0KCQl7DQoJCQkvLyBnZXQgZ2xvYmFsIHZhbHVlDQoJCQlzZWxmOjokbGFuZ1RhZyA9IEhlbHBlcjo6Z2V0UGFyYW1zKCktPmdldCgnbGFuZ3VhZ2UnLCAnZW4tR0InKTsNCgkJfQ0KDQoJCS8vIFRyYW5zbGl0ZXJhdGUgb24gdGhlIGxhbmd1YWdlIHJlcXVlc3RlZA0KCQkkbGFuZyA9IExhbmd1YWdlOjpnZXRJbnN0YW5jZShzZWxmOjokbGFuZ1RhZyk7DQoNCgkJcmV0dXJuICRsYW5nLT50cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIG1ha2Ugc3VyZSBhIHN0cmluZyBpcyBIVE1MIHNhdmUNCgkgKg0KCSAqIEBpbnB1dAlhbiBodG1sIHN0cmluZw0KCSAqDQoJICogQHJldHVybnMgYSBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBodG1sKCR2YXIsICRjaGFyc2V0ID0gJ1VURi04JywgJHNob3J0ZW4gPSBmYWxzZSwgJGxlbmd0aCA9IDQwKQ0KCXsNCgkJaWYgKHNlbGY6OmNoZWNrKCR2YXIpKQ0KCQl7DQoJCQkkZmlsdGVyID0gbmV3IElucHV0RmlsdGVyKCk7DQoJCQkkc3RyaW5nID0gJGZpbHRlci0+Y2xlYW4oDQoJCQkJaHRtbF9lbnRpdHlfZGVjb2RlKA0KCQkJCQlodG1sZW50aXRpZXMoDQoJCQkJCQkkdmFyLA0KCQkJCQkJRU5UX0NPTVBBVCwNCgkJCQkJCSRjaGFyc2V0DQoJCQkJCSkNCgkJCQkpLA0KCQkJCSdIVE1MJw0KCQkJKTsNCgkJCWlmICgkc2hvcnRlbikNCgkJCXsNCgkJCQlyZXR1cm4gc2VsZjo6c2hvcnRlbigkc3RyaW5nLCAkbGVuZ3RoKTsNCgkJCX0NCgkJCXJldHVybiAkc3RyaW5nOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJcmV0dXJuICcnOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogQ29udmVydCBhbGwgaW50IGluIGEgc3RyaW5nIHRvIGFuIEVuZ2xpc2ggd29yZCBzdHJpbmcNCgkgKg0KCSAqIEBpbnB1dAlhbiBzdHJpbmcgd2l0aCBudW1iZXJzDQoJICoNCgkgKiBAcmV0dXJucyBhIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG51bWJlcnMoJHN0cmluZykNCgl7DQoJCS8vIHNldCBudW1iZXJzIGFycmF5DQoJCSRudW1iZXJzID0gYXJyYXkoKTsNCg0KCQkvLyBmaXJzdCBnZXQgYWxsIG51bWJlcnMNCgkJcHJlZ19tYXRjaF9hbGwoJyFcZCshJywgJHN0cmluZywgJG51bWJlcnMpOw0KDQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYW55IG51bWJlcnMNCgkJaWYgKGlzc2V0KCRudW1iZXJzWzBdKSAmJiBBcnJheUhlbHBlcjo6Y2hlY2soJG51bWJlcnNbMF0pKQ0KCQl7DQoJCQlmb3JlYWNoICgkbnVtYmVyc1swXSBhcyAkbnVtYmVyKQ0KCQkJew0KCQkJCSRzZWFyY2hSZXBsYWNlWyRudW1iZXJdID0gc2VsZjo6bnVtYmVyKChpbnQpJG51bWJlcik7DQoJCQl9DQoNCgkJCS8vIG5vdyByZXBsYWNlIG51bWJlcnMgaW4gc3RyaW5nDQoJCQkkc3RyaW5nID0gc3RyX3JlcGxhY2UoYXJyYXlfa2V5cygkc2VhcmNoUmVwbGFjZSksIGFycmF5X3ZhbHVlcygkc2VhcmNoUmVwbGFjZSksICRzdHJpbmcpOw0KDQoJCQkvLyBjaGVjayBpZiB3ZSBtaXNzZWQgYW55LCBzdHJhbmdlIGlmIHdlIGRpZC4NCgkJCXJldHVybiBzZWxmOjpudW1iZXJzKCRzdHJpbmcpOw0KCQl9DQoNCgkJLy8gcmV0dXJuIHRoZSBzdHJpbmcgd2l0aCBubyBudW1iZXJzIHJlbWFpbmluZy4NCgkJcmV0dXJuICRzdHJpbmc7DQoJfQ0KDQoJLyoqDQoJICogQ29udmVydCBhbiBpbnRlZ2VyIGludG8gYW4gRW5nbGlzaCB3b3JkIHN0cmluZw0KCSAqIFRoYW5rcyB0byBUb20gTmljaG9sc29uIDxodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RydmFsLnBocCM0MTk4OD4NCgkgKg0KCSAqIEBpbnB1dAlhbiBpbnQNCgkgKiBAcmV0dXJucyBhIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG51bWJlcigkeCkNCgl7DQoJCSRud29yZHMgPSBhcnJheSggInplcm8iLCAib25lIiwgInR3byIsICJ0aHJlZSIsICJmb3VyIiwgImZpdmUiLCAic2l4IiwgInNldmVuIiwNCgkJCSJlaWdodCIsICJuaW5lIiwgInRlbiIsICJlbGV2ZW4iLCAidHdlbHZlIiwgInRoaXJ0ZWVuIiwNCgkJCSJmb3VydGVlbiIsICJmaWZ0ZWVuIiwgInNpeHRlZW4iLCAic2V2ZW50ZWVuIiwgImVpZ2h0ZWVuIiwNCgkJCSJuaW5ldGVlbiIsICJ0d2VudHkiLCAzMCA9PiAidGhpcnR5IiwgNDAgPT4gImZvcnR5IiwNCgkJCTUwID0+ICJmaWZ0eSIsIDYwID0+ICJzaXh0eSIsIDcwID0+ICJzZXZlbnR5IiwgODAgPT4gImVpZ2h0eSIsDQoJCQk5MCA9PiAibmluZXR5IiApOw0KDQoJCWlmKCFpc19udW1lcmljKCR4KSkNCgkJew0KCQkJJHcgPSAkeDsNCgkJfQ0KCQllbHNlaWYoZm1vZCgkeCwgMSkgIT0gMCkNCgkJew0KCQkJJHcgPSAkeDsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCWlmKCR4IDwgMCkNCgkJCXsNCgkJCQkkdyA9ICdtaW51cyAnOw0KCQkJCSR4ID0gLSR4Ow0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCSR3ID0gJyc7DQoJCQkJLy8gLi4uIG5vdyAkeCBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLg0KCQkJfQ0KDQoJCQlpZigkeCA8IDIxKSAgIC8vIDAgdG8gMjANCgkJCXsNCgkJCQkkdyAuPSAkbndvcmRzWyR4XTsNCgkJCX0NCgkJCWVsc2VpZigkeCA8IDEwMCkgIC8vIDIxIHRvIDk5DQoJCQl7IA0KCQkJCSR3IC49ICRud29yZHNbMTAgKiBmbG9vcigkeC8xMCldOw0KCQkJCSRyID0gZm1vZCgkeCwgMTApOw0KCQkJCWlmKCRyID4gMCkNCgkJCQl7DQoJCQkJCSR3IC49ICcgJyAuICRud29yZHNbJHJdOw0KCQkJCX0NCgkJCX0NCgkJCWVsc2VpZigkeCA8IDEwMDApICAvLyAxMDAgdG8gOTk5DQoJCQl7DQoJCQkJJHcgLj0gJG53b3Jkc1tmbG9vcigkeC8xMDApXSAuJyBodW5kcmVkJzsNCgkJCQkkciA9IGZtb2QoJHgsIDEwMCk7DQoJCQkJaWYoJHIgPiAwKQ0KCQkJCXsNCgkJCQkJJHcgLj0gJyBhbmQgJy4gc2VsZjo6bnVtYmVyKCRyKTsNCgkJCQl9DQoJCQl9DQoJCQllbHNlaWYoJHggPCAxMDAwMDAwKSAgLy8gMTAwMCB0byA5OTk5OTkNCgkJCXsNCgkJCQkkdyAuPSBzZWxmOjpudW1iZXIoZmxvb3IoJHgvMTAwMCkpIC4nIHRob3VzYW5kJzsNCgkJCQkkciA9IGZtb2QoJHgsIDEwMDApOw0KCQkJCWlmKCRyID4gMCkNCgkJCQl7DQoJCQkJCSR3IC49ICcgJzsNCgkJCQkJaWYoJHIgPCAxMDApDQoJCQkJCXsNCgkJCQkJCSR3IC49ICdhbmQgJzsNCgkJCQkJfQ0KCQkJCQkkdyAuPSBzZWxmOjpudW1iZXIoJHIpOw0KCQkJCX0NCgkJCX0gDQoJCQllbHNlIC8vICBtaWxsaW9ucw0KCQkJeyAgICANCgkJCQkkdyAuPSBzZWxmOjpudW1iZXIoZmxvb3IoJHgvMTAwMDAwMCkpIC4nIG1pbGxpb24nOw0KCQkJCSRyID0gZm1vZCgkeCwgMTAwMDAwMCk7DQoJCQkJaWYoJHIgPiAwKQ0KCQkJCXsNCgkJCQkJJHcgLj0gJyAnOw0KCQkJCQlpZigkciA8IDEwMCkNCgkJCQkJew0KCQkJCQkJJHcgLj0gJ2FuZCAnOw0KCQkJCQl9DQoJCQkJCSR3IC49IHNlbGY6Om51bWJlcigkcik7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCXJldHVybiAkdzsNCgl9DQoNCgkvKioNCgkgKiBSYW5kb20gS2V5DQoJICoNCgkgKiBAcmV0dXJucyBhIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHJhbmRvbSgkc2l6ZSkNCgl7DQoJCSRiYWcgPSAiYWJjZWZnaGlqa25vcHFyc3R1d3h5ekFCQ0RERUZHSElKS0xMTU1OT1BRUlNUVVZWV1hZWmFiY2RkZWZnaGlqa2xsbW1ub3BxcnN0dXZ2d3h5ekFCQ0VGR0hJSktOT1BRUlNUVVdYWVoiOw0KCQkka2V5ID0gYXJyYXkoKTsNCgkJJGJhZ3NpemUgPSBzdHJsZW4oJGJhZykgLSAxOw0KDQoJCWZvciAoJGkgPSAwOyAkaSA8ICRzaXplOyAkaSsrKQ0KCQl7DQoJCQkkZ2V0ID0gcmFuZCgwLCAkYmFnc2l6ZSk7DQoJCQkka2V5W10gPSAkYmFnWyRnZXRdOw0KCQl9DQoNCgkJcmV0dXJuIGltcGxvZGUoJGtleSk7DQoJfQ0K', '{}', 'StringHelper', 'VDM\\Joomla\\Utilities.StringHelper', '1.0.0', '{}', 'Utilities String Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-08 21:35:37', '2022-05-27 08:31:35', 25, 7), -(13, '', 'Some array tricks helper\r\n\r\n@since 3.0.9', '', '', '0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a', '', '', '', '{}', 'CS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYW4gYXJyYXkgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0CWFycmF5ICAgVGhlIGFycmF5IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sL2ludCAgbnVtYmVyIG9mIGl0ZW1zIGluIGFycmF5IG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVjaygkYXJyYXksICRyZW1vdmVFbXB0eVN0cmluZyA9IGZhbHNlKQ0KCXsNCgkJaWYgKGlzX2FycmF5KCRhcnJheSkgJiYgKCRuciA9IGNvdW50KChhcnJheSkkYXJyYXkpKSA+IDApDQoJCXsNCgkJCS8vIGFsc28gbWFrZSBzdXJlIHRoZSBlbXB0eSBzdHJpbmdzIGFyZSByZW1vdmVkDQoJCQlpZiAoJHJlbW92ZUVtcHR5U3RyaW5nKQ0KCQkJew0KCQkJCWZvcmVhY2ggKCRhcnJheSBhcyAka2V5ID0+ICRzdHJpbmcpDQoJCQkJew0KCQkJCQlpZiAoZW1wdHkoJHN0cmluZykpDQoJCQkJCXsNCgkJCQkJCXVuc2V0KCRhcnJheVska2V5XSk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJcmV0dXJuIHNlbGY6OmNoZWNrKCRhcnJheSwgZmFsc2UpOw0KCQkJfQ0KCQkJcmV0dXJuICRucjsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogTWVyZ2UgYW4gYXJyYXkgb2YgYXJyYXkncw0KCSAqDQoJICogQGlucHV0CWFycmF5ICAgVGhlIGFycmF5cyB5b3Ugd291bGQgbGlrZSB0byBtZXJnZQ0KCSAqDQoJICogQHJldHVybnMgYXJyYXkgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlKCRhcnJheXMpDQoJew0KCQlpZihzZWxmOjpjaGVjaygkYXJyYXlzKSkNCgkJew0KCQkJJGFycmF5QnVrZXQgPSBhcnJheSgpOw0KCQkJZm9yZWFjaCAoJGFycmF5cyBhcyAkYXJyYXkpDQoJCQl7DQoJCQkJaWYgKHNlbGY6OmNoZWNrKCRhcnJheSkpDQoJCQkJew0KCQkJCQkkYXJyYXlCdWtldCA9IGFycmF5X21lcmdlKCRhcnJheUJ1a2V0LCAkYXJyYXkpOw0KCQkJCX0NCgkJCX0NCgkJCXJldHVybiAkYXJyYXlCdWtldDsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgYXJyYXlzIGludGVyc2VjdA0KCSAqDQoJICogQGlucHV0CWFycmF5ICAgVGhlIGZpcnN0IGFycmF5DQoJICogQGlucHV0CWFycmF5ICAgVGhlIHNlY29uZCBhcnJheQ0KCSAqDQoJICogQHJldHVybnMgYm9vbCAgdHJ1ZSBpZiBpbnRlcnNlY3QgZWxzZSBmYWxzZQ0KCSAqIA0KCSAqIEBzaW5jZSAgMy4xLjENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGludGVyc2VjdCgkYV9hcnJheSwgJGJfYXJyYXkpDQoJew0KCQkvLyBmbGlwIHRoZSBzZWNvbmQgYXJyYXkNCgkJJGJfYXJyYXkgPSBhcnJheV9mbGlwKCRiX2FycmF5KTsNCg0KCQkvLyBsb29wIHRoZSBmaXJzdCBhcnJheQ0KCQlmb3JlYWNoICgkYV9hcnJheSBhcyAkdikNCgkJew0KCQkJaWYgKGlzc2V0KCRiX2FycmF5WyR2XSkpDQoJCQl7DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg==', '{}', 'ArrayHelper', 'VDM\\Joomla\\Utilities.ArrayHelper', '1.0.0', '{}', 'Utilities Array Helper', 'abstract class', '{}', '', 1, '2022-03-08 22:53:52', '2022-06-13 10:25:15', 14, 8), -(14, '', 'Control the naming of a namespace helper\r\n\r\n@since 3.0.9', '', '', 'ce8cf834-6bac-44fb-941c-861f7e046cc0', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBuYW1lc3BhY2Ugc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJHN0cmluZykNCgl7DQoJCS8vIDBubHkgY29udGludWUgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKSkNCgkJew0KCQkJLy8gbWFrZSBzdXJlIGl0IGhhcyBub3QgbnVtYmVycw0KCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6bnVtYmVycygkc3RyaW5nKTsNCg0KCQkJLy8gVHJhbnNsaXRlcmF0ZSBzdHJpbmcgVE9ETzogbG9vayBhZ2FpbiBhcyB0aGlzIG1ha2UgaXQgbG93ZXJjYXNlDQoJCQkvLyAkc3RyaW5nID0gU3RyaW5nSGVscGVyOjp0cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KDQoJCQkvLyBmaXJzdCByZW1vdmUgYWxsIFtcXSBiYWNrc2xhc2hlcw0KCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCdcXCcsICcxJywgJHN0cmluZyk7DQoNCgkJCS8vIHJlbW92ZSBhbGwgYW5kIGtlZXAgb25seSBjaGFyYWN0ZXJzIGFuZCBbXF0gYmFja3NsYXNoZXMgaW5zaWRlIG9mIHRoZSBzdHJpbmcNCgkJCSRzdHJpbmcgPSB0cmltKCBwcmVnX3JlcGxhY2UoIi9bXkEtWmEtejFdLyIsICcnLCAkc3RyaW5nKSwgJzEnKTsNCg0KCQkJLy8gcGxhY2UgdGhlIFtcXSBiYWNrc2xhc2hlcyBiYWNrDQoJCQlyZXR1cm4gdHJpbSggcHJlZ19yZXBsYWNlKCIvMSsvIiwgJ1xcJywgJHN0cmluZykpOw0KCQl9DQoJCS8vIG5vdCBhIHN0cmluZw0KCQlyZXR1cm4gJyc7DQoJfQ0K', '{}', 'NamespaceHelper', 'VDM\\Joomla\\Utilities.String.NamespaceHelper', '1.0.0', '{}', 'String Namespace Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', '', 1, '2022-03-08 23:27:57', '2022-05-21 13:27:39', 15, 5), -(15, 1, 'Control the naming of a field type\r\n\r\n@since 3.0.9', '', '', 'a8935cbe-7701-40dc-bfd5-675f2d600954', 'dXNlIEpvb21sYVxDTVNcQ29tcG9uZW50XENvbXBvbmVudEhlbHBlcjs=', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBmaWVsZCBidWlsZGVyIHN3aXRjaA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRidWlsZGVyID0gZmFsc2U7DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgdHlwZSBuYW1lIHNhZmUNCgkgKg0KCSAqIEBwYXJhbSAgIFN0cmluZyAgICAgICRzdHJpbmcgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAkb3B0aW9uICAgIFRoZSBvcHRpb24gZm9yIHRoZSBjb21wb25lbnQuDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJHN0cmluZywgJG9wdGlvbiA9IG51bGwpDQoJew0KCQkvLyBnZXQgZ2xvYmFsIHZhbHVlDQoJCWlmIChzZWxmOjokYnVpbGRlciA9PT0gZmFsc2UpDQoJCXsNCgkJCXNlbGY6OiRidWlsZGVyID0gSGVscGVyOjpnZXRQYXJhbXMoJG9wdGlvbiktPmdldCgndHlwZV9uYW1lX2J1aWxkZXInLCAxKTsNCgkJfQ0KDQoJCS8vIHVzZSB0aGUgbmV3IGNvbnZlbnRpb24NCgkJaWYgKDIgPT0gc2VsZjo6JGJ1aWxkZXIpDQoJCXsNCgkJCS8vIDBubHkgY29udGludWUgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJHN0cmluZykpDQoJCQl7DQoJCQkJLy8gY2hlY2sgdGhhdCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIG5vdCBhIG51bWJlcg0KCQkJCWlmIChpc19udW1lcmljKHN1YnN0cigkc3RyaW5nLCAwLCAxKSkpDQoJCQkJew0KCQkJCQkkc3RyaW5nID0gU3RyaW5nSGVscGVyOjpudW1iZXJzKCRzdHJpbmcpOw0KCQkJCX0NCg0KCQkJCS8vIFRyYW5zbGl0ZXJhdGUgc3RyaW5nDQoJCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCg0KCQkJCS8vIHJlbW92ZSBhbGwgYW5kIGtlZXAgb25seSBjaGFyYWN0ZXJzIGFuZCBudW1iZXJzIGFuZCBwb2ludCAoVE9ETyBqdXN0IG9uZSBwb2ludCkNCgkJCQkkc3RyaW5nID0gdHJpbShwcmVnX3JlcGxhY2UoIi9bXkEtWmEtejAtOVwuXS8iLCAnJywgJHN0cmluZykpOw0KDQoJCQkJLy8gYmVzdCBpcyB0byByZXR1cm4gbG93ZXIgKGZvciBhbGwgc3RyaW5nIGVxdWFsaXR5IGluIGNvbXBpbGVyKQ0KCQkJCXJldHVybiBzdHJ0b2xvd2VyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8gbm90IGEgc3RyaW5nDQoJCQlyZXR1cm4gJyc7DQoJCX0NCg0KCQkvLyB1c2UgdGhlIGRlZmF1bHQgKG9yaWdpbmFsIGJlaGF2aW91ci9jb252ZW50aW9uKQ0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCX0NCg==', '{}', 'TypeHelper', 'VDM\\Joomla\\Utilities.String.TypeHelper', '1.0.0', '{}', 'String Type Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"},\"use_selection1\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\"}}', '', 1, '2022-03-08 23:33:09', '2022-05-21 13:27:39', 14, 5), -(16, '', 'Control the naming of a class and function\r\n\r\n@since 3.0.9', '', '', '30c5b4c2-f75f-4d15-869a-f8bfedd87358', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBjbGFzcyBvciBmdW5jdGlvbiBuYW1lIHNhZmUNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICAgICAgVGhlIG5hbWUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJG5hbWUpDQoJew0KCQkvLyByZW1vdmUgbnVtYmVycyBpZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIGEgbnVtYmVyDQoJCWlmIChpc19udW1lcmljKHN1YnN0cigkbmFtZSwgMCwgMSkpKQ0KCQl7DQoJCQkkbmFtZSA9IFN0cmluZ0hlbHBlcjo6bnVtYmVycygkbmFtZSk7DQoJCX0NCg0KCQkvLyByZW1vdmUgYWxsIHNwYWNlcyBhbmQgc3RyYW5nZSBjaGFyYWN0ZXJzDQoJCXJldHVybiB0cmltKHByZWdfcmVwbGFjZSgiL1teQS1aYS16MC05Xy1dLyIsICcnLCAkbmFtZSkpOw0KCX0NCg==', '{}', 'ClassfunctionHelper', 'VDM\\Joomla\\Utilities.String.ClassfunctionHelper', '1.0.0', '{}', 'String Classfunction Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', '', 1, '2022-03-08 23:43:10', '2022-05-21 13:27:39', 14, 5), -(17, 1, 'Some easy get...\r\n\r\n@since 3.0.9', '', '', 'db87c339-5bb6-4291-a7ef-2c48ea1b06bc', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIEdldCBhIFZhcmlhYmxlIA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHRhYmxlICAgICAgICBUaGUgdGFibGUgZnJvbSB3aGljaCB0byBnZXQgdGhlIHZhcmlhYmxlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgbWl4IHN0cmluZy9pbnQvZmxvYXQNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB2YXIoJHRhYmxlLCAkd2hlcmUgPSBudWxsLCAkd2hlcmVTdHJpbmcgPSAndXNlcicsICR3aGF0ID0gJ2lkJywgJG9wZXJhdG9yID0gJz0nLCAkbWFpbiA9IG51bGwpDQoJew0KCQlpZihlbXB0eSgkd2hlcmUpKQ0KCQl7DQoJCQkkd2hlcmUgPSBGYWN0b3J5OjpnZXRVc2VyKCktPmlkOw0KCQl9DQoNCgkJaWYoZW1wdHkoJG1haW4pKQ0KCQl7DQoJCQkkbWFpbiA9IEhlbHBlcjo6Z2V0Q29kZSgpOw0KCQl9DQoNCgkJLy8gR2V0IGEgZGIgY29ubmVjdGlvbi4NCgkJJGRiID0gRmFjdG9yeTo6Z2V0RGJvKCk7DQoNCgkJLy8gQ3JlYXRlIGEgbmV3IHF1ZXJ5IG9iamVjdC4NCgkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCgkJJHF1ZXJ5LT5zZWxlY3QoJGRiLT5xdW90ZU5hbWUoYXJyYXkoJHdoYXQpKSk7DQoNCgkJaWYgKGVtcHR5KCR0YWJsZSkpDQoJCXsNCgkJCSRxdWVyeS0+ZnJvbSgkZGItPnF1b3RlTmFtZSgnI19fJyAuICRtYWluKSk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfXycgLiAkbWFpbiAuICdfJyAuICR0YWJsZSkpOw0KCQl9DQoNCgkJaWYgKGlzX251bWVyaWMoJHdoZXJlKSkNCgkJew0KCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAnIC4gKGludCkgJHdoZXJlKTsNCgkJfQ0KCQllbHNlaWYgKGlzX3N0cmluZygkd2hlcmUpKQ0KCQl7DQoJCQkkcXVlcnktPndoZXJlKCRkYi0+cXVvdGVOYW1lKCR3aGVyZVN0cmluZykgLiAnICcgLiAkb3BlcmF0b3IgLiAnICcgLiAkZGItPnF1b3RlKChzdHJpbmcpJHdoZXJlKSk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCg0KCQkkZGItPnNldFF1ZXJ5KCRxdWVyeSk7DQoJCSRkYi0+ZXhlY3V0ZSgpOw0KDQoJCWlmICgkZGItPmdldE51bVJvd3MoKSkNCgkJew0KCQkJcmV0dXJuICRkYi0+bG9hZFJlc3VsdCgpOw0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYXJyYXkgb2YgdmFyaWFibGVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdGFibGUgICAgICAgIFRoZSB0YWJsZSBmcm9tIHdoaWNoIHRvIGdldCB0aGUgdmFyaWFibGVzDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqIEBwYXJhbSAgIGJvb2wgICAgICR1bmlxdWUgICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYSB1bmlxdWUgYXJyYXkNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmFycygkdGFibGUsICR3aGVyZSA9IG51bGwsICR3aGVyZVN0cmluZyA9ICd1c2VyJywgJHdoYXQgPSAnaWQnLCAkb3BlcmF0b3IgPSAnSU4nLCAkbWFpbiA9IG51bGwsICR1bmlxdWUgPSB0cnVlKQ0KCXsNCgkJaWYoZW1wdHkoJHdoZXJlKSkNCgkJew0KCQkJJHdoZXJlID0gRmFjdG9yeTo6Z2V0VXNlcigpLT5pZDsNCgkJfQ0KDQoJCWlmKGlzX251bGwoJG1haW4pKQ0KCQl7DQoJCQkkbWFpbiA9IEhlbHBlcjo6Z2V0Q29kZSgpOw0KCQl9DQoNCgkJaWYgKCFBcnJheUhlbHBlcjo6Y2hlY2soJHdoZXJlKSAmJiAkd2hlcmUgPiAwKQ0KCQl7DQoJCQkkd2hlcmUgPSBhcnJheSgkd2hlcmUpOw0KCQl9DQoNCgkJaWYgKEFycmF5SGVscGVyOjpjaGVjaygkd2hlcmUpKQ0KCQl7DQoJCQkvLyBwcmVwIG1haW4gPC0tIHdoeT8gd2VsbCBpZiAkbWFpbj0nJyBpcyBlbXB0eSB0aGVuICR0YWJsZSBjYW4gYmUgY2F0ZWdvcmllcyBvciB1c2Vycw0KCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJG1haW4pKQ0KCQkJew0KCQkJCSRtYWluID0gJ18nIC4gbHRyaW0oJG1haW4sICdfJyk7DQoJCQl9DQoNCgkJCS8vIEdldCBhIGRiIGNvbm5lY3Rpb24uDQoJCQkkZGIgPSBGYWN0b3J5OjpnZXREYm8oKTsNCg0KCQkJLy8gQ3JlYXRlIGEgbmV3IHF1ZXJ5IG9iamVjdC4NCgkJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoJCQkkcXVlcnktPnNlbGVjdCgkZGItPnF1b3RlTmFtZShhcnJheSgkd2hhdCkpKTsNCg0KCQkJaWYgKGVtcHR5KCR0YWJsZSkpDQoJCQl7DQoJCQkJJHF1ZXJ5LT5mcm9tKCRkYi0+cXVvdGVOYW1lKCcjX18nIC4gJG1haW4pKTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfJyAuICRtYWluIC4gJ18nIC4gJHRhYmxlKSk7DQoJCQl9DQoNCgkJCS8vIGFkZCBzdHJpbmdzIHRvIGFycmF5IHNlYXJjaA0KCQkJaWYgKCdJTl9TVFJJTkdTJyA9PT0gJG9wZXJhdG9yIHx8ICdOT1QgSU5fU1RSSU5HUycgPT09ICRvcGVyYXRvcikNCgkJCXsNCgkJCQkkcXVlcnktPndoZXJlKCRkYi0+cXVvdGVOYW1lKCR3aGVyZVN0cmluZykgLiAnICcgLiBzdHJfcmVwbGFjZSgnX1NUUklOR1MnLCAnJywgJG9wZXJhdG9yKSAuICcgKCInIC4gaW1wbG9kZSgnIiwiJywkd2hlcmUpIC4gJyIpJyk7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAoJyAuIGltcGxvZGUoJywnLCR3aGVyZSkgLiAnKScpOw0KCQkJfQ0KDQoJCQkkZGItPnNldFF1ZXJ5KCRxdWVyeSk7DQoJCQkkZGItPmV4ZWN1dGUoKTsNCg0KCQkJaWYgKCRkYi0+Z2V0TnVtUm93cygpKQ0KCQkJew0KCQkJCWlmICgkdW5pcXVlKQ0KCQkJCXsNCgkJCQkJcmV0dXJuIGFycmF5X3VuaXF1ZSgkZGItPmxvYWRDb2x1bW4oKSk7DQoJCQkJfQ0KCQkJCXJldHVybiAkZGItPmxvYWRDb2x1bW4oKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGFsbCBzdHJpbmdzIGJldHdlZW4gdHdvIG90aGVyIHN0cmluZ3MNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkc3RhcnQgICAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRlbmQgICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheSAgICAgICAgICBPbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWxsQmV0d2VlbigkY29udGVudCwgJHN0YXJ0LCAkZW5kKQ0KCXsNCgkJLy8gcmVzZXQgYnVja2V0DQoJCSRidWNrZXQgPSBhcnJheSgpOw0KCQlmb3IgKCRpID0gMDsgOyAkaSsrKQ0KCQl7DQoJCQkvLyBzZWFyY2ggZm9yIHN0cmluZw0KCQkJJGZvdW5kID0gc2VsZjo6YmV0d2VlbigkY29udGVudCwkc3RhcnQsJGVuZCk7DQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZm91bmQpKQ0KCQkJew0KCQkJCS8vIGFkZCB0byBidWNrZXQNCgkJCQkkYnVja2V0W10gPSAkZm91bmQ7DQoJCQkJLy8gYnVpbGQgcmVtb3ZhbCBzdHJpbmcNCgkJCQkkcmVtb3ZlID0gJHN0YXJ0LiRmb3VuZC4kZW5kOw0KCQkJCS8vIHJlbW92ZSBmcm9tIGNvbnRlbnQNCgkJCQkkY29udGVudCA9IHN0cl9yZXBsYWNlKCRyZW1vdmUsJycsJGNvbnRlbnQpOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQkJLy8gc2FmZXR5IGNhdGNoDQoJCQlpZiAoJGkgPT0gNTAwKQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoJCS8vIG9ubHkgcmV0dXJuIHVuaXF1ZSBhcnJheSBvZiB2YWx1ZXMNCgkJcmV0dXJuICBhcnJheV91bmlxdWUoJGJ1Y2tldCk7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGEgc3RyaW5nIGJldHdlZW4gdHdvIG90aGVyIHN0cmluZ3MNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkc3RhcnQgICAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRlbmQgICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJGRlZmF1bHQgICAgIFRoZSBkZWZhdWx0IHZhbHVlIGlmIG5vbmUgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIHN0cmluZyAgICAgICAgICBPbiBzdWNjZXNzIC8gZW1wdHkgc3RyaW5nIG9uIGZhaWx1cmUNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBiZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQsICRkZWZhdWx0ID0gJycpDQoJew0KCQkkciA9IGV4cGxvZGUoJHN0YXJ0LCAkY29udGVudCk7DQoJCWlmIChpc3NldCgkclsxXSkpDQoJCXsNCgkJCSRyID0gZXhwbG9kZSgkZW5kLCAkclsxXSk7DQoJCQlyZXR1cm4gJHJbMF07DQoJCX0NCgkJcmV0dXJuICRkZWZhdWx0Ow0KCX0NCg==', '{}', 'GetHelper', 'VDM\\Joomla\\Utilities.GetHelper', '1.0.0', '{}', 'Utilities GetHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\"}}', '', 1, '2022-03-09 00:21:06', '2022-05-21 13:27:39', 20, 9), -(18, '', 'Some object tricks\r\n\r\n@since 3.0.9', '', '', '91004529-94a9-4590-b842-e7c6b624ecf5', '', '', '', '{}', 'CS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYW4gb2JqZWN0IHdpdGggYSBsZW5ndGgNCgkgKg0KCSAqIEBpbnB1dAlvYmplY3QgICBUaGUgb2JqZWN0IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrKCRvYmplY3QpDQoJew0KCQlpZiAoaXNfb2JqZWN0KCRvYmplY3QpKQ0KCQl7DQoJCQlyZXR1cm4gY291bnQoKGFycmF5KSAkb2JqZWN0KSA+IDA7DQoJCX0NCg0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0K', '{}', 'ObjectHelper', 'VDM\\Joomla\\Utilities.ObjectHelper', '1.0.0', '{}', 'Utilities Object Helper', 'abstract class', '{}', '', 1, '2022-03-09 00:35:23', '2022-05-21 13:27:39', 12, 8), -(19, '', 'Basic Math Helper\r\n\r\n@since 3.0.9', '', '', '152c8793-8b75-4715-996a-257b9f65451c', '', '', '', '{}', 'CS8qKg0KCSAqIGJjIG1hdGggd3JhcHBlciAodmVyeSBiYXNpYyBub3QgZm9yIGFjY291bnRpbmcpDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdHlwZSAgICBUaGUgdHlwZSBiYyBtYXRoDQoJICogQHBhcmFtICAgaW50ICAgICAgJHZhbDEgICAgVGhlIGZpcnN0IHZhbHVlDQoJICogQHBhcmFtICAgaW50ICAgICAgJHZhbDIgICAgVGhlIHNlY29uZCB2YWx1ZQ0KCSAqIEBwYXJhbSAgIGludCAgICAgICRzY2FsZSAgIFRoZSBzY2FsZSB2YWx1ZQ0KCSAqDQoJICogQHJldHVybiBpbnQNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBiYygkdHlwZSwgJHZhbDEsICR2YWwyLCAkc2NhbGUgPSAwKQ0KCXsNCgkJLy8gYnVpbGQgZnVuY3Rpb24gbmFtZQ0KCQkkZnVuY3Rpb24gPSAnYmMnIC4gJHR5cGU7DQoJCS8vIHVzZSB0aGUgYmNtYXRoIGZ1bmN0aW9uIGlmIGF2YWlsYWJsZQ0KCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCRmdW5jdGlvbikpDQoJCXsNCgkJCXJldHVybiAkZnVuY3Rpb24oJHZhbDEsICR2YWwyLCAkc2NhbGUpOw0KCQl9DQoJCS8vIGlmIGZ1bmN0aW9uIGRvZXMgbm90IGV4aXN0IHdlIHVzZSArLSovIG9wZXJhdG9ycyAoZmFsbGJhY2sgLSBub3QgaWRlYWwpDQoJCXN3aXRjaCAoJHR5cGUpDQoJCXsNCgkJCS8vIE11bHRpcGx5IHR3byBudW1iZXJzDQoJCQljYXNlICdtdWwnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSAqICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gRGl2aWRlIG9mIHR3byBudW1iZXJzDQoJCQljYXNlICdkaXYnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSAvICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gQWRkaW5nIHR3byBudW1iZXJzDQoJCQljYXNlICdhZGQnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSArICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gU3VidHJhY3Qgb25lIG51bWJlciBmcm9tIHRoZSBvdGhlcg0KCQkJY2FzZSAnc3ViJzoNCgkJCQlyZXR1cm4gKHN0cmluZykgcm91bmQoJHZhbDEgLSAkdmFsMiwgJHNjYWxlKTsNCgkJCQlicmVhazsNCgkJCS8vIFJhaXNlIGFuIGFyYml0cmFyeSBwcmVjaXNpb24gbnVtYmVyIHRvIGFub3RoZXINCgkJCWNhc2UgJ3Bvdyc6DQoJCQkJcmV0dXJuIChzdHJpbmcpIHJvdW5kKHBvdygkdmFsMSwgJHZhbDIpLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gQ29tcGFyZSB0d28gYXJiaXRyYXJ5IHByZWNpc2lvbiBudW1iZXJzDQoJCQljYXNlICdjb21wJzoNCgkJCQlyZXR1cm4gKHJvdW5kKCR2YWwxLDIpID09IHJvdW5kKCR2YWwyLDIpKTsNCgkJCQlicmVhazsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogQmFzaWMgc3VtIG9mIGFuIGFycmF5IHdpdGggbW9yZSBwcmVjaXNpb24NCgkgKg0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGFycmF5ICAgIFRoZSB2YWx1ZXMgdG8gc3VtDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VtKCRhcnJheSwgJHNjYWxlID0gNCkNCgl7DQoJCS8vIHVzZSB0aGUgYmNhZGQgZnVuY3Rpb24gaWYgYXZhaWxhYmxlDQoJCWlmIChmdW5jdGlvbl9leGlzdHMoJ2JjYWRkJykpDQoJCXsNCgkJCS8vIHNldCB0aGUgc3RhcnQgdmFsdWUNCgkJCSR2YWx1ZSA9IDAuMDsNCgkJCS8vIGxvb3AgdGhlIHZhbHVlcyBhbmQgcnVuIGJjYWRkDQoJCQlmb3JlYWNoKCRhcnJheSBhcyAkdmFsKQ0KCQkJew0KCQkJCSR2YWx1ZSA9IGJjYWRkKCR2YWx1ZSwgJHZhbCwgJHNjYWxlKTsNCgkJCX0NCgkJCXJldHVybiAkdmFsdWU7DQoJCX0NCgkJLy8gZmFsbCBiYWNrIG9uIGFycmF5IHN1bQ0KCQlyZXR1cm4gYXJyYXlfc3VtKCRhcnJheSk7DQoJfQ0K', '{}', 'MathHelper', 'VDM\\Joomla\\Utilities.MathHelper', '1.0.0', '{}', 'Utilities Math Helper', 'abstract class', '{}', '', 1, '2022-03-09 13:05:39', '2022-05-21 13:27:39', 8, 9), -(20, '', 'Control the naming of a plugin\r\n\r\n@since 3.0.9', '', '', '3cf76fbf-fd95-4a33-878e-7aff6d36b7f6', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBwbHVnaW4gZm9sZGVyIG5hbWUgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAkY29kZU5hbWUgICBUaGUgbmFtZQ0KCSAqIEBpbnB1dAlzdHJpbmcgICAgJGdyb3VwICAgVGhlIGdyb3VwIG5hbWUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FmZUZvbGRlck5hbWUoJGNvZGVOYW1lLCAkZ3JvdXApDQoJew0KCQkvLyBlZGl0b3JzLXh0ZCBncm91cCBwbHVnaW5zIG11c3QgaGF2ZSBhIGNsYXNzIHdpdGggcGxnQnV0dG9uPFBsdWdpbk5hbWU+IHN0cnVjdHVyZQ0KCQlpZiAoJGdyb3VwID09PSAnZWRpdG9ycy14dGQnKQ0KCQl7DQoJCQkkZ3JvdXAgPSAnQnV0dG9uJzsNCgkJfQ0KDQoJCXJldHVybiAncGxnXycgLiBzdHJ0b2xvd2VyKCRncm91cCkgLiAnXycgLiBzdHJ0b2xvd2VyKA0KCQkJJGNvZGVOYW1lDQoJCSk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIHBsdWdpbiBjbGFzcyBuYW1lIHNhZmUNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICAgJGNvZGVOYW1lICAgVGhlIG5hbWUNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRncm91cCAgIFRoZSBncm91cCBuYW1lDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVDbGFzc05hbWUoJGNvZGVOYW1lLCAkZ3JvdXApDQoJew0KCQkvLyBlZGl0b3JzLXh0ZCBncm91cCBwbHVnaW5zIG11c3QgaGF2ZSBhIGNsYXNzIHdpdGggcGxnQnV0dG9uPFBsdWdpbk5hbWU+IHN0cnVjdHVyZQ0KCQlpZiAoJGdyb3VwID09PSAnZWRpdG9ycy14dGQnKQ0KCQl7DQoJCQkkZ3JvdXAgPSAnQnV0dG9uJzsNCgkJfQ0KDQoJCXJldHVybiAnUGxnJyAuIHVjZmlyc3QoJGdyb3VwKSAuIHVjZmlyc3QoDQoJCQkkY29kZU5hbWUNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBNYWtpbmcgcGx1Z2luIGluc3RhbGwgY2xhc3MgbmFtZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRjb2RlTmFtZSAgIFRoZSBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAkZ3JvdXAgICBUaGUgZ3JvdXAgbmFtZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlSW5zdGFsbENsYXNzTmFtZSgkY29kZU5hbWUsICRncm91cCkNCgl7DQoJCS8vIGVkaXRvcnMteHRkIGdyb3VwIHBsdWdpbnMgbXVzdCBoYXZlIGEgY2xhc3Mgd2l0aCBwbGdCdXR0b248UGx1Z2luTmFtZT4gc3RydWN0dXJlDQoJCWlmICgkZ3JvdXAgPT09ICdlZGl0b3JzLXh0ZCcpDQoJCXsNCgkJCSRncm91cCA9ICdCdXR0b24nOw0KCQl9DQoNCgkJcmV0dXJuICdwbGcnIC4gdWNmaXJzdCgkZ3JvdXApIC4gdWNmaXJzdCgNCgkJCSRjb2RlTmFtZQ0KCQkpIC4gJ0luc3RhbGxlclNjcmlwdCc7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGxhbmd1YWdlIHByZWZpeCBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRjb2RlTmFtZSAgIFRoZSBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAkZ3JvdXAgICBUaGUgZ3JvdXAgbmFtZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlTGFuZ1ByZWZpeCgkY29kZU5hbWUsICRncm91cCkNCgl7DQoJCS8vIGVkaXRvcnMteHRkIGdyb3VwIHBsdWdpbnMgbXVzdCBoYXZlIGEgY2xhc3Mgd2l0aCBwbGdCdXR0b248UGx1Z2luTmFtZT4gc3RydWN0dXJlDQoJCWlmICgkZ3JvdXAgPT09ICdlZGl0b3JzLXh0ZCcpDQoJCXsNCgkJCSRncm91cCA9ICdCdXR0b24nOw0KCQl9DQoNCgkJcmV0dXJuICdQTEdfJyAuIHN0cnRvdXBwZXIoJGdyb3VwKSAuICdfJyAuIHN0cnRvdXBwZXIoDQoJCQkkY29kZU5hbWUNCgkJKTsNCgl9DQo=', '{}', 'PluginHelper', 'VDM\\Joomla\\Utilities.String.PluginHelper', '1.0.0', '{}', 'String Plugin Helper', 'abstract class', '{}', '', 1, '2022-03-09 14:44:58', '2022-05-21 13:27:39', 13, 5), -(21, 1, 'Global Unique ID Helper\r\n\r\n@since 3.0.9', '', '', '9c513baf-b279-43fd-ae29-a585c8cbc4f0', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIFJldHVybnMgYSBHVUlEdjQgc3RyaW5nDQoJICogDQoJICogVGhhbmtzIHRvIERhdmUgUGVhcnNvbiAoYW5kIG90aGVyKQ0KCSAqIGh0dHBzOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmNvbS1jcmVhdGUtZ3VpZC5waHAjMTE5MTY4IA0KCSAqDQoJICogVXNlcyB0aGUgYmVzdCBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgbWV0aG9kDQoJICogZm9yIGFsbCBzdXBwb3J0ZWQgcGxhdGZvcm1zIHdpdGggZmFsbGJhY2sgdG8gYW4gb2xkZXIsDQoJICogbGVzcyBzZWN1cmUgdmVyc2lvbi4NCgkgKg0KCSAqIEBwYXJhbSBib29sICR0cmltDQoJICoNCgkgKiBAcmV0dXJuIHN0cmluZw0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0KCR0cmltID0gdHJ1ZSkNCgl7DQoJCS8vIFdpbmRvd3MNCgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnY29tX2NyZWF0ZV9ndWlkJykgPT09IHRydWUpDQoJCXsNCgkJCWlmICgkdHJpbSA9PT0gdHJ1ZSkNCgkJCXsNCgkJCQlyZXR1cm4gdHJpbShjb21fY3JlYXRlX2d1aWQoKSwgJ3t9Jyk7DQoJCQl9DQoJCQlyZXR1cm4gY29tX2NyZWF0ZV9ndWlkKCk7DQoJCX0NCg0KCQkvLyBzZXQgdGhlIGJyYWNlcyBpZiBuZWVkZWQNCgkJJGxicmFjZSA9ICR0cmltID8gIiIgOiBjaHIoMTIzKTsgICAgLy8gInsiDQoJCSRyYnJhY2UgPSAkdHJpbSA/ICIiIDogY2hyKDEyNSk7ICAgIC8vICJ9Ig0KDQoJCS8vIE9TWC9MaW51eA0KCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCdvcGVuc3NsX3JhbmRvbV9wc2V1ZG9fYnl0ZXMnKSA9PT0gdHJ1ZSkNCgkJew0KCQkJJGRhdGEgPSBvcGVuc3NsX3JhbmRvbV9wc2V1ZG9fYnl0ZXMoMTYpOw0KCQkJJGRhdGFbNl0gPSBjaHIoIG9yZCgkZGF0YVs2XSkgJiAweDBmIHwgMHg0MCk7ICAgIC8vIHNldCB2ZXJzaW9uIHRvIDAxMDANCgkJCSRkYXRhWzhdID0gY2hyKCBvcmQoJGRhdGFbOF0pICYgMHgzZiB8IDB4ODApOyAgICAvLyBzZXQgYml0cyA2LTcgdG8gMTANCgkJCXJldHVybiAkbGJyYWNlIC4gdnNwcmludGYoJyVzJXMtJXMtJXMtJXMtJXMlcyVzJywgc3RyX3NwbGl0KGJpbjJoZXgoJGRhdGEpLCA0KSkgLiAkbGJyYWNlOw0KCQl9DQoNCgkJLy8gRmFsbGJhY2sgKFBIUCA0LjIrKQ0KCQltdF9zcmFuZCgoZG91YmxlKSBtaWNyb3RpbWUoKSAqIDEwMDAwKTsNCgkJJGNoYXJpZCA9IHN0cnRvbG93ZXIoIG1kNSggdW5pcWlkKCByYW5kKCksIHRydWUpKSk7DQoJCSRoeXBoZW4gPSBjaHIoNDUpOyAgICAgICAgICAgICAgICAgIC8vICItIg0KCQkkZ3VpZHY0ID0gJGxicmFjZS4NCgkJCXN1YnN0cigkY2hhcmlkLCAgMCwgIDgpLiAkaHlwaGVuLg0KCQkJc3Vic3RyKCRjaGFyaWQsICA4LCAgNCkuICRoeXBoZW4uDQoJCQlzdWJzdHIoJGNoYXJpZCwgMTIsICA0KS4gJGh5cGhlbi4NCgkJCXN1YnN0cigkY2hhcmlkLCAxNiwgIDQpLiAkaHlwaGVuLg0KCQkJc3Vic3RyKCRjaGFyaWQsIDIwLCAxMikuDQoJCQkkcmJyYWNlOw0KCQlyZXR1cm4gJGd1aWR2NDsNCgl9DQoNCgkvKioNCgkgKiBWYWxpZGF0ZSB0aGUgR2xvYmFsbHkgVW5pcXVlIElkZW50aWZpZXIgKCBhbmQgY2hlY2sgaWYgdGFibGUgYWxyZWFkeSBoYXMgdGhpcyBpZGVudGlmaWVyKQ0KCSAqDQoJICogQHBhcmFtIHN0cmluZyAgICAgICAkZ3VpZA0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgJHRhYmxlDQoJICogQHBhcmFtIGludCAgICAgICAgICAgICRpZA0KCSAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY29tcG9uZW50DQoJICoNCgkgKiBAcmV0dXJuIGJvb2wNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhbGlkKCRndWlkLCAkdGFibGUgPSBudWxsLCAkaWQgPSAwLCAkY29tcG9uZW50ID0gbnVsbCkNCgl7DQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYSBzdHJpbmcNCgkJaWYgKHNlbGY6OnZhbGlkYXRlKCRndWlkKSkNCgkJew0KCQkJLy8gY2hlY2sgaWYgdGFibGUgYWxyZWFkeSBoYXMgdGhpcyBpZGVudGlmaWVyDQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkdGFibGUpKQ0KCQkJew0KCQkJCS8vIGNoZWNrIHRoYXQgd2UgaGF2ZSB0aGUgY29tcG9uZW50IGNvZGUgbmFtZQ0KCQkJCWlmICghaXNfc3RyaW5nKCRjb21wb25lbnQpKQ0KCQkJCXsNCgkJCQkJJGNvbXBvbmVudCA9IChzdHJpbmcpIEhlbHBlcjo6Z2V0Q29kZSgpOw0KCQkJCX0NCgkJCQkvLyBHZXQgdGhlIGRhdGFiYXNlIG9iamVjdCBhbmQgYSBuZXcgcXVlcnkgb2JqZWN0Lg0KCQkJCSRkYiA9IEZhY3Rvcnk6OmdldERibygpOw0KCQkJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoJCQkJJHF1ZXJ5LT5zZWxlY3QoJ0NPVU5UKCopJykNCgkJCQkJLT5mcm9tKCcjX18nIC4gKHN0cmluZykgJGNvbXBvbmVudCAuICdfJyAuIChzdHJpbmcpICR0YWJsZSkNCgkJCQkJLT53aGVyZSgkZGItPnF1b3RlTmFtZSgnZ3VpZCcpIC4gJyA9ICcgLiAkZGItPnF1b3RlKCRndWlkKSk7DQoNCgkJCQkvLyByZW1vdmUgdGhpcyBpdGVtIGZyb20gdGhlIGxpc3QNCgkJCQlpZiAoJGlkID4gMCkNCgkJCQl7DQoJCQkJCSRxdWVyeS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJ2lkJykgLiAnIDw+ICcgLiAoaW50KSAkaWQpOw0KCQkJCX0NCg0KCQkJCS8vIFNldCBhbmQgcXVlcnkgdGhlIGRhdGFiYXNlLg0KCQkJCSRkYi0+c2V0UXVlcnkoJHF1ZXJ5KTsNCgkJCQkkZHVwbGljYXRlID0gKGJvb2wpICRkYi0+bG9hZFJlc3VsdCgpOw0KDQoJCQkJaWYgKCRkdXBsaWNhdGUpDQoJCQkJew0KCQkJCQlyZXR1cm4gZmFsc2U7DQoJCQkJfQ0KCQkJfQ0KCQkJcmV0dXJuIHRydWU7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIGdldCB0aGUgaXRlbSBieSBndWlkIGluIGEgdGFibGUNCgkgKg0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICRndWlkDQoJICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJHRhYmxlDQoJICogQHBhcmFtIHN0cmluZy9hcnJheSAgJHdoYXQNCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgJGNvbXBvbmVudA0KCSAqDQoJICogQHJldHVybiBtaXgNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGl0ZW0oJGd1aWQsICR0YWJsZSwgJHdoYXQgPSAnYS5pZCcsICRjb21wb25lbnQgPSBudWxsKQ0KCXsNCgkJLy8gY2hlY2sgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQlpZiAoc2VsZjo6dmFsaWRhdGUoJGd1aWQpKQ0KCQl7DQoJCQkvLyBjaGVjayBpZiB0YWJsZSBhbHJlYWR5IGhhcyB0aGlzIGlkZW50aWZpZXINCgkJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCR0YWJsZSkpDQoJCQl7DQoJCQkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIHRoZSBjb21wb25lbnQgY29kZSBuYW1lDQoJCQkJaWYgKCFpc19zdHJpbmcoJGNvbXBvbmVudCkpDQoJCQkJew0KCQkJCQkkY29tcG9uZW50ID0gKHN0cmluZykgSGVscGVyOjpnZXRDb2RlKCk7DQoJCQkJfQ0KCQkJCS8vIEdldCB0aGUgZGF0YWJhc2Ugb2JqZWN0IGFuZCBhIG5ldyBxdWVyeSBvYmplY3QuDQoJCQkJJGRiID0gRmFjdG9yeTo6Z2V0RGJvKCk7DQoJCQkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCg0KCQkJCWlmIChBcnJheUhlbHBlcjo6Y2hlY2soJHdoYXQpKQ0KCQkJCXsNCgkJCQkJJHF1ZXJ5LT5zZWxlY3QoJGRiLT5xdW90ZU5hbWUoJHdoYXQpKTsNCgkJCQl9DQoJCQkJZWxzZQ0KCQkJCXsNCgkJCQkJJHF1ZXJ5LT5zZWxlY3QoJHdoYXQpOw0KCQkJCX0NCg0KCQkJCSRxdWVyeS0+ZnJvbSgkZGItPnF1b3RlTmFtZSgnI19fJyAuIChzdHJpbmcpICRjb21wb25lbnQgLiAnXycgLiAoc3RyaW5nKSAkdGFibGUsICdhJykpDQoJCQkJCS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJ2EuZ3VpZCcpIC4gJyA9ICcgLiAkZGItPnF1b3RlKCRndWlkKSk7DQoNCgkJCQkvLyBTZXQgYW5kIHF1ZXJ5IHRoZSBkYXRhYmFzZS4NCgkJCQkkZGItPnNldFF1ZXJ5KCRxdWVyeSk7DQoJCQkJJGRiLT5leGVjdXRlKCk7DQoNCgkJCQlpZiAoJGRiLT5nZXROdW1Sb3dzKCkpDQoJCQkJew0KCQkJCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCR3aGF0KSB8fCAkd2hhdCA9PT0gJ2EuKicpDQoJCQkJCXsNCgkJCQkJCXJldHVybiAkZGItPmxvYWRPYmplY3QoKTsNCgkJCQkJfQ0KCQkJCQllbHNlDQoJCQkJCXsNCgkJCQkJCXJldHVybiAkZGItPmxvYWRSZXN1bHQoKTsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogVmFsaWRhdGUgdGhlIEdsb2JhbGx5IFVuaXF1ZSBJZGVudGlmaWVyDQoJICoNCgkgKiBUaGFua3MgdG8gTGV3aWUNCgkgKiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTUxNTQ1Ni8xNDI5Njc3DQoJICoNCgkgKiBAcGFyYW0gc3RyaW5nICRndWlkDQoJICoNCgkgKiBAcmV0dXJuIGJvb2wNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHZhbGlkYXRlKCRndWlkKQ0KCXsNCgkJLy8gY2hlY2sgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZ3VpZCkpDQoJCXsNCgkJCXJldHVybiBwcmVnX21hdGNoKCIvXihceyk/W2EtZlxkXXs4fSgtW2EtZlxkXXs0fSl7NH1bYS1mXGRdezh9KD8oMSlcfSkkL2kiLCAkZ3VpZCk7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg==', '{}', 'GuidHelper', 'VDM\\Joomla\\Utilities.GuidHelper', '1.0.0', '{}', 'Utilities GuidHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\"}}', '', 1, '2022-03-12 01:27:10', '2022-05-21 13:27:39', 12, 9), -(22, 1, 'File helper\r\n\r\n@since 3.0.9', '', '', 'a223b31e-ea1d-4cdf-92ae-5f9becffaff0', 'dXNlIEpvb21sYVxDTVNcVXJpXFVyaTsNCnVzZSBKb29tbGFcQ01TXEZhY3Rvcnk7DQp1c2UgSm9vbWxhXENNU1xMYW5ndWFnZVxUZXh0Ow0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxQYXRoOw0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGaWxlOw0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGb2xkZXI7DQp1c2UgSm9vbWxhXEFyY2hpdmVcQXJjaGl2ZTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"},\"load_selection2\":{\"load\":\"91004529-94a9-4590-b842-e7c6b624ecf5\"}}', 'CS8qKg0KCSAqIFRyaWdnZXIgZXJyb3Igbm90aWNlIG9ubHkgb25jZQ0KCSAqDQoJICogQHZhciAgICBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyAkY3VybEVycm9yID0gZmFsc2U7DQoNCgkvKioNCgkgKiBUaGUgemlwcGVyIG1ldGhvZA0KCSAqIA0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHdvcmtpbmdEaXJlY3RvcnkgICAgVGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgaXRlbXMgbXVzdCBiZSB6aXBwZWQNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRmaWxlcGF0aCAgICAgICAgICBUaGUgcGF0aCB0byB3aGVyZSB0aGUgemlwIGZpbGUgbXVzdCBiZSBwbGFjZWQNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wgdHJ1ZSAgIE9uIHN1Y2Nlc3MNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHppcCgkd29ya2luZ0RpcmVjdG9yeSwgJiRmaWxlcGF0aCkNCgl7DQoJCS8vIHN0b3JlIHRoZSBjdXJyZW50IGpvb21sYSB3b3JraW5nIGRpcmVjdG9yeQ0KCQkkam9vbWxhID0gZ2V0Y3dkKCk7DQoNCgkJLy8gd2UgYXJlIGNoYW5naW5nIHRoZSB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgY29tcG9uZW50IHRlbXAgZm9sZGVyDQoJCWNoZGlyKCR3b3JraW5nRGlyZWN0b3J5KTsNCg0KCQkvLyB0aGUgZnVsbCBmaWxlIHBhdGggb2YgdGhlIHppcCBmaWxlDQoJCSRmaWxlcGF0aCA9IFBhdGg6OmNsZWFuKCRmaWxlcGF0aCk7DQoNCgkJLy8gZGVsZXRlIGFuIGV4aXN0aW5nIHppcCBmaWxlIChvciB1c2UgYW4gZXhjbHVzaW9uIHBhcmFtZXRlciBpbiBGb2xkZXI6OmZpbGVzKCkNCgkJRmlsZTo6ZGVsZXRlKCRmaWxlcGF0aCk7DQoNCgkJLy8gZ2V0IGEgbGlzdCBvZiBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkgdHJlZSAoYWxzbyB0aGUgaGlkZGVuIGZpbGVzKQ0KCQkkZmlsZXMgPSBGb2xkZXI6OmZpbGVzKCcuJywgJycsIHRydWUsIHRydWUsIGFycmF5KCcuc3ZuJywgJ0NWUycsICcuRFNfU3RvcmUnLCAnX19NQUNPU1gnKSwgYXJyYXkoJy4qficpKTsNCg0KCQkkemlwQXJyYXkgPSBhcnJheSgpOw0KCQkvLyBzZXR1cCB0aGUgemlwIGFycmF5DQoJCWZvcmVhY2ggKCRmaWxlcyBhcyAkZmlsZSkNCgkJew0KCQkJJHRtcCA9IGFycmF5KCk7DQoJCQkkdG1wWyduYW1lJ10gPSBzdHJfcmVwbGFjZSgnLi8nLCAnJywgJGZpbGUpOw0KCQkJJHRtcFsnZGF0YSddID0gc2VsZjo6Z2V0Q29udGVudCgkZmlsZSk7DQoJCQkkdG1wWyd0aW1lJ10gPSBmaWxlbXRpbWUoJGZpbGUpOw0KCQkJJHppcEFycmF5W10gPSAkdG1wOw0KCQl9DQoNCgkJLy8gY2hhbmdlIGJhY2sgdG8gam9vbWxhIHdvcmtpbmcgZGlyZWN0b3J5DQoJCWNoZGlyKCRqb29tbGEpOw0KDQoJCS8vIGdldCB0aGUgemlwIGFkYXB0ZXINCgkJJGFkYXB0ZXIgPSBuZXcgQXJjaGl2ZSgpOw0KCQkkemlwID0gJGFkYXB0ZXItPmdldEFkYXB0ZXIoJ3ppcCcpOw0KDQoJCS8vY3JlYXRlIHRoZSB6aXAgZmlsZQ0KCQlpZiAoJHppcC0+Y3JlYXRlKCRmaWxlcGF0aCwgJHppcEFycmF5KSkNCgkJew0KCQkJcmV0dXJuIHRydWU7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIGdldCB0aGUgY29udGVudCBvZiBhIGZpbGUNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkcGF0aCAgIFRoZSBwYXRoIHRvIHRoZSBmaWxlDQoJICogQHBhcmFtICBzdHJpbmcvYm9vbCAgICRub25lICAgVGhlIHJldHVybiB2YWx1ZSBpZiBubyBjb250ZW50IHdhcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgc3RyaW5nICAgT24gc3VjY2Vzcw0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Q29udGVudCgkcGF0aCwgJG5vbmUgPSAnJykNCgl7DQoJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCRwYXRoKSkNCgkJew0KCQkJLy8gdXNlIGJhc2ljIGZpbGUgZ2V0IGNvbnRlbnQgZm9yIG5vdw0KCQkJaWYgKCgkY29udGVudCA9IEBmaWxlX2dldF9jb250ZW50cygkcGF0aCkpICE9PSBGQUxTRSkNCgkJCXsNCgkJCQlyZXR1cm4gJGNvbnRlbnQ7DQoJCQl9DQoJCQkvLyB1c2UgY3VybCBpZiBhdmFpbGFibGUNCgkJCWVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKSkNCgkJCXsNCgkJCQkvLyBzdGFydCBjdXJsDQoJCQkJJGNoID0gY3VybF9pbml0KCk7DQoJCQkJLy8gc2V0IHRoZSBvcHRpb25zDQoJCQkJJG9wdGlvbnMgPSBhcnJheSgpOw0KCQkJCSRvcHRpb25zW0NVUkxPUFRfVVJMXSA9ICRwYXRoOw0KCQkJCSRvcHRpb25zW0NVUkxPUFRfVVNFUkFHRU5UXSA9ICdNb3ppbGxhLzUuMCAoV2luZG93czsgVTsgV2luZG93cyBOVCA2LjE7IGVuLVVTOyBydjoxLjkuMi4xMikgR2Vja28vMjAxMDEwMjYgRmlyZWZveC8zLjYuMTInOw0KCQkJCSRvcHRpb25zW0NVUkxPUFRfUkVUVVJOVFJBTlNGRVJdID0gVFJVRTsNCgkJCQkkb3B0aW9uc1tDVVJMT1BUX1NTTF9WRVJJRllQRUVSXSA9IEZBTFNFOw0KCQkJCS8vIGxvYWQgdGhlIG9wdGlvbnMNCgkJCQljdXJsX3NldG9wdF9hcnJheSgkY2gsICRvcHRpb25zKTsNCgkJCQkvLyBnZXQgdGhlIGNvbnRlbnQNCgkJCQkkY29udGVudCA9IGN1cmxfZXhlYygkY2gpOw0KCQkJCS8vIGNsb3NlIHRoZSBjb25uZWN0aW9uDQoJCQkJY3VybF9jbG9zZSgkY2gpOw0KDQoJCQkJLy8gcmV0dXJuIGlmIGZvdW5kDQoJCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJGNvbnRlbnQpKQ0KCQkJCXsNCgkJCQkJcmV0dXJuICRjb250ZW50Ow0KCQkJCX0NCgkJCX0NCgkJCWVsc2VpZiAoIXNlbGY6OiRjdXJsRXJyb3IpDQoJCQl7DQoJCQkJLy8gc2V0IHRoZSBub3RpY2UNCgkJCQlGYWN0b3J5OjpnZXRBcHBsaWNhdGlvbigpLT5lbnF1ZXVlTWVzc2FnZShUZXh0OjpfKCc8aDI+Q3VybCBOb3QgRm91bmQhPC9oMj48cD5QbGVhc2Ugc2V0dXAgY3VybCBvbiB5b3VyIHN5c3RlbSwgb3IgPGI+W1tbY29tcG9uZW50XV1dPC9iPiB3aWxsIG5vdCBmdW5jdGlvbiBjb3JyZWN0bHkhPC9wPicpLCAnRXJyb3InKTsNCgkJCQkvLyBsb2FkIHRoaXMgbm90aWNlIG9ubHkgb25jZQ0KCQkJCXNlbGY6OiRjdXJsRXJyb3IgPSB0cnVlOw0KCQkJfQ0KCQl9DQoJCXJldHVybiAkbm9uZTsNCgl9DQoNCgkvKioNCgkgKiBXcml0ZSBhIGZpbGUgdG8gdGhlIHNlcnZlcg0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAkcGF0aCAgICBUaGUgcGF0aCBhbmQgZmlsZSBuYW1lIHdoZXJlIHRvIHNhZmUgdGhlIGRhdGENCgkgKiBAcGFyYW0gIHN0cmluZyAgICRkYXRhICAgIFRoZSBkYXRhIHRvIHNhZmUNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wgdHJ1ZSAgIE9uIHN1Y2Nlc3MNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHdyaXRlKCRwYXRoLCAkZGF0YSkNCgl7DQoJCSRrbGFhciA9IGZhbHNlOw0KCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZGF0YSkpDQoJCXsNCgkJCS8vIG9wZW4gdGhlIGZpbGUNCgkJCSRmaCA9IGZvcGVuKCRwYXRoLCAidyIpOw0KCQkJaWYgKCFpc19yZXNvdXJjZSgkZmgpKQ0KCQkJew0KCQkJCXJldHVybiAka2xhYXI7DQoJCQl9DQoJCQkvLyB3cml0ZSB0byB0aGUgZmlsZQ0KCQkJaWYgKGZ3cml0ZSgkZmgsICRkYXRhKSkNCgkJCXsNCgkJCQkvLyBoYXMgYmVlbiBkb25lDQoJCQkJJGtsYWFyID0gdHJ1ZTsNCgkJCX0NCgkJCS8vIGNsb3NlIGZpbGUuDQoJCQlmY2xvc2UoJGZoKTsNCgkJfQ0KCQlyZXR1cm4gJGtsYWFyOw0KCX0NCg0KCS8qKg0KCSAqIGdldCBhbGwgdGhlIGZpbGUgcGF0aHMgaW4gZm9sZGVyIGFuZCBzdWIgZm9sZGVycw0KCSAqIA0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGZvbGRlciAgICAgVGhlIGxvY2FsIHBhdGggdG8gcGFyc2UNCgkgKiBAcGFyYW0gICBhcnJheSAgICRmaWxlVHlwZXMgIFRoZSB0eXBlIG9mIGZpbGVzIHRvIGdldA0KCSAqDQoJICogQHJldHVybiAgdm9pZA0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UGF0aHMoJGZvbGRlciwgJGZpbGVUeXBlcyA9IGFycmF5KCdcLnBocCcsICdcLmpzJywgJ1wuY3NzJywgJ1wubGVzcycpLCAkcmVjdXJzZSA9IHRydWUsICRmdWxsID0gdHJ1ZSkNCgl7DQoJCWlmIChGb2xkZXI6OmV4aXN0cygkZm9sZGVyKSkNCgkJew0KCQkJLy8gd2UgbXVzdCBmaXJzdCBzdG9yZSB0aGUgY3VycmVudCB3b2tpbmcgZGlyZWN0b3J5DQoJCQkkam9vbWxhID0gZ2V0Y3dkKCk7DQoJCQkvLyB3ZSBhcmUgY2hhbmdpbmcgdGhlIHdvcmtpbmcgZGlyZWN0b3J5IHRvIHRoZSBjb21wb25lbnQgcGF0aA0KCQkJY2hkaXIoJGZvbGRlcik7DQoNCgkJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGZpbGUgdHlwZSBmaWx0ZXINCgkJCWlmIChBcnJheUhlbHBlcjo6Y2hlY2soJGZpbGVUeXBlcykpDQoJCQl7DQoJCQkJLy8gZ2V0IHRoZSBmaWxlcw0KCQkJCWZvcmVhY2ggKCRmaWxlVHlwZXMgYXMgJHR5cGUpDQoJCQkJew0KCQkJCQkvLyBnZXQgYSBsaXN0IG9mIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSB0cmVlDQoJCQkJCSRmaWxlc1tdID0gRm9sZGVyOjpmaWxlcygnLicsICR0eXBlLCAkcmVjdXJzZSwgJGZ1bGwpOw0KCQkJCX0NCgkJCX0NCgkJCWVsc2VpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZmlsZVR5cGVzKSkNCgkJCXsNCgkJCQkvLyBnZXQgYSBsaXN0IG9mIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSB0cmVlDQoJCQkJJGZpbGVzW10gPSBGb2xkZXI6OmZpbGVzKCcuJywgJGZpbGVUeXBlcywgJHJlY3Vyc2UsICRmdWxsKTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkvLyBnZXQgYSBsaXN0IG9mIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSB0cmVlDQoJCQkJJGZpbGVzW10gPSBGb2xkZXI6OmZpbGVzKCcuJywgJy4nLCAkcmVjdXJzZSwgJGZ1bGwpOw0KCQkJfQ0KDQoJCQkvLyBjaGFuZ2UgYmFjayB0byBKb29tbGEgd29ya2luZyBkaXJlY3RvcnkNCgkJCWNoZGlyKCRqb29tbGEpOw0KDQoJCQkvLyByZXR1cm4gYXJyYXkgb2YgZmlsZXMNCgkJCXJldHVybiBhcnJheV9tYXAoIGZ1bmN0aW9uKCRmaWxlKSB7IHJldHVybiBzdHJfcmVwbGFjZSgnLi8nLCAnLycsICRmaWxlKTsgfSwgKGFycmF5KSBBcnJheUhlbHBlcjo6bWVyZ2UoJGZpbGVzKSk7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIEdldCB0aGUgZmlsZSBwYXRoIG9yIHVybA0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAkdHlwZSAgICAgICAgICAgICAgVGhlICh1cmwvcGF0aCkgdHlwZSB0byByZXR1cm4NCgkgKiBAcGFyYW0gIHN0cmluZyAgICR0YXJnZXQgICAgICAgICAgICBUaGUgUGFyYW1zIFRhcmdldCBuYW1lIChpZiBzZXQpDQoJICogQHBhcmFtICBzdHJpbmcgICAkZmlsZVR5cGUgICAgICAgICAgVGhlIGtpbmQgb2YgZmlsZW5hbWUgdG8gZ2VuZXJhdGUgKGlmIG5vdCBzZXQgbm8gZmlsZSBuYW1lIGlzIGdlbmVyYXRlZCkNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRrZXkgICAgICAgICAgICAgICBUaGUga2V5IHRvIGFkanVzdCB0aGUgZmlsZW5hbWUgKGlmIG5vdCBzZXQgaWdub3JlZCkNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRkZWZhdWx0ICAgICAgICAgICBUaGUgZGVmYXVsdCBwYXRoIGlmIG5vdCBzZXQgaW4gUGFyYW1zIChmYWxsYmFjayBwYXRoKQ0KCSAqIEBwYXJhbSAgYm9vbCAgICAgJGNyZWF0ZUlmTm90U2V0ICAgIFRoZSBzd2l0Y2ggdG8gY3JlYXRlIHRoZSBmb2xkZXIgaWYgbm90IGZvdW5kDQoJICoNCgkgKiBAcmV0dXJuICBzdHJpbmcgICAgT24gc3VjY2VzcyB0aGUgcGF0aCBvciB1cmwgaXMgcmV0dXJuZWQgYmFzZWQgb24gdGhlIHR5cGUgcmVxdWVzdGVkDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRQYXRoKCR0eXBlID0gJ3BhdGgnLCAkdGFyZ2V0ID0gJ2ZpbGVwYXRoJywgJGZpbGVUeXBlID0gbnVsbCwgJGtleSA9ICcnLCAkZGVmYXVsdCA9ICcnLCAkY3JlYXRlSWZOb3RTZXQgPSB0cnVlKQ0KCXsNCgkJLy8gbWFrZSBzdXJlIHRvIGFsd2F5cyBoYXZlIGEgc3RyaW5nL3BhdGgNCgkJaWYoIVN0cmluZ0hlbHBlcjo6Y2hlY2soJGRlZmF1bHQpKQ0KCQl7DQoJCQkkZGVmYXVsdCA9IEpQQVRIX1NJVEUgLiAnL2ltYWdlcy8nOw0KCQl9DQoNCgkJLy8gZ2V0IHRoZSBnbG9iYWwgc2V0dGluZ3MNCgkJJGZpbGVQYXRoID0gSGVscGVyOjpnZXRQYXJhbXMoKS0+Z2V0KCR0YXJnZXQsICRkZWZhdWx0KTsNCg0KCQkvLyBjaGVjayB0aGUgZmlsZSBwYXRoIChyZXZlcnQgdG8gZGVmYXVsdCBvbmx5IG9mIG5vdCBhIGhpZGRlbiBmaWxlIHBhdGgpDQoJCWlmICgnaGlkZGVuZmlsZXBhdGgnICE9PSAkdGFyZ2V0ICYmIHN0cnBvcygkZmlsZVBhdGgsIEpQQVRIX1NJVEUpID09PSBmYWxzZSkNCgkJew0KCQkJJGZpbGVQYXRoID0gJGRlZmF1bHQ7DQoJCX0NCg0KCQkvLyBjcmVhdGUgdGhlIGZvbGRlciBpZiBpdCBkb2VzIG5vdCBleGlzdA0KCQlpZiAoJGNyZWF0ZUlmTm90U2V0ICYmICFGb2xkZXI6OmV4aXN0cygkZmlsZVBhdGgpKQ0KCQl7DQoJCQlGb2xkZXI6OmNyZWF0ZSgkZmlsZVBhdGgpOw0KCQl9DQoNCgkJLy8gc2V0dXAgdGhlIGZpbGUgbmFtZQ0KCQkkZmlsZU5hbWUgPSAnJzsNCg0KCQkvLyBHZXQgYmFzaWMga2V5DQoJCSRiYXNpY2tleSA9ICdUaCFzX2lTX24wdF9zQWZlX2J1VF9iM3R0ZXJfdGhlbl9uMHRoaXVnJzsNCgkJLy8gZ2V0IHRoZSBjb21wb25lbnQgaGVscGVyDQoJCSRoZWxwZXIgPSBIZWxwZXI6OmdldCgpOw0KCQkvLyBjaGVjayBpZiBtZXRob2QgZXhpc3QgaW4gaGVscGVyIGNsYXNzDQoJCWlmICgkaGVscGVyICYmIEhlbHBlcjo6bWV0aG9kRXhpc3RzKCdnZXRDcnlwdEtleScpKSANCgkJew0KCQkJJGJhc2lja2V5ID0gJGhlbHBlcjo6Z2V0Q3J5cHRLZXkoJ2Jhc2ljJywgJGJhc2lja2V5KTsNCgkJfQ0KDQoJCS8vIGNoZWNrIHRoZSBrZXkNCgkJaWYgKCFTdHJpbmdIZWxwZXI6OmNoZWNrKCRrZXkpKQ0KCQl7DQoJCQkka2V5ID0gJ3ZEbSc7DQoJCX0NCg0KCQkvLyBzZXQgdGhlIGZpbGUgbmFtZQ0KCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZmlsZVR5cGUpKQ0KCQl7DQoJCQkvLyBzZXQgdGhlIG5hbWUNCgkJCSRmaWxlTmFtZSA9IHRyaW0oIG1kNSgkdHlwZSAuICR0YXJnZXQgLiAkYmFzaWNrZXkgLiAka2V5KSAuICcuJyAuIHRyaW0oJGZpbGVUeXBlLCAnLicpKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCSRmaWxlTmFtZSA9IHRyaW0oIG1kNSgkdHlwZSAuICR0YXJnZXQgLiAkYmFzaWNrZXkgLiAka2V5KSkgLiAnLnR4dCc7DQoJCX0NCg0KCQkvLyByZXR1cm4gdGhlIHVybA0KCQlpZiAoJ3VybCcgPT09ICR0eXBlKQ0KCQl7DQoJCQlpZiAoXHN0cnBvcygkZmlsZVBhdGgsIEpQQVRIX1NJVEUpICE9PSBmYWxzZSkNCgkJCXsNCgkJCQkkZmlsZVBhdGggPSB0cmltKCBzdHJfcmVwbGFjZSggSlBBVEhfU0lURSwgJycsICRmaWxlUGF0aCksICcvJyk7DQoNCgkJCQlyZXR1cm4gVXJpOjpyb290KCkgLiAkZmlsZVBhdGggLiAnLycgLiAkZmlsZU5hbWU7DQoJCQl9DQoNCgkJCS8vIHNpbmNlIHRoZSBwYXRoIGlzIGJlaGluZCB0aGUgcm9vdCBmb2xkZXIgb2YgdGhlIHNpdGUsIHJldHVybiBvbmx5IHRoZSByb290IHVybCAobWF5IGJlIHVzZWQgdG8gYnVpbGQgdGhlIGxpbmspDQoJCQlyZXR1cm4gVXJpOjpyb290KCk7DQoJCX0NCg0KCQkvLyBzYW5pdGl6ZSB0aGUgcGF0aA0KCQlyZXR1cm4gJy8nIC4gdHJpbSggJGZpbGVQYXRoLCAnLycgKSAuICcvJyAuICRmaWxlTmFtZTsNCgl9DQoNCgkvKioNCgkgKiBDaGVjayBpZiBmaWxlIGV4aXN0DQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRwYXRoICAgVGhlIHVybC9wYXRoIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJuICBib29sICAgICAgSWYgZXhpc3QgdHJ1ZQ0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZXhpc3RzKCRwYXRoKQ0KCXsNCgkJJGV4aXN0cyA9IGZhbHNlOw0KCQkvLyBpZiB0aGlzIGlzIGEgbG9jYWwgcGF0aA0KCQlpZiAoc3RycG9zKCRwYXRoLCAnaHR0cDonKSA9PT0gZmFsc2UgJiYgc3RycG9zKCRwYXRoLCAnaHR0cHM6JykgPT09IGZhbHNlKQ0KCQl7DQoJCQlpZiAoZmlsZV9leGlzdHMoJHBhdGgpKQ0KCQkJew0KCQkJCSRleGlzdHMgPSB0cnVlOw0KCQkJfQ0KCQl9DQoJCS8vIGNoZWNrIGlmIHdlIGNhbiB1c2UgY3VybA0KCQllbHNlaWYgKGZ1bmN0aW9uX2V4aXN0cygnY3VybF92ZXJzaW9uJykpDQoJCXsNCgkJCS8vIGluaXRpYXRlIGN1cmwNCgkJCSRjaCA9IGN1cmxfaW5pdCgkcGF0aCk7DQoJCQkvLyBDVVJMT1BUX05PQk9EWSAoZG8gbm90IHJldHVybiBib2R5KQ0KCQkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX05PQk9EWSwgdHJ1ZSk7DQoJCQkvLyBtYWtlIGNhbGwNCgkJCSRyZXN1bHQgPSBjdXJsX2V4ZWMoJGNoKTsNCgkJCS8vIGNoZWNrIHJldHVybiB2YWx1ZQ0KCQkJaWYgKCRyZXN1bHQgIT09IGZhbHNlKQ0KCQkJew0KCQkJCS8vIGdldCB0aGUgaHR0cCBDT0RFDQoJCQkJJHN0YXR1c0NvZGUgPSBjdXJsX2dldGluZm8oJGNoLCBDVVJMSU5GT19IVFRQX0NPREUpOw0KCQkJCWlmICgkc3RhdHVzQ29kZSAhPT0gNDA0KQ0KCQkJCXsNCgkJCQkJJGV4aXN0cyA9IHRydWU7DQoJCQkJfQ0KCQkJfQ0KCQkJLy8gY2xvc2UgdGhlIGNvbm5lY3Rpb24NCgkJCWN1cmxfY2xvc2UoJGNoKTsNCgkJfQ0KCQllbHNlaWYgKCRoZWFkZXJzID0gQGdldF9oZWFkZXJzKCRwYXRoKSkNCgkJew0KCQkJaWYoaXNzZXQoJGhlYWRlcnNbMF0pICYmIGlzX3N0cmluZygkaGVhZGVyc1swXSkgJiYgc3RycG9zKCRoZWFkZXJzWzBdLCc0MDQnKSA9PT0gZmFsc2UpDQoJCQl7DQoJCQkJJGV4aXN0cyA9IHRydWU7DQoJCQl9DQoJCX0NCgkJcmV0dXJuICRleGlzdHM7DQoJfQ0K', '{}', 'FileHelper', 'VDM\\Joomla\\Utilities.FileHelper', '1.0.0', '{}', 'Utilities FileHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-12 02:09:18', '2022-06-11 16:54:51', 24, 9), -(23, 1, 'Some component helper\r\n\r\n@since 3.0.11', '', '', '640b5352-fb09-425f-a26e-cd44eda03f15', 'dXNlIEpvb21sYVxJbnB1dFxJbnB1dDsNCnVzZSBKb29tbGFcQ01TXENvbXBvbmVudFxDb21wb25lbnRIZWxwZXI7DQp1c2UgSm9vbWxhXFJlZ2lzdHJ5XFJlZ2lzdHJ5Ow==', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBjdXJyZW50IG9wdGlvbg0KCSAqDQoJICogQHZhciAgICBTdHJpbmcNCgkgKiBAc2luY2UgICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljICRvcHRpb247DQoNCgkvKioNCgkgKiBUaGUgY29tcG9uZW50IHBhcmFtcyBsaXN0IGNhY2hlDQoJICoNCgkgKiBAdmFyICAgIFJlZ2lzdHJ5W10NCgkgKiBAc2luY2UgICAzLjAuMTENCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRwYXJhbXMgPSBhcnJheSgpOw0KDQoJLyoqDQoJICogR2V0cyB0aGUgcGFyYW1ldGVyIG9iamVjdCBmb3IgdGhlIGNvbXBvbmVudA0KCSAqDQoJICogQHBhcmFtICAgU3RyaW5nICAgICAgICAgICAgICAgJG9wdGlvbiAgVGhlIG9wdGlvbiBmb3IgdGhlIGNvbXBvbmVudC4NCgkgKg0KCSAqIEByZXR1cm4gIFJlZ2lzdHJ5ICAgICAgICAgICAgQSBSZWdpc3RyeSBvYmplY3QuDQoJICoNCgkgKiBAc2VlICAgICBSZWdpc3RyeQ0KCSAqIEBzaW5jZSAgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UGFyYW1zKCRvcHRpb24gPSBudWxsKQ0KCXsNCgkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIGFuIG9wdGlvbg0KCQlpZiAoZW1wdHkoJG9wdGlvbikpDQoJCXsNCgkJCSRvcHRpb24gPSBzZWxmOjpnZXRPcHRpb24oKTsNCgkJfQ0KDQoJCS8vIGdldCBnbG9iYWwgdmFsdWUNCgkJaWYgKCFpc3NldChzZWxmOjokcGFyYW1zWyRvcHRpb25dKSB8fCAhc2VsZjo6JHBhcmFtc1skb3B0aW9uXSBpbnN0YW5jZW9mIFJlZ2lzdHJ5KQ0KCQl7DQoJCQlzZWxmOjokcGFyYW1zWyRvcHRpb25dID0gQ29tcG9uZW50SGVscGVyOjpnZXRQYXJhbXMoJG9wdGlvbik7DQoJCX0NCg0KCQlyZXR1cm4gc2VsZjo6JHBhcmFtc1skb3B0aW9uXTsNCgl9DQoNCgkvKioNCgkgKiBHZXRzIHRoZSBjb21wb25lbnQgb3B0aW9uDQoJICoNCgkgKiBAcGFyYW0gICBTdHJpbmd8Qm9vbCAgICAgICRkZWZhdWx0ICBUaGUgZGVmYXVsdCByZXR1cm4gdmFsdWUgaWYgbm9uZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgU3RyaW5nfEJvb2wgICAgICBBIGNvbXBvbmVudCBvcHRpb24NCgkgKg0KCSAqIEBzaW5jZSAgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0T3B0aW9uKCRkZWZhdWx0ID0gJ2VtcHR5JykNCgl7DQoJCWlmIChlbXB0eShzZWxmOjokb3B0aW9uKSkNCgkJew0KCQkJLy8gZ2V0IHRoZSBvcHRpb24gZnJvbSB0aGUgdXJsIGlucHV0DQoJCQlzZWxmOjokb3B0aW9uID0gKG5ldyBJbnB1dCktPmdldFN0cmluZygnb3B0aW9uJywgZmFsc2UpOw0KCQl9DQoNCgkJaWYgKHNlbGY6OiRvcHRpb24pDQoJCXsNCgkJCSByZXR1cm4gc2VsZjo6JG9wdGlvbjsNCgkJfQ0KDQoJCXJldHVybiAkZGVmYXVsdDsNCgl9DQoNCgkvKioNCgkgKiBHZXRzIHRoZSBjb21wb25lbnQgY29kZSBuYW1lDQoJICoNCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAgICAgICAgICRvcHRpb24gIFRoZSBvcHRpb24gZm9yIHRoZSBjb21wb25lbnQuDQoJICogQHBhcmFtICAgU3RyaW5nfEJvb2wgICAgICAkZGVmYXVsdCAgVGhlIGRlZmF1bHQgcmV0dXJuIHZhbHVlIGlmIG5vbmUgaXMgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIFN0cmluZ3xNaXhlZCAgICAgIEEgY29tcG9uZW50IGNvZGUgbmFtZQ0KCSAqDQoJICogQHNpbmNlICAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRDb2RlKCRvcHRpb24gPSBudWxsLCAkZGVmYXVsdCA9IG51bGwpDQoJew0KCQkvLyBjaGVjayB0aGF0IHdlIGhhdmUgYW4gb3B0aW9uDQoJCWlmIChlbXB0eSgkb3B0aW9uKSkNCgkJew0KCQkJJG9wdGlvbiA9IHNlbGY6OmdldE9wdGlvbigpOw0KCQl9DQoJCS8vIG9wdGlvbiB3aXRoIGNvbV8NCgkJaWYgKGlzX3N0cmluZygkb3B0aW9uKSAmJiBzdHJwb3MoJG9wdGlvbiwgJ2NvbV8nKSA9PT0gMCkNCgkJew0KCQkJcmV0dXJuIHN0cnRvbG93ZXIodHJpbShzdWJzdHIoJG9wdGlvbiwgNCkpKTsNCgkJfQ0KDQoJCXJldHVybiAkZGVmYXVsdDsNCgl9DQoNCgkvKioNCgkgKiBHZXRzIHRoZSBjb21wb25lbnQgYWJzdHJhY3QgaGVscGVyIGNsYXNzDQoJICoNCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAgICAgICAgICRvcHRpb24gIFRoZSBvcHRpb24gZm9yIHRoZSBjb21wb25lbnQuDQoJICogQHBhcmFtICAgU3RyaW5nfEJvb2wgICAgICAkZGVmYXVsdCAgVGhlIGRlZmF1bHQgcmV0dXJuIHZhbHVlIGlmIG5vbmUgaXMgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIFN0cmluZ3xNaXhlZCAgICAgIEEgY29tcG9uZW50IGhlbHBlciBuYW1lDQoJICoNCgkgKiBAc2luY2UgICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldCgkb3B0aW9uID0gbnVsbCwgJGRlZmF1bHQgPSBudWxsKQ0KCXsNCgkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIGFuIG9wdGlvbg0KCQkvLyBhbmQgZ2V0IHRoZSBjb2RlIG5hbWUgZnJvbSBpdA0KCQlpZiAoKCRjb2RlX25hbWUgPSBzZWxmOjpnZXRDb2RlKCRvcHRpb24sIGZhbHNlKSkgIT09IGZhbHNlKQ0KCQl7DQoJCQkvLyB3ZSBidWlsZCB0aGUgaGVscGVyIGNsYXNzIG5hbWUNCgkJCSRoZWxwZXJfbmFtZSA9ICdcXCcgLiBcdWNmaXJzdCgkY29kZV9uYW1lKSAuICdIZWxwZXInOw0KCQkJLy8gY2hlY2sgaWYgY2xhc3MgZXhpc3QNCgkJCWlmIChjbGFzc19leGlzdHMoJGhlbHBlcl9uYW1lKSkNCgkJCXsNCgkJCQlyZXR1cm4gJGhlbHBlcl9uYW1lOw0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuICRkZWZhdWx0Ow0KCX0NCg0KCS8qKg0KCSAqIENoZWNrIGlmIHRoZSBoZWxwZXIgY2xhc3Mgb2YgdGhpcyBjb21wb25lbnQgaGFzIGEgbWV0aG9kDQoJICoNCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAgJG1ldGhvZCAgVGhlIG1ldGhvZCBuYW1lIHRvIHNlYXJjaCBmb3INCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAgJG9wdGlvbiAgICBUaGUgb3B0aW9uIGZvciB0aGUgY29tcG9uZW50Lg0KCSAqDQoJICogQHJldHVybiAgYm9vbCAgICAgICAgICB0cnVlIGlmIG1ldGhvZCBleGlzdA0KCSAqDQoJICogQHNpbmNlICAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXRob2RFeGlzdHMoJG1ldGhvZCwgJG9wdGlvbiA9IG51bGwpDQoJew0KCQkvLyBnZXQgdGhlIGhlbHBlciBjbGFzcw0KCQlpZiAoKCRoZWxwZXIgPSBzZWxmOjpnZXQoJG9wdGlvbiwgZmFsc2UpKSAhPT0gZmFsc2UpDQoJCXsNCgkJCWlmIChtZXRob2RfZXhpc3RzKCRoZWxwZXIsICRtZXRob2QpKQ0KCQkJew0KCQkJCXJldHVybiB0cnVlOw0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg==', '{}', 'Helper', 'VDM\\Joomla\\Utilities.Component.Helper', '1.0.0', '{}', 'Utilities Component Helper', 'abstract class', '{}', '', 1, '2022-05-13 05:36:32', '2022-05-21 13:27:39', 17, 7), -(24, 1, 'Image helper\r\n\r\n@since 3.0.11', '', '', '962b15d8-915f-4cd7-aea6-7cf82afdc20b', 'dXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGaWxlOw0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGb2xkZXI7DQp1c2UgSm9vbWxhXENNU1xVcmlcVXJpOw0KdXNlIEpvb21sYVxDTVNcSW1hZ2VcSW1hZ2U7', '', '', '{\"load_selection0\":{\"load\":\"91004529-94a9-4590-b842-e7c6b624ecf5\"},\"load_selection1\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"}}', 'CS8qKg0KCSAqIFJlc2l6ZSBhbiBpbWFnZQ0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAgICRmdWxsUGF0aCAgIFRoZSBmdWxsIHBhdGggdG8gdGhlIGltYWdlDQoJICogQHBhcmFtICAgc3RyaW5nICAgICR0eXBlICAgICAgICBUaGUgdHlwZSBvZiBpbWFnZQ0KCSAqDQoJICogQHJldHVybiBib29sDQoJICogQHNpbmNlIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVzaXplKHN0cmluZyAkZnVsbFBhdGgsIHN0cmluZyAkdHlwZSkNCgl7DQoJCS8vIGZpcnN0IGNoZWNrIGlmIHdlIHNob3VsZCByZXNpemUgdGhpcyB0YXJnZXQNCgkJaWYgKDEgPT0gSGVscGVyOjpnZXRQYXJhbXMoKS0+Z2V0KCR0eXBlIC4gJ19yZXNpemUnLCAwKSkNCgkJew0KCQkJLy8gbG9hZCB0aGUgc2l6ZSB0byBiZSBzZXQNCgkJCSRoZWlnaHQgPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJHR5cGUgLiAnX2hlaWdodCcsICdub3Rfc2V0Jyk7DQoJCQkkd2lkdGggPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJHR5cGUgLiAnX3dpZHRoJywgJ25vdF9zZXQnKTsNCg0KCQkJLy8gR2V0IGZpbGUgZXh0ZW5zaW9uL2Zvcm1hdA0KCQkJJGZpbGVfZm9ybWF0ID0gTWltZUhlbHBlcjo6ZXh0ZW5zaW9uKCRmdWxsUGF0aCk7DQoNCgkJCS8vIGdldCBpbWFnZSBwcm9wZXJ0aWVzDQoJCQkkaW1hZ2UgPSBzZWxmOjpnZXRQcm9wZXJ0aWVzKCRmdWxsUGF0aCk7DQoNCgkJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIG9iamVjdA0KCQkJaWYgKE9iamVjdEhlbHBlcjo6Y2hlY2soJGltYWdlKSAmJiBpc19zdHJpbmcoJGZpbGVfZm9ybWF0KSkNCgkJCXsNCgkJCQlpZiAoJHdpZHRoICE9PSAnbm90X3NldCcgJiYgJGhlaWdodCAhPT0gJ25vdF9zZXQnICYmICgkaW1hZ2UtPndpZHRoICE9ICR3aWR0aCB8fCAkaW1hZ2UtPmhlaWdodCAhPSAkaGVpZ2h0KSkNCgkJCQl7DQoJCQkJCS8vIGlmIGltYWdlIGlzIGh1Z2UgYW5kIHNob3VsZCBvbmx5IGJlIHNjYWxlZCwgcmVzaXplIGl0IG9uIHRoZSBmbHkNCgkJCQkJaWYoKCRpbWFnZS0+d2lkdGggPiA5MDAgfHwgJGltYWdlLT5oZWlnaHQgPiA3MDApICYmICgkaGVpZ2h0ID09IDAgfHwgJHdpZHRoID09IDApKQ0KCQkJCQl7DQoJCQkJCQkvLyBzZWxlY3QgdGhlIGltYWdlICJnZXR0ZXIiIGJhc2VkIG9uIGZvcm1hdA0KCQkJCQkJaWYoJGZpbGVfZm9ybWF0ID09ICJqcGciIHx8ICRmaWxlX2Zvcm1hdCA9PSAianBlZyIgKQ0KCQkJCQkJew0KCQkJCQkJCSRzcmMgPSBpbWFnZWNyZWF0ZWZyb21qcGVnKCRmdWxsUGF0aCk7DQoJCQkJCQl9DQoJCQkJCQllbHNlaWYoJGZpbGVfZm9ybWF0ID09ICJwbmciKQ0KCQkJCQkJew0KCQkJCQkJCSRzcmMgPSBpbWFnZWNyZWF0ZWZyb21wbmcoJGZ1bGxQYXRoKTsNCgkJCQkJCX0NCgkJCQkJCWVsc2VpZigkZmlsZV9mb3JtYXQgPT0gImdpZiIpDQoJCQkJCQl7DQoJCQkJCQkJJHNyYyA9IGltYWdlY3JlYXRlZnJvbWdpZigkZnVsbFBhdGgpOw0KCQkJCQkJfQ0KCQkJCQkJLy8gd2Ugb25seSBzdXBwb3J0IHRoZSBhYm92ZSB0aHJlZSBmb3JtYXRzIGZvciBub3cNCgkJCQkJCWVsc2UNCgkJCQkJCXsNCgkJCQkJCQlyZXR1cm4gZmFsc2U7DQoJCQkJCQl9DQoNCgkJCQkJCS8vIHdvcmtvdXQgdGhlIHJhdGlvIGlmIHdlIGhhdmUgaGVpZ2h0DQoJCQkJCQlpZiAoJGhlaWdodCAhPSAwKQ0KCQkJCQkJew0KCQkJCQkJCSRoZWlnaHRfcmF0aW8gPSAkaW1hZ2UtPmhlaWdodCAvICRoZWlnaHQ7DQoJCQkJCQl9DQoNCgkJCQkJCS8vIHdvcmtvdXQgdGhlIHJhdGlvIGlmIHdlIGhhdmUgd2lkdGgNCgkJCQkJCWlmICgkd2lkdGggIT0gMCkNCgkJCQkJCXsNCgkJCQkJCQkkd2lkdGhfcmF0aW8gPSAkaW1hZ2UtPndpZHRoIC8gJHdpZHRoOw0KCQkJCQkJfQ0KDQoJCQkJCQkvLyBzZXQgbWF4IHJhdGlvIGJhc2VkIG9uIGJvdGgNCgkJCQkJCWlmIChpc3NldCgkaGVpZ2h0X3JhdGlvKSAmJiBpc3NldCgkd2lkdGhfcmF0aW8pKQ0KCQkJCQkJew0KCQkJCQkJCSRtYXhfcmF0aW8JPSBtYXgoJHdpZHRoX3JhdGlvLCAkaGVpZ2h0X3JhdGlvKTsNCgkJCQkJCX0NCgkJCQkJCS8vIHNldCBtYXggcmF0aW8gYmFzZWQgb24gd2lkdGgNCgkJCQkJCWVsc2VpZiAoaXNzZXQoJHdpZHRoX3JhdGlvKSkNCgkJCQkJCXsNCgkJCQkJCQkkbWF4X3JhdGlvCT0gJHdpZHRoX3JhdGlvOw0KCQkJCQkJfQ0KCQkJCQkJLy8gc2V0IG1heCByYXRpbyBiYXNlZCBvbiBoZWlnaHQNCgkJCQkJCWVsc2VpZiAoaXNzZXQoJGhlaWdodF9yYXRpbykpDQoJCQkJCQl7DQoJCQkJCQkJJG1heF9yYXRpbwk9ICRoZWlnaHRfcmF0aW87DQoJCQkJCQl9DQoNCgkJCQkJCS8vIGlmIHdlIGhhdmUgcmF0aW8gZG8gdGhlIGNvbnZlcnNpb24NCgkJCQkJCWlmICgkbWF4X3JhdGlvID4gMSkNCgkJCQkJCXsNCgkJCQkJCQkkbmV3X3dpZHRoCT0gJGltYWdlLT53aWR0aCAvICRtYXhfcmF0aW87DQoJCQkJCQkJJG5ld19oZWlnaHQJPSAkaW1hZ2UtPmhlaWdodCAvICRtYXhfcmF0aW87DQoJCQkJCQl9DQoJCQkJCQllbHNlDQoJCQkJCQl7DQoJCQkJCQkJJG5ld193aWR0aAk9ICRpbWFnZS0+d2lkdGg7DQoJCQkJCQkJJG5ld19oZWlnaHQJPSAkaW1hZ2UtPmhlaWdodDsNCgkJCQkJCX0NCg0KCQkJCQkJJHRtcAkJCT0gaW1hZ2VjcmVhdGV0cnVlY29sb3IoJG5ld193aWR0aCwgJG5ld19oZWlnaHQpOw0KCQkJCQkJJGJhY2tncm91bmRfY29sb3IJPSBpbWFnZWNvbG9yYWxsb2NhdGUoJHRtcCwgMjU1LCAyNTUsIDI1NSk7DQoNCgkJCQkJCWltYWdlZmlsbCgkdG1wLCAwLCAwLCAkYmFja2dyb3VuZF9jb2xvcik7DQoJCQkJCQlpbWFnZWNvcHlyZXNhbXBsZWQoJHRtcCwgJHNyYywgMCwgMCwgMCwgMCwkbmV3X3dpZHRoLCAkbmV3X2hlaWdodCwgJGltYWdlLT53aWR0aCwgJGltYWdlLT5oZWlnaHQpOw0KCQkJCQkJaW1hZ2VqcGVnKCR0bXAsICRmdWxsUGF0aCwgMTAwKTsNCgkJCQkJCWltYWdlZGVzdHJveSgkc3JjKTsNCgkJCQkJCWltYWdlZGVzdHJveSgkdG1wKTsNCgkJCQkJfQ0KCQkJCQkvLyB3ZSBvbmx5IGNyb3AgaWYgYm90aCBoZWlnaHQgYW5kIHdpZHRoIGlzIHNldCB0byBjcm9wDQoJCQkJCWlmICgkaGVpZ2h0ICE9IDAgJiYgJHdpZHRoICE9IDApDQoJCQkJCXsNCgkJCQkJCS8vIGdldCB0aGUgY3VycmVudCBjb21wb25lbnQgY29kZSBuYW1lDQoJCQkJCQlpZiAoKCRjb21wb25lbnRfY29kZV9uYW1lID0gSGVscGVyOjpnZXRDb2RlKG51bGwsIGZhbHNlKSkgPT09IGZhbHNlKQ0KCQkJCQkJew0KCQkJCQkJCS8vIGlmIHdlIGNhbid0IGdldCB0aGUgY29tcG9uZW50IGNvZGUgbmFtZSB3ZSBzaG91bGQgYnJlYWsgcHV0IG5vdw0KCQkJCQkJCXJldHVybiBmYWxzZTsNCgkJCQkJCX0NCgkJCQkJCS8vIEluY2x1ZGUgd2lkZWltYWdlIC0gaHR0cDovL3dpZGVpbWFnZS5zb3VyY2Vmb3JnZS5uZXQgVE9ETzogaHR0cHM6Ly9naXRodWIuY29tL3Ntb3R0dC9XaWRlSW1hZ2UNCgkJCQkJCXJlcXVpcmVfb25jZShKUEFUSF9BRE1JTklTVFJBVE9SIC4gJy9jb21wb25lbnRzL2NvbV8nIC4gJGNvbXBvbmVudF9jb2RlX25hbWUgLiAnL2hlbHBlcnMvd2lkZWltYWdlL1dpZGVJbWFnZS5waHAnKTsNCgkJCQkJCS8vIGxvYWQgdGhlIGltYWdlIGludG8gdGhlIGJ1aWxkZXINCgkJCQkJCSRidWlsZGVyID0gXFdpZGVJbWFnZTo6bG9hZCgkZnVsbFBhdGgpOw0KCQkJCQkJLy8gcmVzaXplIHRoZSBpbWFnZQ0KCQkJCQkJJHJlc2l6ZWQgPSAkYnVpbGRlci0+cmVzaXplKCR3aWR0aCwgJGhlaWdodCwgJ291dHNpZGUnKS0+Y3JvcCgnY2VudGVyJywgJ21pZGRsZScsICR3aWR0aCwgJGhlaWdodCk7DQoJCQkJCQkvLyBzYXZlIHRoZSBuZXcgaW1hZ2UgdG8gZnVsbCBmaWxlIHBhdGgNCgkJCQkJCSRyZXNpemVkLT5zYXZlVG9GaWxlKCRmdWxsUGF0aCk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIEdldCBJbWFnZSBQcm9wZXJ0aWVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgJGZ1bGxQYXRoICAgVGhlIGZ1bGwgcGF0aCB0byB0aGUgaW1hZ2UNCgkgKg0KCSAqIEByZXR1cm4gYm9vbHxzdGRDbGFzcw0KCSAqIEBzaW5jZSAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFByb3BlcnRpZXMoJGZ1bGxQYXRoKQ0KCXsNCgkJLy8gY2hlY2sgdGhhdCB0aGUgZmlsZSBleGlzdA0KCQlpZiAoRmlsZTo6ZXhpc3RzKCRmdWxsUGF0aCkpDQoJCXsNCgkJCSRwcm9wZXJ0aWVzID0gSW1hZ2U6OmdldEltYWdlRmlsZVByb3BlcnRpZXMoJGZ1bGxQYXRoKTsNCgkJCS8vIGNoZWNrIGlmIHdlIGhhdmUgcHJvcGVydGllcw0KCQkJaWYgKE9iamVjdEhlbHBlcjo6Y2hlY2soJHByb3BlcnRpZXMpKQ0KCQkJew0KCQkJCS8vIGdldCBpbWFnZSBmaWxlIG5hbWUNCgkJCQkkbmFtZSA9IGJhc2VuYW1lKCRmdWxsUGF0aCk7DQoJCQkJLy8gcmVtb3ZlIGZpbGUgbmFtZSBmcm9tIHBhdGgNCgkJCQkkZGlyX25hbWUgPSBwYXRoaW5mbygkZnVsbFBhdGgsIFBBVEhJTkZPX0RJUk5BTUUpOw0KCQkJCS8vIHJlbW92ZSB0aGUgc2VydmVyIHBhdGgNCgkJCQkkaW1hZ2VfcHVibGljX3BhdGggPSB0cmltKHN0cl9yZXBsYWNlKEpQQVRIX1NJVEUsICcnLCAkZGlyX25hbWUpLCAnLycpIC4gJy8nIC4gJG5hbWU7DQoJCQkJLy8gbm93IGFkZCB0aGUgc3JjIHBhdGggdG8gc2hvdyB0aGUgaW1hZ2UNCgkJCQkkcHJvcGVydGllcy0+c3JjID0gVXJpOjpyb290KCkgLiAkaW1hZ2VfcHVibGljX3BhdGg7DQoJCQkJLy8gcmV0dXJuIHRoZSBpbWFnZSBwcm9wZXJ0aWVzDQoJCQkJcmV0dXJuICRwcm9wZXJ0aWVzOw0KCQkJfQ0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQo=', '{}', 'ImageHelper', 'VDM\\Joomla\\Utilities.ImageHelper', '1.0.0', '{}', 'Utilities ImageHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-05-16 10:59:17', '2022-05-21 13:27:39', 17, 9), -(25, 1, 'Upload Helper\r\n\r\n@since 3.0.11', '', '', 'd7600b43-771a-4747-9f5d-952765721799', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTsNCnVzZSBKb29tbGFcQ01TXExhbmd1YWdlXFRleHQ7DQp1c2UgSm9vbWxhXENNU1xGaWxlc3lzdGVtXEZpbGU7DQp1c2UgSm9vbWxhXENNU1xGaWxlc3lzdGVtXEZvbGRlcjsNCnVzZSBKb29tbGFcQ01TXEZpbGVzeXN0ZW1cUGF0aDs=', '', '', '{\"load_selection0\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIFRydWUgdG8gdXNlIHN0cmVhbXMNCgkgKg0KCSAqIEB2YXIgICAgYm9vbA0KCSAqDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljICR1c2VTdHJlYW1zID0gZmFsc2U7DQoNCgkvKioNCgkgKiBBbGxvdyB0aGUgdXBsb2FkIG9mIHVuc2FmZSBmaWxlcw0KCSAqDQoJICogQHZhciAgICBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJGFsbG93VW5zYWZlID0gZmFsc2U7DQoNCgkvKioNCgkgKiBPcHRpb25zIHRvIElucHV0RmlsdGVyOjppc1NhZmVGaWxlDQoJICoNCgkgKiBAdmFyICAgIGFycmF5DQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJHNhZmVGaWxlT3B0aW9ucyA9IGFycmF5KCk7DQoNCgkvKioNCgkgKiBTZXQgdGhlIGVycm9yIGJlaGF2aW9yDQoJICoNCgkgKiBAdmFyICAgIGJvb2wNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyAkZW5xdWV1ZUVycm9yID0gdHJ1ZTsNCg0KCS8qKg0KCSAqIEVycm9ycw0KCSAqDQoJICogQHZhciAgICBhcnJheQ0KCSAqDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRlcnJvcnMgPSBhcnJheSgpOw0KDQoJLyoqDQoJICogR2V0IGZpbGUvZmlsZXMgZnJvbSBhIEhUVFAgdXBsb2FkLg0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJGZpZWxkICAgICAgICBUaGUgaW5wdXQgZmllbGQgbmFtZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICR0eXBlICAgICAgICBUaGUgZmlsZSB0eXBlDQoJICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICRmaWx0ZXIgICAgICAgIFRoZSBmaWx0ZXIgdG8gdXNlIHdoZW4gdXBsb2FkaW5nIHRoZSBmaWxlDQoJICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICRwYXRoICAgICAgICBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBpbWFnZSBtdXN0IGJlIHBsYWNlZA0KCSAqDQoJICogQHJldHVybiAgbWl4ZWQgICBGaWxlIGRldGFpbHMgb3IgZmFsc2Ugb24gZmFpbHVyZS4NCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0KHN0cmluZyAkZmllbGQsIHN0cmluZyAkdHlwZSwgc3RyaW5nICRmaWx0ZXIgPSBudWxsLCBzdHJpbmcgJHBhdGggPSBudWxsKQ0KCXsNCgkJLy8gR2V0IHRoZSB1cGxvYWRlZCBmaWxlIGluZm9ybWF0aW9uLg0KCQkkaW5wdXQgICAgPSBGYWN0b3J5OjpnZXRBcHBsaWNhdGlvbigpLT5pbnB1dDsNCg0KCQkvLyBzZXQgdGhlIGRlZmF1bHQgZmlsdGVyDQoJCWlmIChlbXB0eSgkZmlsdGVyKSkNCgkJew0KCQkJJGZpbHRlciA9ICdhcnJheSc7DQoJCX0NCgkJLy8gaWYgcmF3IHRoZW4gYWxzbyB1bnNhZmUNCgkJLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vam9vbWxhL2pvb21sYS1jbXMvYmxvYi80LjEtZGV2L2FkbWluaXN0cmF0b3IvY29tcG9uZW50cy9jb21faW5zdGFsbGVyL3NyYy9Nb2RlbC9JbnN0YWxsTW9kZWwucGhwI0wyNTkNCgkJZWxzZWlmICgkZmlsdGVyID09PSAncmF3JykNCgkJew0KCQkJc2VsZjo6JGFsbG93VW5zYWZlID0gdHJ1ZTsNCgkJfQ0KDQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYSBmaWxlIGRlc3RpbmF0aW9uIG5hbWUgaW4gdGhlIGZpZWxkIG5hbWUNCgkJJG5hbWUgPSBudWxsOw0KCQlpZiAoc3RycG9zKCRmaWVsZCwgJzonKSAhPT0gZmFsc2UpDQoJCXsNCgkJCWxpc3QoJGZpZWxkLCAkbmFtZSkgPSBleHBsb2RlKCc6JywgJGZpZWxkKTsNCgkJfQ0KDQoJCS8vIFNlZSBKSW5wdXRGaWxlczo6Z2V0Lg0KCQkkdXNlcmZpbGUgPSAkaW5wdXQtPmZpbGVzLT5nZXQoJGZpZWxkLCBudWxsLCAkZmlsdGVyKTsNCg0KCQkvLyBNYWtlIHN1cmUgdGhhdCBmaWxlIHVwbG9hZHMgYXJlIGVuYWJsZWQgaW4gcGhwLg0KCQlpZiAoIShib29sKSBpbmlfZ2V0KCdmaWxlX3VwbG9hZHMnKSkNCgkJew0KCQkJc2VsZjo6c2V0RXJyb3IoVGV4dDo6XygnV2FybmluZywgdXBsb2FkIGVycm9yLicpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJLy8gSWYgdGhlcmUgaXMgbm8gdXBsb2FkZWQgZmlsZSwgd2UgaGF2ZSBhIHByb2JsZW0uLi4NCgkJaWYgKCFpc19hcnJheSgkdXNlcmZpbGUpKQ0KCQl7DQoJCQlzZWxmOjpzZXRFcnJvcihUZXh0OjpfKCdObyB1cGxvYWQgc2VsZWN0ZWQnKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIElzIHRoZSBQSFAgdG1wIGRpcmVjdG9yeSBtaXNzaW5nPw0KCQlpZiAoJHVzZXJmaWxlWydlcnJvciddICYmICgkdXNlcmZpbGVbJ2Vycm9yJ10gPT0gVVBMT0FEX0VSUl9OT19UTVBfRElSKSkNCgkJew0KCQkJc2VsZjo6c2V0RXJyb3IoVGV4dDo6XygnVGhlcmUgd2FzIGFuIGVycm9yIHVwbG9hZGluZyB0byB0aGUgc2VydmVyLicpIC4gJzxicj4nIC4gVGV4dDo6XygnVGhlIFBIUCB0ZW1wb3JhcnkgZm9sZGVyIGlzIG5vdCBzZXQuJykpOw0KDQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCg0KCQkvLyBJcyB0aGUgbWF4IHVwbG9hZCBzaXplIHRvbyBzbWFsbCBpbiBwaHAuaW5pPw0KCQlpZiAoJHVzZXJmaWxlWydlcnJvciddICYmICgkdXNlcmZpbGVbJ2Vycm9yJ10gPT0gVVBMT0FEX0VSUl9JTklfU0laRSkpDQoJCXsNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ1RoZXJlIHdhcyBhbiBlcnJvciB1cGxvYWRpbmcgdG8gdGhlIHNlcnZlci4nKSAuICc8YnI+JyAuIFRleHQ6Ol8oJ1lvdXIgZmlsZSB3YXMgaXMgbGFyZ2VyIHRoYW4gdGhlIGFsbG93ZWQgc2l6ZS4nKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIENoZWNrIGlmIHRoZXJlIHdhcyBhIGRpZmZlcmVudCBwcm9ibGVtIHVwbG9hZGluZyB0aGUgZmlsZS4NCgkJaWYgKCR1c2VyZmlsZVsnZXJyb3InXSB8fCAkdXNlcmZpbGVbJ3NpemUnXSA8IDEpDQoJCXsNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ1RoZXJlIHdhcyBhbiBlcnJvciB1cGxvYWRpbmcgdG8gdGhlIHNlcnZlci4nKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIGNoZWNrIGlmIGEgcGF0aCB3YXMgcGFzc2VkIGFuZCBleGlzdA0KCQlpZiAoaXNfc3RyaW5nKCRwYXRoKSAmJiBGb2xkZXI6OmNyZWF0ZSgkcGF0aCkpDQoJCXsNCgkJCS8vIHNldCB0aGUgcGF0aA0KCQkJJHVzZXJmaWxlWydwYXRoJ10gPSAkcGF0aDsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8vIGdldCB0aGUgSm9vbWxhIGNvbmZpZyBjbGFzcw0KCQkJJGNvbmZpZyA9IEZhY3Rvcnk6OmdldENvbmZpZygpOw0KCQkJLy8gc2V0IHRoZSBwYXRoDQoJCQkkdXNlcmZpbGVbJ3BhdGgnXSA9ICRjb25maWctPmdldCgndG1wX3BhdGgnKTsNCgkJfQ0KDQoJCS8vIHNldCB0aGUgcmFuZG9tIHBhcnQgb2YgdGhlIG5hbWUNCgkJJHVzZXJmaWxlWydyYW5kb20nXSA9IFN0cmluZ0hlbHBlcjo6cmFuZG9tKDEyKTsNCg0KCQkvLyBzZXQgdGhlIGZpbGUgbmFtZQ0KCQlpZiAoZW1wdHkoJG5hbWUpKQ0KCQl7DQoJCQkvLyBzZXQgdGhlIGZpbGUgbmFtZQ0KCQkJJHVzZXJmaWxlWydmaWxlX25hbWUnXSA9ICR1c2VyZmlsZVsncmFuZG9tJ10gLiAkdXNlcmZpbGVbJ25hbWUnXTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8vIGNoZWNrIHRoYXQgaGlzIG5hbWUgaGFzIGZpbGUgZm9ybWF0DQoJCQlpZiAoaXNfc3RyaW5nKCRuYW1lKSAmJiBzdHJwb3MoJG5hbWUsICcuJykgPT09IGZhbHNlKQ0KCQkJew0KCQkJCSRuYW1lID0gJG5hbWUgLiAnLicgLiBNaW1lSGVscGVyOjpleHRlbnNpb24obnVsbCwgJHVzZXJmaWxlWyd0eXBlJ10pOw0KCQkJfQ0KCQkJJHVzZXJmaWxlWydmaWxlX25hbWUnXSA9ICRuYW1lOw0KCQl9DQoNCgkJLy8gc2V0IGZ1bGwgcGF0aA0KCQkkdXNlcmZpbGVbJ2Z1bGxfcGF0aCddID0gJHVzZXJmaWxlWydwYXRoJ10gLiAnLycgLiAkdXNlcmZpbGVbJ2ZpbGVfbmFtZSddOw0KDQoJCS8vIFVwbG9hZCB0aGUgZmlsZS4NCgkJaWYgKEZpbGU6OnVwbG9hZCgkdXNlcmZpbGVbJ3RtcF9uYW1lJ10sICR1c2VyZmlsZVsnZnVsbF9wYXRoJ10sIHNlbGY6OiR1c2VTdHJlYW1zLCBzZWxmOjokYWxsb3dVbnNhZmUpKQ0KCQl7DQoJCQkvLyBDaGVjayB0aGF0IHRoaXMgaXMgYSB2YWxpZCBmaWxlDQoJCQlyZXR1cm4gc2VsZjo6Y2hlY2soJHVzZXJmaWxlLCAkdHlwZSk7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIEdldCB0aGUgZXJyb3JzDQoJICoNCgkgKiBAcGFyYW0gIGJvb2wgICAgICAgICAkdG9TdHJpbmcgICAgICBUaGUgb3B0aW9uIHRvIHJldHVybiBlcnJvcnMgYXMgYSBzdHJpbmcNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5DQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEVycm9yKCR0b1N0cmluZyA9IGZhbHNlKQ0KCXsNCgkJaWYgKCR0b1N0cmluZykNCgkJew0KCQkJcmV0dXJuIGltcGxvZGUoJyAnIC4gUEhQX0VPTCwgc2VsZjo6JGVycm9ycyk7DQoJCX0NCgkJcmV0dXJuIHNlbGY6OiRlcnJvcnM7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgYSBmaWxlIGFuZCB2ZXJpZmllcyBpdCBhcyBhIGFsbG93ZWQgZmlsZSBmb3JtYXQgZmlsZQ0KCSAqDQoJICogQHBhcmFtICBhcnJheSAgICAgICAgICR1cGxvYWQgICAgICBUaGUgdXBsb2FkZWQgZGV0YWlscyBhcnJheQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkdHlwZSAgICAgICAgICBUaGUgZmlsZSB0eXBlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheSAgb2YgZWxlbWVudHMNCgkgKg0KCSAqLw0KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gY2hlY2soYXJyYXkgJHVwbG9hZCwgc3RyaW5nICR0eXBlKQ0KCXsNCgkJLy8gRGVmYXVsdCBmb3JtYXRzDQoJCSRmb3JtYXRzID0gTWltZUhlbHBlcjo6ZXh0ZW5zaW9ucygkdHlwZSk7DQoNCgkJLy8gQ2xlYW4gdGhlIHBhdGgNCgkJJHVwbG9hZF9wYXRoID0gUGF0aDo6Y2xlYW4oJHVwbG9hZFsnZnVsbF9wYXRoJ10pOw0KDQoJCS8vIEdldCBmaWxlIGV4dGVuc2lvbi9mb3JtYXQNCgkJJGZvcm1hdCA9IE1pbWVIZWxwZXI6OmV4dGVuc2lvbigkdXBsb2FkX3BhdGgpOw0KDQoJCS8vIExlZ2FsIGZpbGUgZm9ybWF0cw0KCQkkbGVnYWwgPSBhcnJheSgpOw0KDQoJCS8vIGNoZWNrIGlmIHRoZSBmaWxlIGZvcm1hdCBpcyBldmVuIGluIHRoZSBsaXN0DQoJCWlmIChpbl9hcnJheSgkZm9ybWF0LCAkZm9ybWF0cykpDQoJCXsNCgkJCS8vIGdldCBhbGxvd2VkIGZvcm1hdHMNCgkJCSRsZWdhbCA9IChhcnJheSkgSGVscGVyOjpnZXRQYXJhbXMoKS0+Z2V0KCR0eXBlIC4gJ19mb3JtYXRzJywgYXJyYXkoKSk7DQoJCX0NCg0KCQkvLyBjaGVjayB0aGUgZXh0ZW5zaW9uDQoJCWlmICghaW5fYXJyYXkoJGZvcm1hdCwgJGxlZ2FsKSkNCgkJew0KCQkJLy8gQ2xlYW51cCB0aGUgaW1wb3J0IGZpbGUNCgkJCXNlbGY6OnJlbW92ZSgkdXBsb2FkWydmdWxsX3BhdGgnXSk7DQoNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ1VwbG9hZCBpcyBub3QgYSB2YWxpZCB0eXBlLicpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJcmV0dXJuICR1cGxvYWQ7DQoJfQ0KDQoJLyoqDQoJICogQ2xlYW4gdXAgdGVtcG9yYXJ5IHVwbG9hZGVkIGZpbGUNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGZ1bGxQYXRoICAgIFRoZSBmdWxsIHBhdGggb2YgdGhlIHVwbG9hZGVkIGZpbGUNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2xlYW4gIFRydWUgb24gc3VjY2Vzcw0KCSAqDQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiByZW1vdmUoJGZ1bGxQYXRoKQ0KCXsNCgkJLy8gSXMgdGhlIHBhY2thZ2UgZmlsZSBhIHZhbGlkIGZpbGU/DQoJCWlmIChpc19maWxlKCRmdWxsUGF0aCkpDQoJCXsNCgkJCUZpbGU6OmRlbGV0ZSgkZnVsbFBhdGgpOw0KCQl9DQoJCWVsc2VpZiAoaXNfZmlsZShQYXRoOjpjbGVhbigkZnVsbFBhdGgpKSkNCgkJew0KCQkJLy8gSXQgbWlnaHQgYWxzbyBiZSBqdXN0IGEgYmFzZSBmaWxlbmFtZQ0KCQkJRmlsZTo6ZGVsZXRlKFBhdGg6OmNsZWFuKCRmdWxsUGF0aCkpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogU2V0IHRoZSBlcnJvcnMNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkbWVzc2FnZSAgIFRoZSBlcnJvciBtZXNzYWdlDQoJICoNCgkgKiBAcmV0dXJuICB2b2lkDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHNldEVycm9yKCRtZXNzYWdlKQ0KCXsNCgkJaWYgKHNlbGY6OiRlbnF1ZXVlRXJyb3IpDQoJCXsNCgkJCUZhY3Rvcnk6OmdldEFwcGxpY2F0aW9uKCktPmVucXVldWVNZXNzYWdlKCRtZXNzYWdlLCAnZXJyb3InKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXNlbGY6OiRlcnJvcnNbXSA9ICRtZXNzYWdlOw0KCQl9DQoJfQ==', '{}', 'UploadHelper', 'VDM\\Joomla\\Utilities.UploadHelper', '1.0.0', '{}', 'Utilities UploadHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-05-16 13:20:50', '2022-05-21 13:27:39', 31, 9), -(26, '', 'Mime Helper\r\n\r\n@since 3.0.11', '', '', 'f11dc790-713e-4706-9a85-a318ed3ad56e', '', '', '', '{}', 'W0VYVEVSTkFMQ09ERT1odHRwczovL2dpc3QuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0xsZXdlbGx5bnZkbS83NGJlMzczMzU3ZTEzMWI4Nzc1YTc1ODJjM2RlNTA4Yi9yYXcvbWltZV90eXBlcy5waHBdDQoNCltFWFRFUk5BTENPREU9aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9MbGV3ZWxseW52ZG0vNzRiZTM3MzM1N2UxMzFiODc3NWE3NTgyYzNkZTUwOGIvcmF3L2dldC5waHBdDQoNCltFWFRFUk5BTENPREU9aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9MbGV3ZWxseW52ZG0vNzRiZTM3MzM1N2UxMzFiODc3NWE3NTgyYzNkZTUwOGIvcmF3L2V4dGVuc2lvbnMucGhwXQ==', '{}', 'MimeHelper', 'VDM\\Joomla\\Utilities.MimeHelper', '1.0.0', '{}', 'Utilities MimeHelper', 'abstract class', '{}', '', 1, '2022-05-16 14:27:38', '2022-05-21 13:27:39', 3, 9), -(27, '', 'Just to link powers to the power updater component', '', '', '8025e71c-8e21-44cb-b23e-dce2fb5a1ab5', '', '', '', '{\"load_selection0\":{\"load\":\"db4a1e4d-be59-4e87-8b4d-c40512752232\"},\"load_selection1\":{\"load\":\"79d765b3-7319-4988-9730-446c7f347020\"},\"load_selection2\":{\"load\":\"d7600b43-771a-4747-9f5d-952765721799\"},\"load_selection3\":{\"load\":\"962b15d8-915f-4cd7-aea6-7cf82afdc20b\"},\"load_selection4\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"}}', '', '{}', 'Updater', 'VDM\\Powe\\Updater', '1.0.0', '{}', 'Power Updater', 'class', '{}', '', 1, '2022-05-21 13:15:55', '2022-06-11 16:54:51', 3, 13), -(28, 1, 'Start looking here:\r\nhttps://git.vdm.dev/api/swagger#/repository/repoGetContents', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', '', 'ef011ee1-64f0-4048-b013-777473b727dd', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIEdldHMgdGhlIG1ldGFkYXRhIGFuZCBjb250ZW50cyAoaWYgYSBmaWxlKSBvZiBhbiBlbnRyeSBpbiBhIHJlcG9zaXRvcnksIG9yIGEgbGlzdCBvZiBlbnRyaWVzIGlmIGEgZGlyDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRvd25lciAgICAgICBSZXBvc2l0b3J5IG93bmVyLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHJlcG8gICAgICAgICBSZXBvc2l0b3J5IG5hbWUuDQoJICogQHBhcmFtICAgc3RyaW5nICAkZmlsZXBhdGggICAgUmVwb3NpdG9yeSBmaWxlIHBhdGguDQoJICoNCgkgKiBAcmV0dXJuICBvYmplY3QNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXQoJG93bmVyLCAkcmVwbywgJGZpbGVwYXRoKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHBhdGggPSAnL3JlcG9zLycgLiAkb3duZXIgLiAnLycgLiAkcmVwbyAuICcvY29udGVudHMvJyAuICRmaWxlcGF0aDsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPmdldCgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpKQ0KCQkpOw0KCX0NCg==', '{}', 'File', 'VDM\\Gitea\\Package.Repo.File', '1.0.0', '{}', 'Gitea Repo File', 'class', '{}', '', 1, '2022-05-21 13:40:09', '2022-07-09 10:28:20', 10, 4), -(29, 1, 'Start looking here:\r\nhttps://git.vdm.dev/api/swagger#/repository/repoCreateWikiPage', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', '', 'c4a188de-ad78-4a6d-9d5b-01866846d701', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIEdldCBhIHJlcG9zaXRvcnkgd2lraSBwYWdlDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRvd25lciAgICAgICAgICAgICAgIFRoZSByZXBvc2l0b3J5IG93bmVyDQoJICogQHBhcmFtICAgc3RyaW5nICAkcmVwbyAgICAgICAgICAgICAgICAgVGhlIHJlcG9zaXRvcnkgbmFtZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHBhZ2VOYW1lICAgICAgIFRoZSBwYWdlIG5hbWUNCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldChzdHJpbmcgJG93bmVyLCBzdHJpbmcgJHJlcG8sIHN0cmluZyAkcGFnZU5hbWUpDQoJew0KCQkvLyBCdWlsZCB0aGUgcmVxdWVzdCBwYXRoLg0KCQkkcGF0aCA9ICcvcmVwb3MvJyAuICRvd25lciAuICcvJyAuICRyZXBvIC4gJy93aWtpL3BhZ2UvJyAuICRwYWdlTmFtZTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPmdldCgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpKQ0KCQkpOw0KCX0NCg0KCS8qKg0KCSAqIEdldCBhIHJlcG9zaXRvcnkgd2lraSBodG1sIHBhZ2UNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG93bmVyICAgICAgICAgICAgICAgVGhlIHJlcG9zaXRvcnkgb3duZXINCgkgKiBAcGFyYW0gICBzdHJpbmcgICRyZXBvICAgICAgICAgICAgICAgICBUaGUgcmVwb3NpdG9yeSBuYW1lDQoJICogQHBhcmFtICAgc3RyaW5nICAkcGFnZU5hbWUgICAgICAgVGhlIHBhZ2UgbmFtZQ0KCSAqDQoJICogQHJldHVybiAgb2JqZWN0DQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0SHRtbChzdHJpbmcgJG93bmVyLCBzdHJpbmcgJHJlcG8sIHN0cmluZyAkcGFnZU5hbWUpDQoJew0KCQkvLyBnZXQgdGhlIGdpdGVhIHdpa2kgcGFnZQ0KCQkkcGFnZSA9ICR0aGlzLT5nZXQoJG93bmVyLCAkcmVwbywgJHBhZ2VOYW1lKTsNCg0KCQlpZiAoZW1wdHkoJHBhZ2UtPmNvbnRlbnQpKQ0KCQl7DQoJCQl0aHJvdyBuZXcgXEV4Y2VwdGlvbignV2lraSBwYWdlIGNvdWxkIG5vdCBiZSBmb3VuZC4nKTsNCgkJfQ0KDQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSRwYXRoID0gJy9tYXJrZG93bic7DQoNCgkJLy8gR2V0IGhlYWRlcnMNCgkJJGhlYWRlcnMgPSAkdGhpcy0+Y2xpZW50LT5nZXRPcHRpb24oJ2hlYWRlcnMnLCBhcnJheSgpKTsNCg0KCQkkaGVhZGVyc1snYWNjZXB0J10gPSAndGV4dC9odG1sJzsNCgkJJGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gJ2FwcGxpY2F0aW9uL2pzb24nOw0KDQoJCS8vIGJ1aWxkIHRoZSBwb3N0IGJvZHkNCgkJJGRhdGEgPSBbDQoJCQknQ29udGV4dCcgPT4gJ3N0cmluZycsDQoJCQknTW9kZScgPT4gJ3N0cmluZycsDQoJCQknVGV4dCcgPT4gJHBhZ2UtPmNvbnRlbnQsDQoJCQknV2lraScgPT4gdHJ1ZQ0KCQldOw0KDQoJCS8vIFBvc3QgdGhlIHJlcXVlc3QuDQoJCXJldHVybiAkdGhpcy0+cHJvY2Vzc1Jlc3BvbnNlKA0KCQkJJHRoaXMtPmNsaWVudC0+cG9zdCgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpLCBqc29uX2VuY29kZSgkZGF0YSksICRoZWFkZXJzKQ0KCQkpOw0KCX0NCg==', '{}', 'Wiki', 'VDM\\Gitea\\Package.Repo.Wiki', '1.0.0', '{}', 'Gitea Repo Wiki', 'class', '{}', '', 1, '2022-07-09 10:21:53', '2022-07-09 12:18:07', 9, 4); - -- -- Dumping data for table `#__componentbuilder_admin_view` -- @@ -2004,19 +1981,13 @@ INSERT INTO `#__componentbuilder_power` (`id`, `add_head`, `description`, `exten INSERT INTO `#__componentbuilder_admin_view` (`id`, `add_css_view`, `add_css_views`, `add_custom_button`, `add_custom_import`, `add_fadein`, `add_javascript_view_file`, `add_javascript_view_footer`, `add_javascript_views_file`, `add_javascript_views_footer`, `add_php_ajax`, `add_php_allowedit`, `add_php_batchcopy`, `add_php_batchmove`, `add_php_getitem`, `add_php_getitems`, `add_php_getitems_after_all`, `add_php_getlistquery`, `add_php_postsavehook`, `add_php_save`, `add_sql`, `addlinked_views`, `addpermissions`, `addtables`, `addtabs`, `add_php_before_delete`, `add_php_before_publish`, `add_php_document`, `add_php_after_delete`, `add_php_after_publish`, `php_before_delete`, `php_before_publish`, `php_controller`, `php_document`, `php_after_delete`, `php_after_publish`, `ajax_input`, `css_view`, `css_views`, `custom_button`, `description`, `html_import_view`, `icon`, `icon_add`, `icon_category`, `javascript_view_file`, `javascript_view_footer`, `javascript_views_file`, `javascript_views_footer`, `name_list`, `system_name`, `name_single`, `php_ajaxmethod`, `php_allowedit`, `php_batchcopy`, `php_batchmove`, `php_getitem`, `php_getitems`, `php_getitems_after_all`, `php_getlistquery`, `php_import`, `php_import_display`, `php_import_save`, `php_import_setdata`, `php_model`, `php_postsavehook`, `php_save`, `short_description`, `source`, `sql`, `type`, `params`, `published`, `created`, `modified`, `version`, `hits`, `ordering`, `guid`) VALUES (109, '', '', '', '', 1, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '{}', '{\"addpermissions0\":{\"action\":\"view.edit\",\"implementation\":3},\"addpermissions1\":{\"action\":\"view.edit.own\",\"implementation\":3},\"addpermissions2\":{\"action\":\"view.edit.state\",\"implementation\":3},\"addpermissions3\":{\"action\":\"view.edit.created_by\",\"implementation\":3},\"addpermissions4\":{\"action\":\"view.edit.created\",\"implementation\":3},\"addpermissions5\":{\"action\":\"view.create\",\"implementation\":3},\"addpermissions6\":{\"action\":\"view.delete\",\"implementation\":3},\"addpermissions7\":{\"action\":\"view.access\",\"implementation\":3}}', '{}', '{\"addtabs0\":{\"name\":\"Details\"},\"addtabs1\":{\"name\":\"More\"}}', '', '', '', '', '', '', '', '', '', '', '', '{}', '', '', '{}', '', '', 'images/WoodMannequin-icon.png', 'images/WoodMannequin-icon-plus.png', '', '', '', '', '', 'Looks', 'Look', 'Look', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'The demo view', '', '', 1, '{\"fieldordering\":{\"add_admin_ordering\":\"0\",\"admin_ordering_fields\":{\"admin_ordering_fields0\":{\"field\":\"\",\"direction\":\"ASC\"}},\"add_linked_ordering\":\"0\",\"linked_ordering_fields\":{\"linked_ordering_fields0\":{\"field\":\"\",\"direction\":\"ASC\"}}},\"privacy\":{\"activate\":\"1\",\"permissions\":\"1\",\"anonymize\":\"0\",\"anonymize_fields\":[],\"user_link\":\"1\",\"custom_link\":\"$query->where($db->quoteName(\'created_by\') . \' = \' . $db->quote($user->id));\",\"other_user_field\":\"682\"}}', 1, '2016-10-18 11:44:46', '2020-05-21 14:39:27', 18, '', 110, 'c1053952-8a84-4398-aef1-41726f7c0043'); - - -- -- Dumping data for table `#__componentbuilder_site_view` -- INSERT INTO `#__componentbuilder_site_view` (`id`, `add_css_document`, `add_css`, `add_js_document`, `add_php_document`, `add_php_jview`, `add_php_jview_display`, `add_php_view`, `add_php_ajax`, `add_custom_button`, `custom_button`, `button_position`, `php_controller`, `php_model`, `ajax_input`, `php_ajaxmethod`, `codename`, `css_document`, `css`, `custom_get`, `default`, `description`, `dynamic_get`, `js_document`, `main_get`, `name`, `system_name`, `php_document`, `php_jview`, `php_jview_display`, `php_view`, `snippet`, `params`, `published`, `created`, `modified`, `version`, `hits`, `ordering`, `guid`) VALUES (23, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'looks', '', '', '', 'PHRhYmxlIGNsYXNzPSJ1ay10YWJsZSB1ay10YWJsZS1ob3ZlciI+DQogICAgPGNhcHRpb24+PD9waHAgZWNobyBKVGV4dDo6XygnTGlzdCBvZiBhbGwgbG9va3MnKTsgPz48L2NhcHRpb24+DQogICAgPHRoZWFkPg0KICAgICAgICA8dHI+DQogICAgICAgICAgICA8dGg+PD9waHAgZWNobyBKVGV4dDo6XygnTmFtZScpOyA/PjwvdGg+DQogICAgICAgICAgICA8dGg+PD9waHAgZWNobyBKVGV4dDo6XygnRGVzY3JpcHRpb24nKTsgPz48L3RoPg0KICAgICAgICA8L3RyPg0KICAgIDwvdGhlYWQ+DQogICAgPHRib2R5Pg0KICAgICAgICA8P3BocCBmb3JlYWNoICgkdGhpcy0+aXRlbXMgYXMgJGl0ZW0pOiA/Pg0KICAgICAgICA8dHI+DQogICAgICAgICAgICA8dGQ+PGEgaHJlZj0iPD9waHAgZWNobyAgW1tbQ29tcG9uZW50XV1dSGVscGVyUm91dGU6OmdldExvb2tpbmdSb3V0ZSgkaXRlbS0+c2x1Zyk7ID8+IiA+PD9waHAgZWNobyAkaXRlbS0+bmFtZTsgPz48L2E+PC90ZD4NCiAgICAgICAgICAgIDx0ZD48P3BocCBlY2hvICR0aGlzLT5lc2NhcGUoJGl0ZW0tPmRlc2NyaXB0aW9uLCB0cnVlLCAxMjApOyA/Pjw/cGhwIGVjaG8gJGl0ZW0tPmVkaXRMaW5rOyA/PjwvdGQ+DQogICAgICAgIDwvdHI+DQogICAgICAgIDw/cGhwIGVuZGZvcmVhY2g7ID8+DQogICAgPC90Ym9keT4NCjwvdGFibGU+', 'The List of all published looks', 36, '', 36, 'Looks', 'Looks', '', '', '', '', '', '', 1, '2016-04-05 14:31:59', '2016-10-20 15:57:24', 9, '', 14, 'b2dce59e-e3b8-4467-bcb5-8f2df4bdfeb7'), -(25, '', '', '', '', 1, 1, '', '', '', '', 1, '', '', '', '', 'looking', '', '', '', 'PGFydGljbGUgY2xhc3M9InVrLWNvbW1lbnQiPg0KICAgIDxoZWFkZXIgY2xhc3M9InVrLWNvbW1lbnQtaGVhZGVyIj4NCiAgICAgICAgPGltZyBjbGFzcz0idWstY29tbWVudC1hdmF0YXIiIHNyYz0ie2ltYWdldXJsfSIgYWx0PSIiPg0KICAgICAgICA8aDQgY2xhc3M9InVrLWNvbW1lbnQtdGl0bGUiPjw/cGhwIGVjaG8gJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+bmFtZSk7ID8+PC9oND4NCiAgICAgICAgPGRpdiBjbGFzcz0idWstY29tbWVudC1tZXRhIj48P3BocCBlY2hvIEpUZXh0OjpfKCdIaXRzJyk7ID8+OiA8P3BocCBlY2hvICR0aGlzLT5pdGVtLT5oaXRzOyA/PjwvZGl2Pg0KICAgIDwvaGVhZGVyPg0KICAgIDxkaXYgY2xhc3M9InVrLWNvbW1lbnQtYm9keSI+DQogICAgICAgIDw/cGhwIGVjaG8gJHRoaXMtPml0ZW0tPmRlc2NyaXB0aW9uOyA/Pg0KICAgICAgICA8P3BocCBpZiAoJHRoaXMtPml0ZW0tPmFkZCk6ID8+DQogICAgICAgICAgICA8YnIgLz4NCiAgICAgICAgICAgIDwhLS0gVGhpcyBpcyBhIGJ1dHRvbiB0b2dnbGluZyB0aGUgbW9kYWwgLS0+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJ1ay1idXR0b24iIGRhdGEtdWstbW9kYWw9Int0YXJnZXQ6JyNtb3JlLWRldGFpbHMtMDkwJ30iPjw/cGhwIGVjaG8gSlRleHQ6Ol8oJ01vcmUgRGV0YWlscycpOyA/PjwvYnV0dG9uPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICA8L2Rpdj4NCjwvYXJ0aWNsZT4NCjw/cGhwIGlmICgkdGhpcy0+aXRlbS0+YWRkKTogPz4NCjwhLS0gVGhpcyBpcyB0aGUgbW9kYWwgLS0+DQo8ZGl2IGlkPSJtb3JlLWRldGFpbHMtMDkwIiBjbGFzcz0idWstbW9kYWwiPg0KICAgIDxkaXYgY2xhc3M9InVrLW1vZGFsLWRpYWxvZyI+DQogICAgICAgIDxhIGNsYXNzPSJ1ay1tb2RhbC1jbG9zZSB1ay1jbG9zZSI+PC9hPg0KICAgICAgICA8ZGwgY2xhc3M9InVrLWRlc2NyaXB0aW9uLWxpc3QtaG9yaXpvbnRhbCI+DQogICAgICAgIDw/cGhwIGlmIChbW1tDb21wb25lbnRdXV1IZWxwZXI6OmNoZWNrU3RyaW5nKCR0aGlzLT5pdGVtLT5kYXRlb2ZiaXJ0aCkpOiA/Pg0KICAgICAgICAgICAgPGR0Pjw/cGhwIGVjaG8gSlRleHQ6Ol8oJ0JpcnRoIGRheScpOyA/PjwvZHQ+PGRkPjw/cGhwIGVjaG8gW1tbQ29tcG9uZW50XV1dSGVscGVyOjpmYW5jeURhdGUoJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+ZGF0ZW9mYmlydGgpKTsgPz48L2RkPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICAgICAgPD9waHAgaWYgKFtbW0NvbXBvbmVudF1dXUhlbHBlcjo6Y2hlY2tTdHJpbmcoJHRoaXMtPml0ZW0tPmVtYWlsKSk6ID8+DQogICAgICAgICAgICA8ZHQ+PD9waHAgZWNobyBKVGV4dDo6XygnRW1haWwnKTsgPz48L2R0PjxkZD48P3BocCBlY2hvICR0aGlzLT5lc2NhcGUoJHRoaXMtPml0ZW0tPmVtYWlsKTsgPz48L2RkPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICAgICAgPD9waHAgaWYgKFtbW0NvbXBvbmVudF1dXUhlbHBlcjo6Y2hlY2tTdHJpbmcoJHRoaXMtPml0ZW0tPm1vYmlsZV9waG9uZSkpOiA/Pg0KICAgICAgICAgICAgPGR0Pjw/cGhwIGVjaG8gSlRleHQ6Ol8oJ01vYmlsZScpOyA/PjwvZHQ+PGRkPjw/cGhwIGVjaG8gJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+bW9iaWxlX3Bob25lKTsgPz48L2RkPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICAgICAgPD9waHAgaWYgKFtbW0NvbXBvbmVudF1dXUhlbHBlcjo6Y2hlY2tTdHJpbmcoJHRoaXMtPml0ZW0tPndlYnNpdGUpKTogPz4NCiAgICAgICAgICAgIDxkdD48P3BocCBlY2hvIEpUZXh0OjpfKCdXZWJzaXRlJyk7ID8+PC9kdD48ZGQ+PD9waHAgZWNobyAkdGhpcy0+ZXNjYXBlKCR0aGlzLT5pdGVtLT53ZWJzaXRlKTsgPz48L2RkPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICAgICAgPC9kbD4NCiAgICA8L2Rpdj4NCjwvZGl2Pg0KPD9waHAgZW5kaWY7ID8+', 'Looking at a look', 39, '', 39, 'Looking', 'Looking', '', 'CSAvKioNCgkgKiBJbmNyZW1lbnQgdGhlIGhpdCBjb3VudGVyIGZvciB0aGUgcHJlYWNoZXIuDQoJICoNCgkgKiBAcGFyYW0gICBpbnRlZ2VyICAkcGsgIFByaW1hcnkga2V5IG9mIHRoZSBwcmVhY2hlciB0byBpbmNyZW1lbnQuDQoJICoNCgkgKiBAcmV0dXJuICBib29sZWFuICBUcnVlIGlmIHN1Y2Nlc3NmdWw7DQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGhpdCgkcGsgPSAwKQ0KCXsNCgkJaWYgKCRwaykNCgkJew0KCQkJJGRiID0gSkZhY3Rvcnk6OmdldERibygpOw0KCQkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCg0KCQkJLy8gRmllbGRzIHRvIHVwZGF0ZS4NCgkJCSRmaWVsZHMgPSBhcnJheSgNCgkJCSAgICAkZGItPnF1b3RlTmFtZSgnaGl0cycpIC4gJyA9ICcuJGRiLT5xdW90ZU5hbWUoJ2hpdHMnKS4nICsgMScNCgkJCSk7DQoNCgkJCS8vIENvbmRpdGlvbnMgZm9yIHdoaWNoIHJlY29yZHMgc2hvdWxkIGJlIHVwZGF0ZWQuDQoJCQkkY29uZGl0aW9ucyA9IGFycmF5KA0KCQkJICAgICRkYi0+cXVvdGVOYW1lKCdpZCcpIC4gJyA9ICcgLiAkcGsNCgkJCSk7DQoNCgkJCSRxdWVyeS0+dXBkYXRlKCRkYi0+cXVvdGVOYW1lKCcjX19bW1tjb21wb25lbnRdXV1fbG9vaycpKS0+c2V0KCRmaWVsZHMpLT53aGVyZSgkY29uZGl0aW9ucyk7DQoNCgkJCSRkYi0+c2V0UXVlcnkoJHF1ZXJ5KTsNCgkJCXJldHVybiAkZGItPmV4ZWN1dGUoKTsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ==', 'Ly8gYWRkIGEgaGl0IHRvIHRoZSBsb29rDQppZiAoJHRoaXMtPmhpdCgkdGhpcy0+aXRlbS0+aWQpKQ0Kew0KCSR0aGlzLT5pdGVtLT5oaXRzKys7DQp9', '', '', '', 1, '2016-10-20 15:11:29', '2016-10-20 17:10:58', 16, '', 14, '851ed44e-5431-4951-876f-4b62a4c56ad2'); - - - - +(25, '', '', '', '', 1, 1, '', '', '', '', 1, '', '', '', '', 'looking', '', '', '', 'PGFydGljbGUgY2xhc3M9InVrLWNvbW1lbnQiPg0KICAgIDxoZWFkZXIgY2xhc3M9InVrLWNvbW1lbnQtaGVhZGVyIj4NCiAgICAgICAgPGltZyBjbGFzcz0idWstY29tbWVudC1hdmF0YXIiIHNyYz0ie2ltYWdldXJsfSIgYWx0PSIiPg0KICAgICAgICA8aDQgY2xhc3M9InVrLWNvbW1lbnQtdGl0bGUiPjw/cGhwIGVjaG8gJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+bmFtZSk7ID8+PC9oND4NCiAgICAgICAgPGRpdiBjbGFzcz0idWstY29tbWVudC1tZXRhIj48P3BocCBlY2hvIEpUZXh0OjpfKCdIaXRzJyk7ID8+OiA8P3BocCBlY2hvICR0aGlzLT5pdGVtLT5oaXRzOyA/PjwvZGl2Pg0KICAgIDwvaGVhZGVyPg0KICAgIDxkaXYgY2xhc3M9InVrLWNvbW1lbnQtYm9keSI+DQogICAgICAgIDw/cGhwIGVjaG8gJHRoaXMtPml0ZW0tPmRlc2NyaXB0aW9uOyA/Pg0KICAgICAgICA8P3BocCBpZiAoJHRoaXMtPml0ZW0tPmFkZCk6ID8+DQogICAgICAgICAgICA8YnIgLz4NCiAgICAgICAgICAgIDwhLS0gVGhpcyBpcyBhIGJ1dHRvbiB0b2dnbGluZyB0aGUgbW9kYWwgLS0+DQogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJ1ay1idXR0b24iIGRhdGEtdWstbW9kYWw9Int0YXJnZXQ6JyNtb3JlLWRldGFpbHMtMDkwJ30iPjw/cGhwIGVjaG8gSlRleHQ6Ol8oJ01vcmUgRGV0YWlscycpOyA/PjwvYnV0dG9uPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICA8L2Rpdj4NCjwvYXJ0aWNsZT4NCjw/cGhwIGlmICgkdGhpcy0+aXRlbS0+YWRkKTogPz4NCjwhLS0gVGhpcyBpcyB0aGUgbW9kYWwgLS0+DQo8ZGl2IGlkPSJtb3JlLWRldGFpbHMtMDkwIiBjbGFzcz0idWstbW9kYWwiPg0KICAgIDxkaXYgY2xhc3M9InVrLW1vZGFsLWRpYWxvZyI+DQogICAgICAgIDxhIGNsYXNzPSJ1ay1tb2RhbC1jbG9zZSB1ay1jbG9zZSI+PC9hPg0KICAgICAgICA8ZGwgY2xhc3M9InVrLWRlc2NyaXB0aW9uLWxpc3QtaG9yaXpvbnRhbCI+DQogICAgICAgIDw/cGhwIGlmIChTdXBlcl9fXzFmMjhjYjUzXzYwZDlfNGRiMV9iNTE3XzNjN2RjNmI0MjllZl9fX1Bvd2VyOjpjaGVjaygkdGhpcy0+aXRlbS0+ZGF0ZW9mYmlydGgpKTogPz4NCiAgICAgICAgICAgIDxkdD48P3BocCBlY2hvIEpUZXh0OjpfKCdCaXJ0aCBkYXknKTsgPz48L2R0PjxkZD48P3BocCBlY2hvIFtbW0NvbXBvbmVudF1dXUhlbHBlcjo6ZmFuY3lEYXRlKCR0aGlzLT5lc2NhcGUoJHRoaXMtPml0ZW0tPmRhdGVvZmJpcnRoKSk7ID8+PC9kZD4NCiAgICAgICAgPD9waHAgZW5kaWY7ID8+DQogICAgICAgIDw/cGhwIGlmIChTdXBlcl9fXzFmMjhjYjUzXzYwZDlfNGRiMV9iNTE3XzNjN2RjNmI0MjllZl9fX1Bvd2VyOjpjaGVjaygkdGhpcy0+aXRlbS0+ZW1haWwpKTogPz4NCiAgICAgICAgICAgIDxkdD48P3BocCBlY2hvIEpUZXh0OjpfKCdFbWFpbCcpOyA/PjwvZHQ+PGRkPjw/cGhwIGVjaG8gJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+ZW1haWwpOyA/PjwvZGQ+DQogICAgICAgIDw/cGhwIGVuZGlmOyA/Pg0KICAgICAgICA8P3BocCBpZiAoU3VwZXJfX18xZjI4Y2I1M182MGQ5XzRkYjFfYjUxN18zYzdkYzZiNDI5ZWZfX19Qb3dlcjo6Y2hlY2soJHRoaXMtPml0ZW0tPm1vYmlsZV9waG9uZSkpOiA/Pg0KICAgICAgICAgICAgPGR0Pjw/cGhwIGVjaG8gSlRleHQ6Ol8oJ01vYmlsZScpOyA/PjwvZHQ+PGRkPjw/cGhwIGVjaG8gJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+bW9iaWxlX3Bob25lKTsgPz48L2RkPg0KICAgICAgICA8P3BocCBlbmRpZjsgPz4NCiAgICAgICAgPD9waHAgaWYgKFN1cGVyX19fMWYyOGNiNTNfNjBkOV80ZGIxX2I1MTdfM2M3ZGM2YjQyOWVmX19fUG93ZXI6OmNoZWNrKCR0aGlzLT5pdGVtLT53ZWJzaXRlKSk6ID8+DQogICAgICAgICAgICA8ZHQ+PD9waHAgZWNobyBKVGV4dDo6XygnV2Vic2l0ZScpOyA/PjwvZHQ+PGRkPjw/cGhwIGVjaG8gJHRoaXMtPmVzY2FwZSgkdGhpcy0+aXRlbS0+d2Vic2l0ZSk7ID8+PC9kZD4NCiAgICAgICAgPD9waHAgZW5kaWY7ID8+DQogICAgICAgIDwvZGw+DQogICAgPC9kaXY+DQo8L2Rpdj4NCjw/cGhwIGVuZGlmOyA/Pg==', 'Looking at a look', 39, '', 39, 'Looking', 'Looking', '', 'CSAvKioNCgkgKiBJbmNyZW1lbnQgdGhlIGhpdCBjb3VudGVyIGZvciB0aGUgcHJlYWNoZXIuDQoJICoNCgkgKiBAcGFyYW0gICBpbnRlZ2VyICAkcGsgIFByaW1hcnkga2V5IG9mIHRoZSBwcmVhY2hlciB0byBpbmNyZW1lbnQuDQoJICoNCgkgKiBAcmV0dXJuICBib29sZWFuICBUcnVlIGlmIHN1Y2Nlc3NmdWw7DQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGhpdCgkcGsgPSAwKQ0KCXsNCgkJaWYgKCRwaykNCgkJew0KCQkJJGRiID0gSkZhY3Rvcnk6OmdldERibygpOw0KCQkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCg0KCQkJLy8gRmllbGRzIHRvIHVwZGF0ZS4NCgkJCSRmaWVsZHMgPSBhcnJheSgNCgkJCSAgICAkZGItPnF1b3RlTmFtZSgnaGl0cycpIC4gJyA9ICcuJGRiLT5xdW90ZU5hbWUoJ2hpdHMnKS4nICsgMScNCgkJCSk7DQoNCgkJCS8vIENvbmRpdGlvbnMgZm9yIHdoaWNoIHJlY29yZHMgc2hvdWxkIGJlIHVwZGF0ZWQuDQoJCQkkY29uZGl0aW9ucyA9IGFycmF5KA0KCQkJICAgICRkYi0+cXVvdGVOYW1lKCdpZCcpIC4gJyA9ICcgLiAkcGsNCgkJCSk7DQoNCgkJCSRxdWVyeS0+dXBkYXRlKCRkYi0+cXVvdGVOYW1lKCcjX19bW1tjb21wb25lbnRdXV1fbG9vaycpKS0+c2V0KCRmaWVsZHMpLT53aGVyZSgkY29uZGl0aW9ucyk7DQoNCgkJCSRkYi0+c2V0UXVlcnkoJHF1ZXJ5KTsNCgkJCXJldHVybiAkZGItPmV4ZWN1dGUoKTsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ==', 'Ly8gYWRkIGEgaGl0IHRvIHRoZSBsb29rDQppZiAoJHRoaXMtPmhpdCgkdGhpcy0+aXRlbS0+aWQpKQ0Kew0KCSR0aGlzLT5pdGVtLT5oaXRzKys7DQp9', '', '', '', 1, '2016-10-20 15:11:29', '2016-10-20 17:10:58', 16, '', 14, '851ed44e-5431-4951-876f-4b62a4c56ad2'); -- -- Dumping data for table `#__componentbuilder_dynamic_get` @@ -2026,8 +1997,6 @@ INSERT INTO `#__componentbuilder_dynamic_get` (`id`, `add_php_after_getitem`, `a (36, '', '', 1, '', '', '', '', '', '', 'CQkvLyBkbyBhIHF1aWNrIGJ1aWxkIG9mIGFsbCBlZGl0IGxpbmtzIGxpbmtzDQoJCWlmIChpc3NldCgkaXRlbXMpICYmICRpdGVtcykNCgkJew0KCQkJZm9yZWFjaCAoJGl0ZW1zIGFzICRuciA9PiAmJGl0ZW0pDQoJCQl7DQoJCQkJJGNhbkRvID0gW1tbQ29tcG9uZW50XV1dSGVscGVyOjpnZXRBY3Rpb25zKCdsb29rJywkaXRlbSwnbG9va3MnKTsNCgkJCQlpZiAoJGNhbkRvLT5nZXQoJ2xvb2suZWRpdCcpKQ0KCQkJCXsNCgkJCQkJJGl0ZW0tPmVkaXRMaW5rID0gJzxiciAvPjxiciAvPjxhIGNsYXNzPSJ1ay1idXR0b24gdWstYnV0dG9uLXByaW1hcnkgdWstd2lkdGgtMS0xIiBocmVmPSInOw0KCQkJCQkkaXRlbS0+ZWRpdExpbmsgLj0gSlJvdXRlOjpfKCdpbmRleC5waHA/b3B0aW9uPWNvbV9bW1tjb21wb25lbnRdXV0mdmlldz1sb29rJnRhc2s9bG9vay5lZGl0JmlkPScgLiAkaXRlbS0+aWQpOw0KCQkJCQkkaXRlbS0+ZWRpdExpbmsgLj0gJyI+PGkgY2xhc3M9InVrLWljb24tcGVuY2lsIj48L2k+PHNwYW4gY2xhc3M9InVrLWhpZGRlbi1zbWFsbCI+JzsNCgkJCQkJJGl0ZW0tPmVkaXRMaW5rIC49IEpUZXh0OjpfKCdFZGl0IExvb2snKTsNCgkJCQkJJGl0ZW0tPmVkaXRMaW5rIC49ICc8L3NwYW4+PC9hPic7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCSRpdGVtLT5lZGl0TGluayA9ICcnOw0KCQkJCX0NCgkJCX0NCgkJfQ==', 1, '', '', '', '', '', 2, '', '', '', 1, 'Looks', '{\"order0\":{\"table_key\":\"a.name\",\"direction\":\"ASC\"}}', '', '', 'a.*', 109, '{\"where0\":{\"table_key\":\"a.published\",\"operator\":\"1\",\"value_key\":\"1\"}}', '', 1, 12, '', 13, '32b3ae7d-8aa8-47f1-ab2e-30076ddaa029'), (39, '', '', '', '', '', '', '', '', '', '', 1, '', '', '', '{\"filter0\":{\"filter_type\":\"1\",\"state_key\":\"id\",\"operator\":\"1\",\"table_key\":\"a.id\"}}', '', 1, '', '', '', 1, 'Looking', '', '', '', 'a.id AS id\r\na.name AS name\r\na.alias AS alias\r\na.description AS description\r\na.add AS add\r\na.email AS email\r\na.mobile_phone AS mobile_phone\r\na.dateofbirth AS dateofbirth\r\na.image AS image\r\na.website AS website\r\na.published AS published\r\na.hits AS hits\r\na.created_by AS created_by', 109, '', '', 1, 8, '', '', '98e6ea56-0911-4d89-b1f4-8f0bb1e4aa5a'); - - -- -- Dumping data for table `#__componentbuilder_library` -- @@ -2204,15 +2173,15 @@ INSERT INTO `#__componentbuilder_validation_rule` (`id`, `name`, `php`, `short_d -- INSERT INTO `#__componentbuilder_field` (`id`, `add_css_view`, `add_css_views`, `add_javascript_view_footer`, `add_javascript_views_footer`, `css_view`, `css_views`, `datadefault`, `datadefault_other`, `datalenght`, `datalenght_other`, `datatype`, `indexes`, `javascript_view_footer`, `javascript_views_footer`, `name`, `null_switch`, `store`, `fieldtype`, `xml`, `published`, `created`, `modified`, `version`, `hits`, `ordering`, `guid`) VALUES -(23, '', '', '', '', '', '', '', '', 64, '', 'CHAR', '', '', '', 'Alias', 'NOT NULL', '', 24, '\"\"', 1, '2015-04-09 13:46:04', '2016-05-05 22:30:18', 2, '', 216, '335866ce-b81b-4329-901d-c20254135c9c'), -(84, '', '', '', '', '', '', '', '', '', '', 'TEXT', '', '', '', 'Description (full width)', 'NOT NULL', '', 25, '\"\"', 1, '2015-03-19 18:20:49', '2016-10-20 17:01:21', 4, '', 265, '749a9917-90c3-49c4-9e72-aa33b0683a87'), +(23, '', '', '', '', '', '', '', '', 64, '', 'CHAR', 2, '', '', 'Alias', 'NOT NULL', '', 24, '\"\"', 1, '2015-04-09 13:46:04', '2023-06-27 23:46:54', 3, '', 216, '335866ce-b81b-4329-901d-c20254135c9c'), +(84, '', '', '', '', '', '', '', '', '', '', 'TEXT', '', '', '', 'Description (full width)', 'NOT NULL', '', 25, '\"\"', 1, '2015-03-19 18:20:49', '2022-09-21 10:17:10', 4, '', 265, '749a9917-90c3-49c4-9e72-aa33b0683a87'), (100, '', '', '', '', '', '', '', '', 255, '', 'VARCHAR', '', '', '', 'Email (required)', 'NOT NULL', '', 24, '\"\"', 1, '2015-05-05 23:44:32', '2016-02-07 22:43:18', 4, '', 285, '10c1eccb-b3c3-4325-a056-45a72d116fd8'), (158, '', '', '', '', '', '', '', '', 255, '', 'VARCHAR', '', '', '', 'Image', 'NOT NULL', '', 12, '\"\"', 1, '2015-04-29 14:00:56', '2020-06-07 02:17:46', 2, '', 45, '0d6970af-b361-4f65-84f6-0eb0c5f09bad'), (196, '', '', '', '', '', '', '', '', 64, '', 'VARCHAR', '', '', '', 'Mobile Phone', 'NOT NULL', '', 23, '\"\"', 1, '2015-04-07 22:12:58', '2016-03-28 14:00:02', 2, '', 7, '65933a19-243a-48b2-aae9-34e2da710051'), -(199, '', '', '', '', '', '', '', '', 255, '', 'VARCHAR', 2, '', '', 'Name (required)', 'NOT NULL', '', 24, '\"\"', 1, '2015-03-19 17:30:59', '2021-08-05 08:42:17', 10, '', 4, '5d3d34dd-4876-4c6a-86ab-b4e162f22c08'), -(203, '', '', '', '', '', '', '', '', 1, '', 'INT', '', '', '', 'Not Required', 'NOT NULL', '', 9, '\"\"', 1, '2015-05-08 16:19:16', '2020-02-27 20:17:33', 13, '', 19, 'da5e6901-6958-40e5-a4f5-6822d6fe57ac'), +(199, '', '', '', '', '', '', '', '', 255, '', 'VARCHAR', 2, '', '', 'Name (Key - Required)', 'NOT NULL', '', 24, '\"\"', 1, '2015-03-19 17:30:59', '2023-06-19 22:38:40', 10, '', 4, '5d3d34dd-4876-4c6a-86ab-b4e162f22c08'), +(203, '', '', '', '', '', '', '', '', 1, '', 'INT', '', '', '', 'Not Required', 'NOT NULL', '', 9, '\"\"', 1, '2015-05-08 16:19:16', '2023-09-27 07:57:19', 16, '', 19, 'da5e6901-6958-40e5-a4f5-6822d6fe57ac'), (280, '', '', '', '', '', '', '', '', 255, '', 'VARCHAR', '', '', '', 'Website', 'NOT NULL', '', 27, '\"\"', 1, '2015-04-08 00:36:16', '2018-07-08 00:11:05', 2, '', 105, '6c3a6983-d1bf-4e5e-9e99-deea00b0cefd'), -(682, '', '', '', '', '', '', '', '', 1, '', 'TINYINT', 2, '', '', 'Add More', 'NOT NULL', '', 17, '\"\"', 1, '2015-08-05 01:18:20', '2018-03-30 09:30:45', 4, '', 196, 'a66389aa-2323-4f44-8c23-ff44969639be'), +(682, '', '', '', '', '', '', '', '', 1, '', 'TINYINT', 2, '', '', 'Add More', 'NOT NULL', '', 17, '\"\"', 1, '2015-08-05 01:18:20', '2023-01-20 11:15:45', 7, '', 196, 'a66389aa-2323-4f44-8c23-ff44969639be'), (1011, '', '', '', '', '', '', 'Other', '0000-00-00', '', '', 'DATE', '', '', '', 'Date of Birth', 'NOT NULL', '', 1, '\"\"', 1, '2015-12-07 01:47:32', '2018-08-03 09:56:07', 4, '', 649, 'cb2bdf20-8800-407b-a4f6-250152a0bdfb'); -- @@ -2378,8 +2347,6 @@ INSERT INTO `#__componentbuilder_admin_fields` (`id`, `addfields`, `admin_view`, INSERT INTO `#__componentbuilder_admin_fields_conditions` (`id`, `addconditions`, `admin_view`, `published`, `created`, `modified`, `version`, `hits`, `ordering`) VALUES (111, '{\"addconditions0\":{\"target_field\":[\"1011\",\"100\",\"158\",\"196\",\"280\"],\"target_behavior\":\"1\",\"target_relation\":\"0\",\"match_field\":\"682\",\"match_behavior\":\"1\",\"match_options\":\"1|Yes\"}}', 109, 1, '2017-10-12 21:36:00', '0000-00-00 00:00:00', 2, '', ''); - - -- -- Dumping data for table `#__componentbuilder_component_admin_views` -- @@ -2511,14 +2478,16 @@ INSERT INTO `#__componentbuilder_library_files_folders_urls` (`id`, `addfiles`, (6, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/raw.githubusercontent.com\\/artf\\/grapesjs-preset-webpage\\/master\\/dist\\/grapesjs-preset-webpage.min.css\",\"type\":2},\"addurls1\":{\"url\":\"https:\\/\\/raw.githubusercontent.com\\/artf\\/grapesjs-preset-webpage\\/master\\/dist\\/grapesjs-preset-webpage.min.js\",\"type\":2},\"addurls2\":{\"url\":\"https:\\/\\/static.filestackapi.com\\/v3\\/filestack-0.1.10.js\",\"type\":2}}', 9, '', 1, '2020-02-18 21:13:16', '2020-02-18 21:14:11', 2, '', 5), (7, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/cdn.jsdelivr.net\\/npm\\/vue\",\"type\":3}}', 10, '', 1, '2020-06-05 13:11:54', '0000-00-00 00:00:00', 1, '', 6), (8, '{}', '{}', '{\"addurls2\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/1.10.21\\/js\\/jquery.dataTables.min.js\",\"type\":2},\"addurls1\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/1.10.21\\/css\\/dataTables.uikit.min.css\",\"type\":2}}', 11, '', 1, '2020-06-27 21:34:44', '0000-00-00 00:00:00', 1, '', 7), -(9, '{}', '{}', '{\"addurls3\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/themes\\/smoothness\\/jquery-ui.css\",\"type\":2},\"addurls0\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.css\",\"type\":2},\"addurls1\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/jquery-ui.min.js\",\"type\":2},\"addurls2\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.js\",\"type\":2}}', 12, '', 1, '2020-06-29 00:00:44', '2020-06-29 04:32:57', 4, '', 8); +(9, '{}', '{}', '{\"addurls3\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/themes\\/smoothness\\/jquery-ui.css\",\"type\":2},\"addurls0\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.css\",\"type\":2},\"addurls1\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/jquery-ui.min.js\",\"type\":2},\"addurls2\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.js\",\"type\":2}}', 12, '', 1, '2020-06-29 00:00:44', '2020-06-29 04:32:57', 4, '', 8), +(10, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/v\\/dt\\/jszip-2.5.0\\/dt-1.11.5\\/b-2.2.2\\/b-colvis-2.2.2\\/b-html5-2.2.2\\/b-print-2.2.2\\/cr-1.5.5\\/date-1.1.2\\/fc-4.0.2\\/fh-3.2.2\\/kt-2.6.4\\/r-2.2.9\\/rg-1.1.4\\/rr-1.2.8\\/sc-2.0.5\\/sb-1.3.2\\/sp-2.0.0\\/sl-1.3.4\\/sr-1.1.0\\/datatables.min.css\",\"type\":3},\"addurls1\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/pdfmake\\/0.1.36\\/pdfmake.min.js\",\"type\":3},\"addurls2\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/pdfmake\\/0.1.36\\/vfs_fonts.js\",\"type\":3},\"addurls3\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/v\\/dt\\/jszip-2.5.0\\/dt-1.11.5\\/b-2.2.2\\/b-colvis-2.2.2\\/b-html5-2.2.2\\/b-print-2.2.2\\/cr-1.5.5\\/date-1.1.2\\/fc-4.0.2\\/fh-3.2.2\\/kt-2.6.4\\/r-2.2.9\\/rg-1.1.4\\/rr-1.2.8\\/sc-2.0.5\\/sb-1.3.2\\/sp-2.0.0\\/sl-1.3.4\\/sr-1.1.0\\/datatables.min.js\",\"type\":3}}', 13, '', 1, '2022-10-17 20:56:24', '0000-00-00 00:00:00', 1, '', 9), +(11, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/cdn.jsdelivr.net\\/npm\\/nouislider\\/dist\\/nouislider.min.css\",\"type\":2},\"addurls1\":{\"url\":\"https:\\/\\/cdn.jsdelivr.net\\/npm\\/nouislider\\/dist\\/nouislider.min.js\",\"type\":2}}', 14, '', 1, '2023-06-26 15:02:42', '2023-07-24 18:11:41', 3, '', 10); CREATE TABLE IF NOT EXISTS `#__componentbuilder_external_code` ( `target` VARCHAR(255) NOT NULL DEFAULT '', `hash` VARCHAR(64) NOT NULL DEFAULT '', PRIMARY KEY (`target`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; diff --git a/admin/sql/updates/mysql/3.1.12.sql b/admin/sql/updates/mysql/3.1.12.sql new file mode 100644 index 000000000..c8e27449a --- /dev/null +++ b/admin/sql/updates/mysql/3.1.12.sql @@ -0,0 +1 @@ +ALTER TABLE `#__componentbuilder_power` ADD `composer` TEXT NOT NULL AFTER `add_licensing_template`; diff --git a/admin/sql/updates/mysql/3.1.19.sql b/admin/sql/updates/mysql/3.1.19.sql new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.19.sql @@ -0,0 +1 @@ + diff --git a/admin/sql/updates/mysql/3.1.21.sql b/admin/sql/updates/mysql/3.1.21.sql new file mode 100644 index 000000000..c7d0397e8 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.21.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__componentbuilder_power` ADD `approved` TINYINT(1) NOT NULL DEFAULT 0 AFTER `add_licensing_template`; +ALTER TABLE `#__componentbuilder_power` ADD `approved_paths` TEXT NOT NULL AFTER `approved`; diff --git a/admin/sql/updates/mysql/3.1.24.sql b/admin/sql/updates/mysql/3.1.24.sql new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.24.sql @@ -0,0 +1 @@ + diff --git a/admin/sql/updates/mysql/3.1.25.sql b/admin/sql/updates/mysql/3.1.25.sql new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.25.sql @@ -0,0 +1 @@ + diff --git a/admin/sql/updates/mysql/3.1.26.sql b/admin/sql/updates/mysql/3.1.26.sql new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.26.sql @@ -0,0 +1 @@ + diff --git a/admin/sql/updates/mysql/3.1.27.sql b/admin/sql/updates/mysql/3.1.27.sql new file mode 100644 index 000000000..3edcba651 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.27.sql @@ -0,0 +1,7 @@ +ALTER TABLE `#__componentbuilder_joomla_component` ADD `add_backup_folder_path` TINYINT(1) NOT NULL DEFAULT 0 AFTER `add_admin_event`; + +ALTER TABLE `#__componentbuilder_joomla_component` ADD `add_git_folder_path` TINYINT(1) NOT NULL DEFAULT 0 AFTER `add_email_helper`; + +ALTER TABLE `#__componentbuilder_joomla_component` ADD `backup_folder_path` VARCHAR(255) NOT NULL DEFAULT '' AFTER `author`; + +ALTER TABLE `#__componentbuilder_joomla_component` ADD `git_folder_path` VARCHAR(255) NOT NULL DEFAULT '' AFTER `export_key`; diff --git a/admin/sql/updates/mysql/3.1.5.sql b/admin/sql/updates/mysql/3.1.5.sql new file mode 100644 index 000000000..951fcc604 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.5.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__componentbuilder_power` ADD `add_licensing_template` TINYINT(1) NOT NULL DEFAULT 1 AFTER `add_head`; +ALTER TABLE `#__componentbuilder_power` ADD `licensing_template` TEXT NOT NULL AFTER `implements_custom`; diff --git a/admin/views/admin_views/tmpl/default_body.php b/admin/views/admin_views/tmpl/default_body.php index 633f8281a..38310f033 100644 --- a/admin/views/admin_views/tmpl/default_body.php +++ b/admin/views/admin_views/tmpl/default_body.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\ArrayHelper; $edit = "index.php?option=com_componentbuilder&view=admin_views&task=admin_view.edit"; @@ -72,7 +73,7 @@ $edit = "index.php?option=com_componentbuilder&view=admin_views&task=admin_view. canState = $this->canDo->get('admin_view.edit.state'); $this->canCreate = $this->canDo->get('admin_view.create'); $this->canDelete = $this->canDo->get('admin_view.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('admin_view.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/admins_custom_tabs/view.html.php b/admin/views/admins_custom_tabs/view.html.php index 8aad2ea99..84201b327 100644 --- a/admin/views/admins_custom_tabs/view.html.php +++ b/admin/views/admins_custom_tabs/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewAdmins_custom_tabs extends HtmlView $this->canState = $this->canDo->get('admin_custom_tabs.edit.state'); $this->canCreate = $this->canDo->get('admin_custom_tabs.create'); $this->canDelete = $this->canDo->get('admin_custom_tabs.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('admin_custom_tabs.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/admins_fields/view.html.php b/admin/views/admins_fields/view.html.php index 9a85b77bf..ef6cad1dc 100644 --- a/admin/views/admins_fields/view.html.php +++ b/admin/views/admins_fields/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewAdmins_fields extends HtmlView $this->canState = $this->canDo->get('admin_fields.edit.state'); $this->canCreate = $this->canDo->get('admin_fields.create'); $this->canDelete = $this->canDo->get('admin_fields.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('admin_fields.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/admins_fields_conditions/view.html.php b/admin/views/admins_fields_conditions/view.html.php index 4253ed693..d99212b9c 100644 --- a/admin/views/admins_fields_conditions/view.html.php +++ b/admin/views/admins_fields_conditions/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewAdmins_fields_conditions extends HtmlView $this->canState = $this->canDo->get('admin_fields_conditions.edit.state'); $this->canCreate = $this->canDo->get('admin_fields_conditions.create'); $this->canDelete = $this->canDo->get('admin_fields_conditions.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('admin_fields_conditions.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/admins_fields_relations/view.html.php b/admin/views/admins_fields_relations/view.html.php index d6382395b..dfcada8ef 100644 --- a/admin/views/admins_fields_relations/view.html.php +++ b/admin/views/admins_fields_relations/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewAdmins_fields_relations extends HtmlView $this->canState = $this->canDo->get('admin_fields_relations.edit.state'); $this->canCreate = $this->canDo->get('admin_fields_relations.create'); $this->canDelete = $this->canDo->get('admin_fields_relations.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('admin_fields_relations.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/class_extendings/view.html.php b/admin/views/class_extendings/view.html.php index 459e76827..3e0582f87 100644 --- a/admin/views/class_extendings/view.html.php +++ b/admin/views/class_extendings/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewClass_extendings extends HtmlView $this->canState = $this->canDo->get('class_extends.edit.state'); $this->canCreate = $this->canDo->get('class_extends.create'); $this->canDelete = $this->canDo->get('class_extends.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('class_extends.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/class_methods/view.html.php b/admin/views/class_methods/view.html.php index dcbc7694d..29c445ee0 100644 --- a/admin/views/class_methods/view.html.php +++ b/admin/views/class_methods/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewClass_methods extends HtmlView $this->canState = $this->canDo->get('class_method.edit.state'); $this->canCreate = $this->canDo->get('class_method.create'); $this->canDelete = $this->canDo->get('class_method.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('class_method.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/class_properties/tmpl/default_body.php b/admin/views/class_properties/tmpl/default_body.php index ed9882423..4befb19f3 100644 --- a/admin/views/class_properties/tmpl/default_body.php +++ b/admin/views/class_properties/tmpl/default_body.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; $edit = "index.php?option=com_componentbuilder&view=class_properties&task=class_property.edit"; @@ -73,7 +74,7 @@ $edit = "index.php?option=com_componentbuilder&view=class_properties&task=class_ visibility); ?>
").insertAfter(H));r.nTBody=ea[0];H=t.children("tfoot");0===H.length&&0").appendTo(t));0===H.length||0===H.children().length?t.addClass(C.sNoFooter):0/g,vc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,wc=/(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\|\$|\^|\-)/g,rb=/['\u00A0,$£₏„%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,Z=function(a){return a&&!0!==a&&"-"!==a?!1:!0},hc= +function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},ic=function(a,b){sb[b]||(sb[b]=new RegExp(jb(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(sb[b],"."):a},tb=function(a,b,c){var d="string"===typeof a;if(Z(a))return!0;b&&d&&(a=ic(a,b));c&&d&&(a=a.replace(rb,""));return!isNaN(parseFloat(a))&&isFinite(a)},jc=function(a,b,c){return Z(a)?!0:Z(a)||"string"===typeof a?tb(a.replace(Va,""),b,c)?!0:null:null},U=function(a,b,c){var d=[],e=0,h=a.length;if(c!==q)for(;e< +h;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;ea.length)){var b=a.slice().sort();for(var c=b[0],d=1,e=b.length;d< +e;d++){if(b[d]===c){b=!1;break a}c=b[d]}}b=!0}if(b)return a.slice();b=[];e=a.length;var h,f=0;d=0;a:for(;d")[0],tc=Qa.textContent!==q,uc=/<.*?>/g,hb=u.util.throttle,nc=[],N=Array.prototype,xc=function(a){var b,c=u.settings,d=l.map(c,function(h,f){return h.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase()){var e= +l.inArray(a,d);return-1!==e?[c[e]]:null}if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?b=l(a):a instanceof l&&(b=a)}else return[];if(b)return b.map(function(h){e=l.inArray(this,d);return-1!==e?c[e]:null}).toArray()};var B=function(a,b){if(!(this instanceof B))return new B(a,b);var c=[],d=function(f){(f=xc(f))&&c.push.apply(c,f)};if(Array.isArray(a))for(var e=0,h=a.length;ea?new B(b[a],this[a]):null},filter:function(a){var b=[];if(N.filter)b=N.filter.call(this,a,this);else for(var c=0,d=this.length;c").addClass(g),l("td",k).addClass(g).html(f)[0].colSpan=oa(a),e.push(k[0]))};h(c,d);b._details&&b._details.detach();b._details=l(e);b._detailsShow&&b._details.insertAfter(b.nTr)},qc=u.util.throttle(function(a){Ca(a[0])},500),xb=function(a,b){var c=a.context;c.length&&(a=c[0].aoData[b!== +q?b:a[0]])&&a._details&&(a._details.remove(),a._detailsShow=q,a._details=q,l(a.nTr).removeClass("dt-hasChild"),qc(c))},rc=function(a,b){var c=a.context;if(c.length&&a.length){var d=c[0].aoData[a[0]];d._details&&((d._detailsShow=b)?(d._details.insertAfter(d.nTr),l(d.nTr).addClass("dt-hasChild")):(d._details.detach(),l(d.nTr).removeClass("dt-hasChild")),F(c[0],null,"childRow",[b,a.row(a[0])]),Ac(c[0]),qc(c))}},Ac=function(a){var b=new B(a),c=a.aoData;b.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details"); +0g){var n=l.map(d,function(p,t){return p.bVisible?t:null});return[n[n.length+g]]}return[ta(a,g)];case "name":return l.map(e,function(p,t){return p===m[1]?t:null});default:return[]}if(f.nodeName&&f._DT_CellIndex)return[f._DT_CellIndex.column];g=l(h).filter(f).map(function(){return l.inArray(this,h)}).toArray();if(g.length||!f.nodeName)return g;g=l(f).closest("*[data-dt-column]");return g.length?[g.data("dt-column")]:[]},a,c)}; +y("columns()",function(a,b){a===q?a="":l.isPlainObject(a)&&(b=a,a="");b=vb(b);var c=this.iterator("table",function(d){return Cc(d,a,b)},1);c.selector.cols=a;c.selector.opts=b;return c});J("columns().header()","column().header()",function(a,b){return this.iterator("column",function(c,d){return c.aoColumns[d].nTh},1)});J("columns().footer()","column().footer()",function(a,b){return this.iterator("column",function(c,d){return c.aoColumns[d].nTf},1)});J("columns().data()","column().data()",function(){return this.iterator("column-rows", +sc,1)});J("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});J("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,h){return Ea(b.aoData,h,"search"===a?"_aFilterData":"_aSortData",c)},1)});J("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return Ea(a.aoData,e,"anCells",b)},1)});J("columns().visible()","column().visible()", +function(a,b){var c=this,d=this.iterator("column",function(e,h){if(a===q)return e.aoColumns[h].bVisible;var f=e.aoColumns,g=f[h],k=e.aoData,m;if(a!==q&&g.bVisible!==a){if(a){var n=l.inArray(!0,U(f,"bVisible"),h+1);f=0;for(m=k.length;fd;return!0};u.isDataTable=u.fnIsDataTable=function(a){var b=l(a).get(0),c=!1;if(a instanceof u.Api)return!0;l.each(u.settings,function(d,e){d=e.nScrollHead?l("table",e.nScrollHead)[0]:null;var h=e.nScrollFoot?l("table",e.nScrollFoot)[0]:null;if(e.nTable===b||d===b||h===b)c=!0});return c};u.tables=u.fnTables=function(a){var b= +!1;l.isPlainObject(a)&&(b=a.api,a=a.visible);var c=l.map(u.settings,function(d){if(!a||a&&l(d.nTable).is(":visible"))return d.nTable});return b?new B(c):c};u.camelToHungarian=P;y("$()",function(a,b){b=this.rows(b).nodes();b=l(b);return l([].concat(b.filter(a).toArray(),b.find(a).toArray()))});l.each(["on","one","off"],function(a,b){y(b+"()",function(){var c=Array.prototype.slice.call(arguments);c[0]=l.map(c[0].split(/\s/),function(e){return e.match(/\.dt\b/)?e:e+".dt"}).join(" ");var d=l(this.tables().nodes()); +d[b].apply(d,c);return this})});y("clear()",function(){return this.iterator("table",function(a){Ka(a)})});y("settings()",function(){return new B(this.context,this.context)});y("init()",function(){var a=this.context;return a.length?a[0].oInit:null});y("data()",function(){return this.iterator("table",function(a){return U(a.aoData,"_aData")}).flatten()});y("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,h=b.nTBody,f=b.nTHead, +g=b.nTFoot,k=l(e);h=l(h);var m=l(b.nTableWrapper),n=l.map(b.aoData,function(t){return t.nTr}),p;b.bDestroying=!0;F(b,"aoDestroyCallback","destroy",[b]);a||(new B(b)).columns().visible(!0);m.off(".DT").find(":not(tbody *)").off(".DT");l(z).off(".DT-"+b.sInstance);e!=f.parentNode&&(k.children("thead").detach(),k.append(f));g&&e!=g.parentNode&&(k.children("tfoot").detach(),k.append(g));b.aaSorting=[];b.aaSortingFixed=[];Sa(b);l(n).removeClass(b.asStripeClasses.join(" "));l("th, td",f).removeClass(d.sSortable+ +" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);h.children().detach();h.append(n);f=a?"remove":"detach";k[f]();m[f]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),k.css("width",b.sDestroyWidth).removeClass(d.sTable),(p=b.asDestroyStripes.length)&&h.children().each(function(t){l(this).addClass(b.asDestroyStripes[t%p])}));c=l.inArray(b,u.settings);-1!==c&&u.settings.splice(c,1)})});l.each(["column","row","cell"],function(a,b){y(b+"s().every()",function(c){var d=this.selector.opts,e= +this;return this.iterator(b,function(h,f,g,k,m){c.call(e[b](f,"cell"===b?g:d,"cell"===b?d:q),f,g,k,m)})})});y("i18n()",function(a,b,c){var d=this.context[0];a=na(a)(d.oLanguage);a===q&&(a=b);c!==q&&l.isPlainObject(a)&&(a=a[c]!==q?a[c]:a._);return a.replace("%d",c)});u.version="1.11.5";u.settings=[];u.models={};u.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0,"return":!1};u.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"", +src:null,idx:-1};u.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};u.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10, +25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null, +fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){return{}}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}}, +fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)", +sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:l.extend({},u.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};E(u.defaults);u.defaults.column={aDataSort:null, +iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};E(u.defaults.column);u.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null, +iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[], +aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,jqXHR:null,json:q,oAjaxData:q,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0, +bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==Q(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==Q(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,h= +e.bPaginate;return e.bServerSide?!1===h||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!h||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};u.ext=M={buttons:{},classes:{},builder:"dt/jszip-2.5.0/dt-1.11.5/b-2.2.2/b-colvis-2.2.2/b-html5-2.2.2/b-print-2.2.2/cr-1.5.5/date-1.1.2/fc-4.0.2/fh-3.2.2/kt-2.6.4/r-2.2.9/rg-1.1.4/rr-1.2.8/sc-2.0.5/sb-1.3.2/sp-2.0.0/sl-1.3.4/sr-1.1.0",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:u.fnVersionCheck, +iApiIndex:0,oJUIClasses:{},sVersion:u.version};l.extend(M,{afnFiltering:M.search,aTypes:M.type.detect,ofnSearch:M.type.search,oSort:M.type.order,afnSortData:M.order,aoFeatures:M.feature,oApi:M.internal,oStdClasses:M.classes,oPagination:M.pager});l.extend(u.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter", +sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_desc_disabled",sSortableDesc:"sorting_asc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody", +sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var ec=u.ext.pager;l.extend(ec,{simple:function(a,b){return["previous","next"]},full:function(a,b){return["first","previous","next","last"]},numbers:function(a,b){return[Da(a,b)]},simple_numbers:function(a,b){return["previous",Da(a,b),"next"]}, +full_numbers:function(a,b){return["first","previous",Da(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",Da(a,b),"last"]},_numbers:Da,numbers_length:7});l.extend(!0,u.ext.renderer,{pageButton:{_:function(a,b,c,d,e,h){var f=a.oClasses,g=a.oLanguage.oPaginate,k=a.oLanguage.oAria.paginate||{},m,n,p=0,t=function(x,w){var r,C=f.sPageButtonDisabled,G=function(I){Ra(a,I.data.action,!0)};var aa=0;for(r=w.length;aa").appendTo(x); +t(O,L)}else{m=null;n=L;O=a.iTabIndex;switch(L){case "ellipsis":x.append('');break;case "first":m=g.sFirst;0===e&&(O=-1,n+=" "+C);break;case "previous":m=g.sPrevious;0===e&&(O=-1,n+=" "+C);break;case "next":m=g.sNext;if(0===h||e===h-1)O=-1,n+=" "+C;break;case "last":m=g.sLast;if(0===h||e===h-1)O=-1,n+=" "+C;break;default:m=a.fnFormatNumber(L+1),n=e===L?f.sPageButtonActive:""}null!==m&&(O=l("",{"class":f.sPageButton+" "+n,"aria-controls":a.sTableId,"aria-label":k[L], +"data-dt-idx":p,tabindex:O,id:0===c&&"string"===typeof L?a.sTableId+"_"+L:null}).html(m).appendTo(x),ob(O,{action:L},G),p++)}}};try{var v=l(b).find(A.activeElement).data("dt-idx")}catch(x){}t(l(b).empty(),d);v!==q&&l(b).find("[data-dt-idx="+v+"]").trigger("focus")}}});l.extend(u.ext.type.detect,[function(a,b){b=b.oLanguage.sDecimal;return tb(a,b)?"num"+b:null},function(a,b){if(a&&!(a instanceof Date)&&!vc.test(a))return null;b=Date.parse(a);return null!==b&&!isNaN(b)||Z(a)?"date":null},function(a, +b){b=b.oLanguage.sDecimal;return tb(a,b,!0)?"num-fmt"+b:null},function(a,b){b=b.oLanguage.sDecimal;return jc(a,b)?"html-num"+b:null},function(a,b){b=b.oLanguage.sDecimal;return jc(a,b,!0)?"html-num-fmt"+b:null},function(a,b){return Z(a)||"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);l.extend(u.ext.type.search,{html:function(a){return Z(a)?a:"string"===typeof a?a.replace(gc," ").replace(Va,""):""},string:function(a){return Z(a)?a:"string"===typeof a?a.replace(gc," "):a}});var Ua=function(a, +b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=ic(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};l.extend(M.type.order,{"date-pre":function(a){a=Date.parse(a);return isNaN(a)?-Infinity:a},"html-pre":function(a){return Z(a)?"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return Z(a)?"":"string"===typeof a?a.toLowerCase():a.toString?a.toString():""},"string-asc":function(a,b){return ab?1:0},"string-desc":function(a,b){return a< +b?1:a>b?-1:0}});Xa("");l.extend(!0,u.ext.renderer,{header:{_:function(a,b,c,d){l(a.nTable).on("order.dt.DT",function(e,h,f,g){a===h&&(e=c.idx,b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass("asc"==g[e]?d.sSortAsc:"desc"==g[e]?d.sSortDesc:c.sSortingClass))})},jqueryui:function(a,b,c,d){l("
").addClass(d.sSortJUIWrapper).append(b.contents()).append(l("").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);l(a.nTable).on("order.dt.DT",function(e,h,f,g){a===h&&(e=c.idx,b.removeClass(d.sSortAsc+ +" "+d.sSortDesc).addClass("asc"==g[e]?d.sSortAsc:"desc"==g[e]?d.sSortDesc:c.sSortingClass),b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass("asc"==g[e]?d.sSortJUIAsc:"desc"==g[e]?d.sSortJUIDesc:c.sSortingClassJUI))})}}});var yb=function(a){Array.isArray(a)&&(a=a.join(","));return"string"===typeof a?a.replace(/&/g,"&").replace(//g,">").replace(/"/g,"""):a};u.render= +{number:function(a,b,c,d,e){return{display:function(h){if("number"!==typeof h&&"string"!==typeof h)return h;var f=0>h?"-":"",g=parseFloat(h);if(isNaN(g))return yb(h);g=g.toFixed(c);h=Math.abs(g);g=parseInt(h,10);h=c?b+(h-g).toFixed(c).substring(2):"";0===g&&0===parseFloat(h)&&(f="");return f+(d||"")+g.toString().replace(/\B(?=(\d{3})+(?!\d))/g,a)+h+(e||"")}}},text:function(){return{display:yb,filter:yb}}};l.extend(u.ext.internal,{_fnExternApiFunc:fc,_fnBuildAjax:Oa,_fnAjaxUpdate:Gb,_fnAjaxParameters:Pb, +_fnAjaxUpdateDraw:Qb,_fnAjaxDataSrc:za,_fnAddColumn:Ya,_fnColumnOptions:Ga,_fnAdjustColumnSizing:sa,_fnVisibleToColumnIndex:ta,_fnColumnIndexToVisible:ua,_fnVisbleColumns:oa,_fnGetColumns:Ia,_fnColumnTypes:$a,_fnApplyColumnDefs:Db,_fnHungarianMap:E,_fnCamelToHungarian:P,_fnLanguageCompat:ma,_fnBrowserDetect:Bb,_fnAddData:ia,_fnAddTr:Ja,_fnNodeToDataIndex:function(a,b){return b._DT_RowIndex!==q?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return l.inArray(c,a.aoData[b].anCells)},_fnGetCellData:T, +_fnSetCellData:Eb,_fnSplitObjNotation:cb,_fnGetObjectDataFn:na,_fnSetObjectDataFn:ha,_fnGetDataMaster:db,_fnClearTable:Ka,_fnDeleteIndex:La,_fnInvalidate:va,_fnGetRowElements:bb,_fnCreateTr:ab,_fnBuildHead:Fb,_fnDrawHead:xa,_fnDraw:ja,_fnReDraw:ka,_fnAddOptionsHtml:Ib,_fnDetectHeader:wa,_fnGetUniqueThs:Na,_fnFeatureHtmlFilter:Kb,_fnFilterComplete:ya,_fnFilterCustom:Tb,_fnFilterColumn:Sb,_fnFilter:Rb,_fnFilterCreateSearch:ib,_fnEscapeRegex:jb,_fnFilterData:Ub,_fnFeatureHtmlInfo:Nb,_fnUpdateInfo:Xb, +_fnInfoMacros:Yb,_fnInitialise:Aa,_fnInitComplete:Pa,_fnLengthChange:kb,_fnFeatureHtmlLength:Jb,_fnFeatureHtmlPaginate:Ob,_fnPageChange:Ra,_fnFeatureHtmlProcessing:Lb,_fnProcessingDisplay:V,_fnFeatureHtmlTable:Mb,_fnScrollDraw:Ha,_fnApplyToChildren:ca,_fnCalculateColumnWidths:Za,_fnThrottle:hb,_fnConvertToWidth:Zb,_fnGetWidestNode:$b,_fnGetMaxLenString:ac,_fnStringToCss:K,_fnSortFlatten:pa,_fnSort:Hb,_fnSortAria:cc,_fnSortListener:nb,_fnSortAttachListener:fb,_fnSortingClasses:Sa,_fnSortData:bc,_fnSaveState:Ca, +_fnLoadState:dc,_fnImplementState:pb,_fnSettingsFromNode:Ta,_fnLog:da,_fnMap:X,_fnBindAction:ob,_fnCallbackReg:R,_fnCallbackFire:F,_fnLengthOverflow:lb,_fnRenderer:gb,_fnDataSource:Q,_fnRowAttributes:eb,_fnExtend:qb,_fnCalculateEnd:function(){}});l.fn.dataTable=u;u.$=l;l.fn.dataTableSettings=u.settings;l.fn.dataTableExt=u.ext;l.fn.DataTable=function(a){return l(this).dataTable(a).api()};l.each(u,function(a,b){l.fn.DataTable[a]=b});return u}); + + +/*! + DataTables styling integration + ©2018 SpryMedia Ltd - datatables.net/license +*/ +(function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return c(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);b&&b.fn.dataTable||(b=require("datatables.net")(a,b).$);return c(b,a,a.document)}:c(jQuery,window,document)})(function(c,a,b,d){return c.fn.dataTable}); + + +/*! + Buttons for DataTables 2.2.2 + ©2016-2022 SpryMedia Ltd - datatables.net/license +*/ +(function(d){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(z){return d(z,window,document)}):"object"===typeof exports?module.exports=function(z,B){z||(z=window);B&&B.fn.dataTable||(B=require("datatables.net")(z,B).$);return d(B,z,z.document)}:d(jQuery,window,document)})(function(d,z,B,p){function I(a,b,c){d.fn.animate?a.stop().fadeIn(b,c):(a.css("display","block"),c&&c.call(a))}function J(a,b,c){d.fn.animate?a.stop().fadeOut(b,c):(a.css("display","none"),c&&c.call(a))} +function L(a,b){a=new u.Api(a);b=b?b:a.init().buttons||u.defaults.buttons;return(new x(a,b)).container()}var u=d.fn.dataTable,O=0,P=0,C=u.ext.buttons,x=function(a,b){if(!(this instanceof x))return function(c){return(new x(c,a)).container()};"undefined"===typeof b&&(b={});!0===b&&(b={});Array.isArray(b)&&(b={buttons:b});this.c=d.extend(!0,{},x.defaults,b);b.buttons&&(this.c.buttons=b.buttons);this.s={dt:new u.Api(a),buttons:[],listenKeys:"",namespace:"dtb"+O++};this.dom={container:d("<"+this.c.dom.container.tag+ +"/>").addClass(this.c.dom.container.className)};this._constructor()};d.extend(x.prototype,{action:function(a,b){a=this._nodeToButton(a);if(b===p)return a.conf.action;a.conf.action=b;return this},active:function(a,b){var c=this._nodeToButton(a);a=this.c.dom.button.active;c=d(c.node);if(b===p)return c.hasClass(a);c.toggleClass(a,b===p?!0:b);return this},add:function(a,b,c){var e=this.s.buttons;if("string"===typeof b){b=b.split("-");var h=this.s;e=0;for(var f=b.length-1;e");k.conf._collection=k.collection;if(k.conf.split)for(var t=0;t'+this.c.dom.splitDropdown.text+""));this._expandButton(k.buttons,k.conf.buttons,k.conf.split,!b,b,f,k.conf)}k.conf.parent=g;n.init&&n.init.call(l.button(k.node),l,d(k.node),n);m++}}}},_buildButton:function(a,b,c,e){var h=this.c.dom.button,f=this.c.dom.buttonLiner,g=this.c.dom.collection,l=this.c.dom.splitCollection,m=this.c.dom.splitDropdownButton, +r=this.s.dt,q=function(w){return"function"===typeof w?w(r,k,a):w};if(a.spacer){var n=d("").addClass("dt-button-spacer "+a.style+" "+h.spacerClass).html(q(a.text));return{conf:a,node:n,inserter:n,buttons:[],inCollection:b,isSplit:c,inSplit:e,collection:null}}!c&&e&&l?h=m:!c&&b&&g.button&&(h=g.button);!c&&e&&l.buttonLiner?f=l.buttonLiner:!c&&b&&g.buttonLiner&&(f=g.buttonLiner);if(a.available&&!a.available(r,a)&&!a.hasOwnProperty("html"))return!1;if(a.hasOwnProperty("html"))var k=d(a.html); +else{var t=function(w,D,F,G){G.action.call(D.button(F),w,D,F,G);d(D.table().node()).triggerHandler("buttons-action.dt",[D.button(F),D,F,G])};g=a.tag||h.tag;var y=a.clickBlurs===p?!0:a.clickBlurs;k=d("<"+g+"/>").addClass(h.className).addClass(e?this.c.dom.splitDropdownButton.className:"").attr("tabindex",this.s.dt.settings()[0].iTabIndex).attr("aria-controls",this.s.dt.table().node().id).on("click.dtb",function(w){w.preventDefault();!k.hasClass(h.disabled)&&a.action&&t(w,r,k,a);y&&k.trigger("blur")}).on("keypress.dtb", +function(w){13===w.keyCode&&(w.preventDefault(),!k.hasClass(h.disabled)&&a.action&&t(w,r,k,a))});"a"===g.toLowerCase()&&k.attr("href","#");"button"===g.toLowerCase()&&k.attr("type","button");f.tag?(g=d("<"+f.tag+"/>").html(q(a.text)).addClass(f.className),"a"===f.tag.toLowerCase()&&g.attr("href","#"),k.append(g)):k.html(q(a.text));!1===a.enabled&&k.addClass(h.disabled);a.className&&k.addClass(a.className);a.titleAttr&&k.attr("title",q(a.titleAttr));a.attr&&k.attr(a.attr);a.namespace||(a.namespace= +".dt-button-"+P++);a.config!==p&&a.config.split&&(a.split=a.config.split)}f=(f=this.c.dom.buttonContainer)&&f.tag?d("<"+f.tag+"/>").addClass(f.className).append(k):k;this._addKey(a);this.c.buttonCreated&&(f=this.c.buttonCreated(a,f));if(c){n=d("
").addClass(this.c.dom.splitWrapper.className);n.append(k);var v=d.extend(a,{text:this.c.dom.splitDropdown.text,className:this.c.dom.splitDropdown.className,closeButton:!1,attr:{"aria-haspopup":!0,"aria-expanded":!1},align:this.c.dom.splitDropdown.align, +splitAlignClass:this.c.dom.splitDropdown.splitAlignClass});this._addKey(v);var E=function(w,D,F,G){C.split.action.call(D.button(d("div.dt-btn-split-wrapper")[0]),w,D,F,G);d(D.table().node()).triggerHandler("buttons-action.dt",[D.button(F),D,F,G]);F.attr("aria-expanded",!0)},A=d('").on("click.dtb",function(w){w.preventDefault();w.stopPropagation(); +A.hasClass(h.disabled)||E(w,r,A,v);y&&A.trigger("blur")}).on("keypress.dtb",function(w){13===w.keyCode&&(w.preventDefault(),A.hasClass(h.disabled)||E(w,r,A,v))});0===a.split.length&&A.addClass("dtb-hide-drop");n.append(A).attr(v.attr)}return{conf:a,node:c?n.get(0):k.get(0),inserter:c?n:f,buttons:[],inCollection:b,isSplit:c,inSplit:e,collection:null}},_nodeToButton:function(a,b){b||(b=this.s.buttons);for(var c=0,e=b.length;c").addClass("dt-button-collection").addClass(f.collectionLayout).addClass(f.splitAlignClass).addClass(e).css("display","none");a=d(a).addClass(f.contentClassName).attr("role","menu").appendTo(m);g.attr("aria-expanded","true");g.parents("body")[0]!== +B.body&&(g=B.body.lastChild);f.popoverTitle?m.prepend('
'+f.popoverTitle+"
"):f.collectionTitle&&m.prepend('
'+f.collectionTitle+"
");f.closeButton&&m.prepend('
x
').addClass("dtb-collection-closeable");I(m.insertAfter(g),f.fade);c=d(b.table().container());var r=m.css("position");if("container"===f.span||"dt-container"===f.align)g=g.parent(),m.css("width",c.width());if("absolute"=== +r){var q=d(g[0].offsetParent);c=g.position();e=g.offset();var n=q.offset(),k=q.position(),t=z.getComputedStyle(q[0]);n.height=q.outerHeight();n.width=q.width()+parseFloat(t.paddingLeft);n.right=n.left+n.width;n.bottom=n.top+n.height;q=c.top+g.outerHeight();var y=c.left;m.css({top:q,left:y});t=z.getComputedStyle(m[0]);var v=m.offset();v.height=m.outerHeight();v.width=m.outerWidth();v.right=v.left+v.width;v.bottom=v.top+v.height;v.marginTop=parseFloat(t.marginTop);v.marginBottom=parseFloat(t.marginBottom); +f.dropup&&(q=c.top-v.height-v.marginTop-v.marginBottom);if("button-right"===f.align||m.hasClass(f.rightAlignClassName))y=c.left-v.width+g.outerWidth();if("dt-container"===f.align||"container"===f.align)yn.width&&(y=n.width-v.width);k.left+y+v.width>d(z).width()&&(y=d(z).width()-v.width-k.left);0>e.left+y&&(y=-e.left);k.top+q+v.height>d(z).height()+d(z).scrollTop()&&(q=c.top-v.height-v.marginTop-v.marginBottom);k.top+qE&&(A=E);m.css("marginTop",-1*A)},r(),d(z).on("resize.dtb-collection",function(){r()});f.background&&x.background(!0,f.backgroundClassName,f.fade,f.backgroundHost||g);d("div.dt-button-background").on("click.dtb-collection",function(){});f.autoClose&&setTimeout(function(){b.on("buttons-action.b-internal",function(E,A,w,D){D[0]!==g[0]&&l()})},0);d(m).trigger("buttons-popover.dt");b.on("destroy",l);setTimeout(function(){h=!1;d("body").on("click.dtb-collection", +function(E){if(!h){var A=d.fn.addBack?"addBack":"andSelf",w=d(E.target).parent()[0];(!d(E.target).parents()[A]().filter(a).length&&!d(w).hasClass("dt-buttons")||d(E.target).hasClass("dt-button-background"))&&l()}}).on("keyup.dtb-collection",function(E){27===E.keyCode&&l()})},0)}}});x.background=function(a,b,c,e){c===p&&(c=400);e||(e=B.body);a?I(d("
").addClass(b).css("display","none").insertAfter(e),c):J(d("div."+b),c,function(){d(this).removeClass(b).remove()})};x.instanceSelector=function(a, +b){if(a===p||null===a)return d.map(b,function(f){return f.inst});var c=[],e=d.map(b,function(f){return f.name}),h=function(f){if(Array.isArray(f))for(var g=0,l=f.length;g)<[^<]*)*<\/script>/gi,"");a=a.replace(//g,"");if(!b||b.stripHtml)a=a.replace(/<[^>]*>/g,"");if(!b||b.trim)a=a.replace(/^\s+|\s+$/g,"");if(!b||b.stripNewlines)a=a.replace(/\n/g," ");if(!b||b.decodeEntities)M.innerHTML=a,a=M.value;return a};x.defaults={buttons:["copy","excel","csv","pdf","print"],name:"main",tabIndex:0,dom:{container:{tag:"div",className:"dt-buttons"},collection:{tag:"div",className:""},button:{tag:"button", +className:"dt-button",active:"active",disabled:"disabled",spacerClass:""},buttonLiner:{tag:"span",className:""},split:{tag:"div",className:"dt-button-split"},splitWrapper:{tag:"div",className:"dt-btn-split-wrapper"},splitDropdown:{tag:"button",text:"▼",className:"dt-btn-split-drop",align:"split-right",splitAlignClass:"dt-button-split-left"},splitDropdownButton:{tag:"button",className:"dt-btn-split-drop-button dt-button"},splitCollection:{tag:"div",className:"dt-button-split-collection"}}}; +x.version="2.2.2";d.extend(C,{collection:{text:function(a){return a.i18n("buttons.collection","Collection")},className:"buttons-collection",closeButton:!1,init:function(a,b,c){b.attr("aria-expanded",!1)},action:function(a,b,c,e){e._collection.parents("body").length?this.popover(!1,e):this.popover(e._collection,e)},attr:{"aria-haspopup":!0}},split:{text:function(a){return a.i18n("buttons.split","Split")},className:"buttons-split",closeButton:!1,init:function(a,b,c){return b.attr("aria-expanded",!1)}, +action:function(a,b,c,e){this.popover(e._collection,e)},attr:{"aria-haspopup":!0}},copy:function(a,b){if(C.copyHtml5)return"copyHtml5"},csv:function(a,b){if(C.csvHtml5&&C.csvHtml5.available(a,b))return"csvHtml5"},excel:function(a,b){if(C.excelHtml5&&C.excelHtml5.available(a,b))return"excelHtml5"},pdf:function(a,b){if(C.pdfHtml5&&C.pdfHtml5.available(a,b))return"pdfHtml5"},pageLength:function(a){a=a.settings()[0].aLengthMenu;var b=[],c=[];if(Array.isArray(a[0]))b=a[0],c=a[1];else for(var e=0;e"+a+"":"";I(d('
').html(a).append(d("
")["string"=== +typeof b?"html":"append"](b)).css("display","none").appendTo("body"));c!==p&&0!==c&&(H=setTimeout(function(){e.buttons.info(!1)},c));this.on("destroy.btn-info",function(){e.buttons.info(!1)});return this});u.Api.register("buttons.exportData()",function(a){if(this.context.length)return Q(new u.Api(this.context[0]),a)});u.Api.register("buttons.exportInfo()",function(a){a||(a={});var b=a;var c="*"===b.filename&&"*"!==b.title&&b.title!==p&&null!==b.title&&""!==b.title?b.title:b.filename;"function"=== +typeof c&&(c=c());c===p||null===c?c=null:(-1!==c.indexOf("*")&&(c=c.replace("*",d("head > title").text()).trim()),c=c.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,""),(b=K(b.extension))||(b=""),c+=b);b=K(a.title);b=null===b?null:-1!==b.indexOf("*")?b.replace("*",d("head > title").text()||"Exported data"):b;return{filename:c,title:b,messageTop:N(this,a.message||a.messageTop,"top"),messageBottom:N(this,a.messageBottom,"bottom")}});var K=function(a){return null===a||a===p?null:"function"===typeof a? +a():a},N=function(a,b,c){b=K(b);if(null===b)return null;a=d("caption",a.table().container()).eq(0);return"*"===b?a.css("caption-side")!==c?null:a.length?a.text():"":b},M=d("
" . $result->name . " " . $editget . "<?php echo JLayoutHelper::render('" . ComponentbuilderHelper::safeString($result->alias) . "', \$this->item); ?> " . $edit . "" . $result->name . " " . $editget . "<?php echo JLayoutHelper::render('" . StringHelper::safe($result->alias) . "', \$this->item); ?> " . $edit . "" . $result->name . " " . $editget . "<?php echo JLayoutHelper::render('" . ComponentbuilderHelper::safeString($result->alias) . "', \$this->items); ?> " . $edit . "" . $result->name . " " . $editget . "<?php echo JLayoutHelper::render('" . StringHelper::safe($result->alias) . "', \$this->items); ?> " . $edit . "" . $result->name . " " . $editget . "<?php echo JLayoutHelper::render('" . ComponentbuilderHelper::safeString($result->alias) . "', \$this->" . $varName . "); ?> " . $edit . "" . $result->name . " " . $editget . "<?php echo JLayoutHelper::render('" . StringHelper::safe($result->alias) . "', \$this->" . $varName . "); ?> " . $edit . "" . JText::_('COM_COMPONENTBUILDER_NONE_SELECTED') . "<?php echo JLayoutHelper::render('" . ComponentbuilderHelper::safeString($result->alias) . "', [?]); ?> " . $edit . "" . JText::_('COM_COMPONENTBUILDER_NONE_SELECTED') . "<?php echo JLayoutHelper::render('" . StringHelper::safe($result->alias) . "', [?]); ?> " . $edit . " -
joomla_plugin_group) && ComponentbuilderHelper::checkString($item->joomla_plugin_group)): ?> +
joomla_plugin_group) && StringHelper::check($item->joomla_plugin_group)): ?> extension_type); ?> : escape($item->joomla_plugin_group_name); ?> diff --git a/admin/views/class_properties/view.html.php b/admin/views/class_properties/view.html.php index 654de35c1..58201f0e2 100644 --- a/admin/views/class_properties/view.html.php +++ b/admin/views/class_properties/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewClass_properties extends HtmlView $this->canState = $this->canDo->get('class_property.edit.state'); $this->canCreate = $this->canDo->get('class_property.create'); $this->canDelete = $this->canDo->get('class_property.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('class_property.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/compiler/tmpl/default.php b/admin/views/compiler/tmpl/default.php index 9618879fe..744feffb5 100644 --- a/admin/views/compiler/tmpl/default.php +++ b/admin/views/compiler/tmpl/default.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); JHtml::_('behavior.formvalidator'); @@ -25,7 +26,6 @@ $selectNotice .= '

' . JText::_('COM_COMPONENTBUILDER_PLEASE_SELECT_A_COMPONEN $noticeboardOptions = array('vdm', 'pro'); ?> canDo->get('compiler.access')): ?> -

- - -

diff --git a/admin/views/compiler/view.html.php b/admin/views/compiler/view.html.php index 689e0509d..2a47eff3e 100644 --- a/admin/views/compiler/view.html.php +++ b/admin/views/compiler/view.html.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\View\HtmlView; use Joomla\CMS\Filesystem\File; +use Joomla\CMS\Form\Form; +use VDM\Joomla\Utilities\ArrayHelper; /** * Componentbuilder Html View class for the Compiler @@ -40,11 +42,18 @@ class ComponentbuilderViewCompiler extends HtmlView JHtmlSidebar::setAction('index.php?option=com_componentbuilder&view=compiler'); $this->sidebar = JHtmlSidebar::render(); } + // get the success message if set $this->SuccessMessage = $this->app->getUserState('com_componentbuilder.success_message', false); + + // get active components $this->Components = $this->get('Components'); - $this->form = $this->setForm(); + + // get the needed form fields + $this->form = $this->getDynamicForm(); + // set the compiler artwork from global settings $this->builder_gif_size = $this->params->get('builder_gif_size', '480-272'); + // only run these checks if he has access if ($this->canDo->get('compiler.compiler_animations')) { @@ -56,10 +65,17 @@ class ComponentbuilderViewCompiler extends HtmlView // we count of all the files are already there else { + $directory_path = JPATH_ROOT . "/administrator/components/com_componentbuilder/assets/images/builder-gif"; // get all the gif files in the gif folder - $all_gifs = scandir(JPATH_ROOT . "/administrator/components/com_componentbuilder/assets/images/builder-gif"); + $all_gifs = null; + if (is_dir($directory_path) && is_readable($directory_path)) + { + $all_gifs = scandir($directory_path); + + } + // check if we have any values - if (ComponentbuilderHelper::checkArray($all_gifs)) + if ($all_gifs !== null && ArrayHelper::check($all_gifs)) { // count number of files but remove the 2 dot values $num_gifs = count($all_gifs) - 2; @@ -96,121 +112,440 @@ class ComponentbuilderViewCompiler extends HtmlView // JLayoutHelper::render('sectionjcb', [?]); // added to ensure the layout are loaded // JLayoutHelper::render('repeatablejcb', [?]); // added to ensure the layout are loaded - public function setForm() + /** + * Get the dynamic build form fields needed on the page + * + * @return Form|null The form fields + * + * @since 3.2.0 + */ + public function getDynamicForm(): ?Form { - if(ComponentbuilderHelper::checkArray($this->Components)) + if(ArrayHelper::check($this->Components)) { // start the form - $form = array(); + $form = new Form('Builder'); + + $form->load('
+
+
+
'); + // sales attributes - $attributes = array( + $attributes = [ 'type' => 'radio', 'name' => 'backup', 'label' => 'COM_COMPONENTBUILDER_ADD_TO_BACKUP_FOLDER_AMP_SALES_SERVER_SMALLIF_SETSMALL', 'class' => 'btn-group btn-group-yesno', 'description' => 'COM_COMPONENTBUILDER_SHOULD_THE_ZIPPED_PACKAGE_OF_THE_COMPONENT_BE_MOVED_TO_THE_LOCAL_BACKUP_AND_REMOTE_SALES_SERVER_THIS_IS_ONLY_APPLICABLE_IF_THIS_COMPONENT_HAS_THOSE_VALUES_SET', - 'default' => '0'); + 'default' => '0']; // set the sales options - $options = array( + $options = [ '1' => 'COM_COMPONENTBUILDER_YES', - '0' => 'COM_COMPONENTBUILDER_NO'); + '0' => 'COM_COMPONENTBUILDER_NO']; + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, 0, $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + // repository attributes - $attributes = array( + $attributes = [ 'type' => 'radio', 'name' => 'repository', 'label' => 'COM_COMPONENTBUILDER_ADD_TO_REPOSITORY_FOLDER', 'class' => 'btn-group btn-group-yesno', 'description' => 'COM_COMPONENTBUILDER_SHOULD_THE_COMPONENT_BE_MOVED_TO_YOUR_LOCAL_REPOSITORY_FOLDER', - 'default' => '1'); + 'default' => '1']; // start the repository options - $options = array( + $options = [ '1' => 'COM_COMPONENTBUILDER_YES', - '0' => 'COM_COMPONENTBUILDER_NO'); + '0' => 'COM_COMPONENTBUILDER_NO']; + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, 1, $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + // placeholders attributes - $attributes = array( + $attributes = [ 'type' => 'radio', - 'name' => 'placeholders', + 'name' => 'add_placeholders', 'label' => 'COM_COMPONENTBUILDER_ADD_CUSTOM_CODE_PLACEHOLDERS', 'class' => 'btn-group btn-group-yesno', 'description' => 'COM_COMPONENTBUILDER_SHOULD_JCB_INSERT_THE_CUSTOM_CODE_PLACEHOLDERS_THIS_IS_ONLY_APPLICABLE_IF_THIS_COMPONENT_HAS_CUSTOM_CODE', - 'default' => '2'); + 'default' => '2']; // start the placeholders options - $options = array( + $options = [ '2' => 'COM_COMPONENTBUILDER_GLOBAL', '1' => 'COM_COMPONENTBUILDER_YES', - '0' => 'COM_COMPONENTBUILDER_NO'); + '0' => 'COM_COMPONENTBUILDER_NO']; + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, 2, $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + // debuglinenr attributes - $attributes = array( + $attributes = [ 'type' => 'radio', - 'name' => 'debuglinenr', + 'name' => 'debug_line_nr', 'label' => 'COM_COMPONENTBUILDER_DEBUG_LINE_NUMBERS', 'class' => 'btn-group btn-group-yesno', 'description' => 'COM_COMPONENTBUILDER_ADD_CORRESPONDING_LINE_NUMBERS_TO_THE_DYNAMIC_COMMENTS_SO_TO_SEE_WHERE_IN_THE_COMPILER_THE_LINES_OF_CODE_WAS_BUILD_THIS_WILL_HELP_IF_YOU_NEED_TO_GET_MORE_TECHNICAL_WITH_AN_ISSUE_ON_GITHUB_OR_EVEN_FOR_YOUR_OWN_DEBUGGING', - 'default' => '2'); - $options = array( + 'default' => '2']; + $options = [ '2' => 'COM_COMPONENTBUILDER_GLOBAL', '1' => 'COM_COMPONENTBUILDER_YES', - '0' => 'COM_COMPONENTBUILDER_NO'); + '0' => 'COM_COMPONENTBUILDER_NO']; + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, 2, $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + // minify attributes - $attributes = array( + $attributes = [ 'type' => 'radio', 'name' => 'minify', 'label' => 'COM_COMPONENTBUILDER_MINIFY_JAVASCRIPT', 'class' => 'btn-group btn-group-yesno', 'description' => 'COM_COMPONENTBUILDER_SHOULD_THE_JAVASCRIPT_BE_MINIFIED_IN_THE_COMPONENT', - 'default' => '2'); - $options = array( + 'default' => '2']; + $options = [ '2' => 'COM_COMPONENTBUILDER_GLOBAL', '1' => 'COM_COMPONENTBUILDER_YES', - '0' => 'COM_COMPONENTBUILDER_NO'); + '0' => 'COM_COMPONENTBUILDER_NO']; + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, 2, $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + // powers attributes - $attributes = array( + $attributes = [ 'type' => 'radio', 'name' => 'powers', 'label' => 'COM_COMPONENTBUILDER_ADD_POWERS', 'class' => 'btn-group btn-group-yesno', 'description' => 'COM_COMPONENTBUILDER_SHOULD_JCB_ADD_ANY_POWERS_THAT_ARE_CONNECTED_TO_THIS_COMPONENT_THIS_MAY_BE_HELPFUL_IF_YOU_ARE_LOADING_POWERS_VIA_ANOTHER_COMPONENT_AND_WOULD_LIKE_TO_AVOID_ADDING_IT_TO_BOTH_JUST_REMEMBER_THAT_IN_THIS_CASE_YOU_NEED_TO_LOAD_THE_POWERS_VIA_A_PLUGIN', - 'default' => '2'); - $options = array( + 'default' => '2']; + $options = [ '2' => 'COM_COMPONENTBUILDER_GLOBAL', '1' => 'COM_COMPONENTBUILDER_YES', - '0' => 'COM_COMPONENTBUILDER_NO'); + '0' => 'COM_COMPONENTBUILDER_NO']; + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, 2, $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + // component attributes - $attributes = array( + $attributes = [ 'type' => 'list', - 'name' => 'component', + 'name' => 'component_id', 'label' => 'COM_COMPONENTBUILDER_COMPONENTS', 'class' => 'list_class', 'description' => 'COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_COMPILE', - 'required' => 'true'); + 'required' => 'true']; // start the component options - $options = array(); + $options = []; $options[''] = 'COM_COMPONENTBUILDER__SELECT_COMPONENT_'; // load component options from array foreach($this->Components as $component) { $options[(int) $component->id] = $this->escape($component->name); } + // add to form - $form[] = ComponentbuilderHelper::getFieldObject($attributes, '', $options); + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + + // Advanced Options + $attributes = [ + 'type' => 'radio', + 'name' => 'show_advanced_options', + 'label' => 'COM_COMPONENTBUILDER_SHOW_ADVANCED_OPTIONS', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_SEE_THE_ADVANCED_COMPILER_OPTIONS', + 'default' => '0']; + // start the advanced options switch + $options = [ + '1' => 'COM_COMPONENTBUILDER_YES', + '0' => 'COM_COMPONENTBUILDER_NO']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'builder'); + } + + // Advanced Options note attributes + $attributes = [ + 'type' => 'note', + 'name' => 'show_advanced_options_note', + 'label' => "COM_COMPONENTBUILDER_ADVANCED_OPTIONS", + 'heading' => 'h3', + 'showon' => 'show_advanced_options:1']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Joomla Versions attributes + $attributes = [ + 'type' => 'radio', + 'name' => 'joomla_version_donations', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_VERSION', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_WHAT_VERSION_OF_JOOMLA_WOULD_YOU_LIKE_TO_TARGET', + 'default' => '3', + 'showon' => 'show_advanced_options:1']; + // start the joomla versions options + $options = [ + '3' => 'COM_COMPONENTBUILDER_JOOMLA_THREE', + '4' => 'COM_COMPONENTBUILDER_JOOMLA_FOUR']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Joomla Version 3 attributes + $attributes = [ + 'type' => 'note', + 'name' => 'joomla_version_note_three', + 'description' => 'COM_COMPONENTBUILDER_YOUR_COMPONENT_WILL_BE_COMPILED_TO_WORK_IN_JOOMLA_THREE', + 'class' => 'alert alert-success', + 'showon' => 'show_advanced_options:1[AND]joomla_version_donations:3']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Joomla Version 4 attributes + $attributes = [ + 'type' => 'note', + 'name' => 'joomla_version_note_four', + 'description' => 'COM_COMPONENTBUILDER_JCB_IS_NOT_YET_FULLY_READY_FOR_JOOMLA_FOUR_BUT_WITH_YOUR_HELP_WE_CAN_MAKE_THE_TRANSITION_FASTER_SHOW_YOUR_SUPPORT_BY_MAKING_A_DONATION_TODAY_AND_HELP_US_BRING_JCB_TO_THE_NEXT_LEVELBR_BR_BYOUR_COMPONENT_WILL_STILL_ONLY_BE_COMPILED_FOR_JOOMLA_THREEB', + 'class' => 'alert alert-info', + 'showon' => 'show_advanced_options:1[AND]joomla_version_donations:4']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // powers repository attributes + $attributes = [ + 'type' => 'radio', + 'name' => 'powers_repository', + 'label' => 'COM_COMPONENTBUILDER_ACTIVATE_SUPER_POWERS', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_THIS_ADDS_POWERS_TO_A_LOCAL_REPOSITORY_FOLDER_ALL_BAPPROVEDB_POWERS_LINKED_TO_THIS_COMPONENT_WILL_BE_MOVED_TO_YOUR_BLOCALB_POWERS_REPOSITORY_FOLDER_INTO_THEIR_SELECTIVE_TARGET_PATHS_THIS_LOCAL_FOLDER_PATH_MUST_BE_SET_IN_THE_GLOBAL_OPTIONS_OF_JCB_UNDER_THE_BSUPER_POWERB_TAB', + 'default' => '2', + 'showon' => 'show_advanced_options:1']; + // start the repository options + $options = [ + '2' => 'COM_COMPONENTBUILDER_GLOBAL', + '1' => 'COM_COMPONENTBUILDER_YES', + '0' => 'COM_COMPONENTBUILDER_NO']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // powers local path to repositories attributes + $attributes = [ + 'type' => 'text', + 'name' => 'local_powers_repository_path', + 'label' => 'COM_COMPONENTBUILDER_LOCAL_POWERS_REPOSITORY_PATH', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_HERE_YOU_CAN_SET_THE_PATH_TO_THE_SUPER_POWERS_LOCAL_REPOSITORY_FOLDER_WHERE_BLAYERCOREB_AND_ALL_TARGETED_BLAYEROWNB_SUB_PATHS_WILL_BE_PLACED_WITH_THEIR_SELECTIVE_BSWITCHAPPROVEDB_POWERS', + 'default' => $this->params->get('local_powers_repository_path', ''), + 'showon' => 'show_advanced_options:1[AND]powers_repository:1']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Indentation attributes + $attributes = [ + 'type' => 'radio', + 'name' => 'indentation_value', + 'label' => 'COM_COMPONENTBUILDER_INDENTATION_OPTIONS', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_WHICH_TYPE_OF_INDENTATION_WOULD_YOU_LIKE_TO_USE_PLEASE_NOTE_THAT_THIS_DOES_NOT_YET_IMPACT_THE_STATIC_TEMPLATES', + 'default' => '1', + 'showon' => 'show_advanced_options:1']; + + // start the indentation options + $options = [ + '1' => 'COM_COMPONENTBUILDER_TAB', + '2' => 'COM_COMPONENTBUILDER_TWO_SPACES', + '4' => 'COM_COMPONENTBUILDER_FOUR_SPACES']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Build date attributes + $attributes = [ + 'type' => 'radio', + 'name' => 'add_build_date', + 'label' => 'COM_COMPONENTBUILDER_BUILD_DATE', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_OVERRIDE_THE_BUILD_DATE', + 'default' => '1', + 'showon' => 'show_advanced_options:1']; + // start the build date options + $options = [ + '1' => 'COM_COMPONENTBUILDER_DEFAULT', + '2' => 'COM_COMPONENTBUILDER_MANUAL', + '3' => 'COM_COMPONENTBUILDER_COMPONENT']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Build date note attributes + $attributes = [ + 'type' => 'note', + 'name' => 'add_build_date_note_two', + 'description' => 'COM_COMPONENTBUILDER_ALLOWS_YOU_TO_OVERRIDE_THE_BUILD_DATE_BY_SELECTING_A_DATE_MANUALLY_FROM_THE_CALENDER', + 'class' => 'alert alert-info', + 'showon' => 'show_advanced_options:1[AND]add_build_date:2']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Build date note attributes + $attributes = [ + 'type' => 'note', + 'name' => 'add_build_date_note_three', + 'description' => "COM_COMPONENTBUILDER_THE_COMPONENTS_LAST_MODIFIED_DATE_WILL_BE_USED", + 'class' => 'alert alert-info', + 'showon' => 'show_advanced_options:1[AND]add_build_date:3']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Build date calendar attributes + $attributes = [ + 'type' => 'calendar', + 'name' => 'build_date', + 'label' => 'COM_COMPONENTBUILDER_SELECT_BUILD_DATE', + 'format' => '%Y-%m-%d', + 'filter' => 'user_utc', + 'default' => 'now', + 'size' => '22', + 'showon' => 'show_advanced_options:1[AND]add_build_date:2']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Build date note attributes + $attributes = [ + 'type' => 'note', + 'name' => 'donations_note', + 'label' => "COM_COMPONENTBUILDER_DONATIONS", + 'description' => $this->getSupportMessage(), + 'class' => 'alert alert-success', + 'heading' => 'h1', + 'showon' => 'show_advanced_options:1']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // Build date note line attributes + $attributes = [ + 'type' => 'note', + 'name' => 'donations_note_line', + 'description' => '
', + 'showon' => 'show_advanced_options:1']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } // return the form array return $form; } - return false; - } + + return null; + } + + /** + * Get the dynamic support request/gratitude message + * + * @return string The support message + * + * @since 3.2.0 + */ + protected function getSupportMessage(): string + { + return JLayoutHelper::render('jcbsupportmessage', []); + } + /** * Prepares the document @@ -218,8 +553,11 @@ class ComponentbuilderViewCompiler extends HtmlView protected function setDocument() { - // always make sure jquery is loaded. - JHtml::_('jquery.framework'); + // Only load jQuery if needed. (default is true) + if ($this->params->get('add_jquery_framework', 1) == 1) + { + JHtml::_('jquery.framework'); + } // Load the header checker class. require_once( JPATH_COMPONENT_ADMINISTRATOR.'/helpers/headercheck.php' ); // Initialize the header checker. @@ -294,7 +632,7 @@ class ComponentbuilderViewCompiler extends HtmlView // add marked library $this->document->addScript(JURI::root() . "administrator/components/com_componentbuilder/custom/marked.js"); // add the document default css file - $this->document->addStyleSheet(JURI::root(true) .'/administrator/components/com_componentbuilder/assets/css/compiler.css', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + JHtml::_('stylesheet', 'administrator/components/com_componentbuilder/assets/css/compiler.css', ['version' => 'auto']); // Set the Custom JS script to view $this->document->addScriptDeclaration(" function getComponentDetails_server(id){ @@ -396,7 +734,7 @@ class ComponentbuilderViewCompiler extends HtmlView if ($this->canDo->get('compiler.compiler_animations')) { // add Compiler Animations button. - JToolBarHelper::custom('compiler.getCompilerAnimations', 'download custom-button-getcompileranimations', '', 'COM_COMPONENTBUILDER_COMPILER_ANIMATIONS', false); + JToolBarHelper::custom('compiler.getDynamicContent', 'download custom-button-getdynamiccontent', '', 'COM_COMPONENTBUILDER_COMPILER_ANIMATIONS', false); } if ($this->canDo->get('compiler.clear_tmp')) { diff --git a/admin/views/components_admin_views/view.html.php b/admin/views/components_admin_views/view.html.php index 72c91a491..f1943e4c8 100644 --- a/admin/views/components_admin_views/view.html.php +++ b/admin/views/components_admin_views/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_admin_views extends HtmlView $this->canState = $this->canDo->get('component_admin_views.edit.state'); $this->canCreate = $this->canDo->get('component_admin_views.create'); $this->canDelete = $this->canDo->get('component_admin_views.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_admin_views.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_config/view.html.php b/admin/views/components_config/view.html.php index 5fa22d9ed..4d0d8d298 100644 --- a/admin/views/components_config/view.html.php +++ b/admin/views/components_config/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_config extends HtmlView $this->canState = $this->canDo->get('component_config.edit.state'); $this->canCreate = $this->canDo->get('component_config.create'); $this->canDelete = $this->canDo->get('component_config.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_config.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_custom_admin_menus/view.html.php b/admin/views/components_custom_admin_menus/view.html.php index dbe9a58b7..8e3075413 100644 --- a/admin/views/components_custom_admin_menus/view.html.php +++ b/admin/views/components_custom_admin_menus/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_custom_admin_menus extends HtmlView $this->canState = $this->canDo->get('component_custom_admin_menus.edit.state'); $this->canCreate = $this->canDo->get('component_custom_admin_menus.create'); $this->canDelete = $this->canDo->get('component_custom_admin_menus.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_custom_admin_menus.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_custom_admin_views/view.html.php b/admin/views/components_custom_admin_views/view.html.php index 1e7947fa0..b59abfe7f 100644 --- a/admin/views/components_custom_admin_views/view.html.php +++ b/admin/views/components_custom_admin_views/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_custom_admin_views extends HtmlView $this->canState = $this->canDo->get('component_custom_admin_views.edit.state'); $this->canCreate = $this->canDo->get('component_custom_admin_views.create'); $this->canDelete = $this->canDo->get('component_custom_admin_views.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_custom_admin_views.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_dashboard/view.html.php b/admin/views/components_dashboard/view.html.php index f849017d6..d0272e3b6 100644 --- a/admin/views/components_dashboard/view.html.php +++ b/admin/views/components_dashboard/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_dashboard extends HtmlView $this->canState = $this->canDo->get('component_dashboard.edit.state'); $this->canCreate = $this->canDo->get('component_dashboard.create'); $this->canDelete = $this->canDo->get('component_dashboard.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_dashboard.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_files_folders/view.html.php b/admin/views/components_files_folders/view.html.php index 141842b79..e84fddcdc 100644 --- a/admin/views/components_files_folders/view.html.php +++ b/admin/views/components_files_folders/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_files_folders extends HtmlView $this->canState = $this->canDo->get('component_files_folders.edit.state'); $this->canCreate = $this->canDo->get('component_files_folders.create'); $this->canDelete = $this->canDo->get('component_files_folders.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_files_folders.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_modules/view.html.php b/admin/views/components_modules/view.html.php index 0bcd03b6e..95d6f6d0b 100644 --- a/admin/views/components_modules/view.html.php +++ b/admin/views/components_modules/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_modules extends HtmlView $this->canState = $this->canDo->get('component_modules.edit.state'); $this->canCreate = $this->canDo->get('component_modules.create'); $this->canDelete = $this->canDo->get('component_modules.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_modules.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_mysql_tweaks/view.html.php b/admin/views/components_mysql_tweaks/view.html.php index 1afbdf26f..88094a7de 100644 --- a/admin/views/components_mysql_tweaks/view.html.php +++ b/admin/views/components_mysql_tweaks/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_mysql_tweaks extends HtmlView $this->canState = $this->canDo->get('component_mysql_tweaks.edit.state'); $this->canCreate = $this->canDo->get('component_mysql_tweaks.create'); $this->canDelete = $this->canDo->get('component_mysql_tweaks.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_mysql_tweaks.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_placeholders/view.html.php b/admin/views/components_placeholders/view.html.php index 5ac481531..6e0b1a526 100644 --- a/admin/views/components_placeholders/view.html.php +++ b/admin/views/components_placeholders/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_placeholders extends HtmlView $this->canState = $this->canDo->get('component_placeholders.edit.state'); $this->canCreate = $this->canDo->get('component_placeholders.create'); $this->canDelete = $this->canDo->get('component_placeholders.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_placeholders.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_plugins/view.html.php b/admin/views/components_plugins/view.html.php index be86bdaf1..da7c53e35 100644 --- a/admin/views/components_plugins/view.html.php +++ b/admin/views/components_plugins/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_plugins extends HtmlView $this->canState = $this->canDo->get('component_plugins.edit.state'); $this->canCreate = $this->canDo->get('component_plugins.create'); $this->canDelete = $this->canDo->get('component_plugins.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_plugins.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_site_views/view.html.php b/admin/views/components_site_views/view.html.php index 5a09c7b3b..6f60f7f6a 100644 --- a/admin/views/components_site_views/view.html.php +++ b/admin/views/components_site_views/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_site_views extends HtmlView $this->canState = $this->canDo->get('component_site_views.edit.state'); $this->canCreate = $this->canDo->get('component_site_views.create'); $this->canDelete = $this->canDo->get('component_site_views.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_site_views.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/components_updates/view.html.php b/admin/views/components_updates/view.html.php index 8f6669b3e..5c5b3b7b6 100644 --- a/admin/views/components_updates/view.html.php +++ b/admin/views/components_updates/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewComponents_updates extends HtmlView $this->canState = $this->canDo->get('component_updates.edit.state'); $this->canCreate = $this->canDo->get('component_updates.create'); $this->canDelete = $this->canDo->get('component_updates.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('component_updates.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/custom_admin_views/tmpl/default_body.php b/admin/views/custom_admin_views/tmpl/default_body.php index b8ce6316b..c66378b18 100644 --- a/admin/views/custom_admin_views/tmpl/default_body.php +++ b/admin/views/custom_admin_views/tmpl/default_body.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; $edit = "index.php?option=com_componentbuilder&view=custom_admin_views&task=custom_admin_view.edit"; @@ -74,7 +75,7 @@ $edit = "index.php?option=com_componentbuilder&view=custom_admin_views&task=cust escape($item->name); ?>
: escape($item->codename); ?>
- context)): ?> + context)): ?> : escape($item->context); ?> diff --git a/admin/views/custom_admin_views/view.html.php b/admin/views/custom_admin_views/view.html.php index 619068a0f..f8675e470 100644 --- a/admin/views/custom_admin_views/view.html.php +++ b/admin/views/custom_admin_views/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewCustom_admin_views extends HtmlView $this->canState = $this->canDo->get('core.edit.state'); $this->canCreate = $this->canDo->get('core.create'); $this->canDelete = $this->canDo->get('core.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('custom_admin_view.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/custom_codes/view.html.php b/admin/views/custom_codes/view.html.php index 7c8c067d0..4c9274739 100644 --- a/admin/views/custom_codes/view.html.php +++ b/admin/views/custom_codes/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewCustom_codes extends HtmlView $this->canState = $this->canDo->get('custom_code.edit.state'); $this->canCreate = $this->canDo->get('custom_code.create'); $this->canDelete = $this->canDo->get('custom_code.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('custom_code.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/dynamic_gets/view.html.php b/admin/views/dynamic_gets/view.html.php index e533b37ff..c6c300e2d 100644 --- a/admin/views/dynamic_gets/view.html.php +++ b/admin/views/dynamic_gets/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewDynamic_gets extends HtmlView $this->canState = $this->canDo->get('dynamic_get.edit.state'); $this->canCreate = $this->canDo->get('dynamic_get.create'); $this->canDelete = $this->canDo->get('dynamic_get.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('dynamic_get.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/fields/view.html.php b/admin/views/fields/view.html.php index 7cf2398ac..e37e8b641 100644 --- a/admin/views/fields/view.html.php +++ b/admin/views/fields/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewFields extends HtmlView $this->canState = $this->canDo->get('field.edit.state'); $this->canCreate = $this->canDo->get('field.create'); $this->canDelete = $this->canDo->get('field.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('field.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/fieldtypes/view.html.php b/admin/views/fieldtypes/view.html.php index fb5a53fff..9fa379881 100644 --- a/admin/views/fieldtypes/view.html.php +++ b/admin/views/fieldtypes/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewFieldtypes extends HtmlView $this->canState = $this->canDo->get('fieldtype.edit.state'); $this->canCreate = $this->canDo->get('fieldtype.create'); $this->canDelete = $this->canDo->get('fieldtype.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('fieldtype.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/get_snippets/view.html.php b/admin/views/get_snippets/view.html.php index efe9c8218..af14e980b 100644 --- a/admin/views/get_snippets/view.html.php +++ b/admin/views/get_snippets/view.html.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\View\HtmlView; use Joomla\CMS\Filesystem\File; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; /** * Componentbuilder Html View class for the Get_snippets @@ -59,15 +61,18 @@ class ComponentbuilderViewGet_snippets extends HtmlView protected function setDocument() { - // always make sure jquery is loaded. - JHtml::_('jquery.framework'); + // Only load jQuery if needed. (default is true) + if ($this->params->get('add_jquery_framework', 1) == 1) + { + JHtml::_('jquery.framework'); + } // Load the header checker class. require_once( JPATH_COMPONENT_ADMINISTRATOR.'/helpers/headercheck.php' ); // Initialize the header checker. $HeaderCheck = new componentbuilderHeaderCheck; // Add View JavaScript File - $this->document->addScript(JURI::root(true) . "/administrator/components/com_componentbuilder/assets/js/get_snippets.js", (ComponentbuilderHelper::jVersion()->isCompatible("3.8.0")) ? array("version" => "auto") : "text/javascript"); + JHtml::_('script', "administrator/components/com_componentbuilder/assets/js/get_snippets.js", ['version' => 'auto']); // Load uikit options. $uikit = $this->params->get('uikit_load'); @@ -92,7 +97,6 @@ class ComponentbuilderViewGet_snippets extends HtmlView { // Set the default uikit components in this view. $uikitComp = array(); - $uikitComp[] = 'UIkit.notify'; $uikitComp[] = 'data-uk-grid'; } @@ -122,12 +126,12 @@ class ComponentbuilderViewGet_snippets extends HtmlView } } // load the local snippets - if (ComponentbuilderHelper::checkArray($this->items)) + if (ArrayHelper::check($this->items)) { $local_snippets = array(); foreach ($this->items as $item) { - $path = ComponentbuilderHelper::safeString($item->library . ' - (' . $item->type . ') ' . $item->name, 'filename', '', false). '.json'; + $path = StringHelper::safe($item->library . ' - (' . $item->type . ') ' . $item->name, 'filename', '', false). '.json'; $local_snippets[$path] = $item; } } @@ -237,13 +241,13 @@ class ComponentbuilderViewGet_snippets extends HtmlView } "); // load the local snippets - if (ComponentbuilderHelper::checkArray($this->items)) + if (ArrayHelper::check($this->items)) { // Set the local snippets array $this->document->addScriptDeclaration("var local_snippets = ". json_encode($local_snippets).";"); } // add the document default css file - $this->document->addStyleSheet(JURI::root(true) .'/administrator/components/com_componentbuilder/assets/css/get_snippets.css', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); + JHtml::_('stylesheet', 'administrator/components/com_componentbuilder/assets/css/get_snippets.css', ['version' => 'auto']); } /** diff --git a/admin/views/help_documents/view.html.php b/admin/views/help_documents/view.html.php index 79cb8ef99..08b606523 100644 --- a/admin/views/help_documents/view.html.php +++ b/admin/views/help_documents/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewHelp_documents extends HtmlView $this->canState = $this->canDo->get('help_document.edit.state'); $this->canCreate = $this->canDo->get('help_document.create'); $this->canDelete = $this->canDo->get('help_document.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('help_document.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/import_joomla_components/tmpl/default.php b/admin/views/import_joomla_components/tmpl/default.php index f3a994ce9..59d07a8da 100644 --- a/admin/views/import_joomla_components/tmpl/default.php +++ b/admin/views/import_joomla_components/tmpl/default.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\ArrayHelper; JHtml::_('jquery.framework'); JHtml::_('bootstrap.tooltip'); @@ -171,7 +172,7 @@ jQuery('
')
hasPackage) && $this->hasPackage && $this->dataType === 'smart_package') : ?> packageInfo['name']) && ComponentbuilderHelper::checkArray($this->packageInfo['name'])) + if (isset($this->packageInfo['name']) && ArrayHelper::check($this->packageInfo['name'])) { $cAmount = count($this->packageInfo['name']); $comP = ($cAmount == 1) ? 'Component' : 'Components'; @@ -181,7 +182,7 @@ jQuery('
') $cAmount = 1; $comP = 'Component'; } - $hasOwner = (isset($this->packageInfo['getKeyFrom']) && ComponentbuilderHelper::checkArray($this->packageInfo['getKeyFrom'])) ? true:false; + $hasOwner = (isset($this->packageInfo['getKeyFrom']) && ArrayHelper::check($this->packageInfo['getKeyFrom'])) ? true:false; $class1 = ($hasOwner) ? 'span6' : 'span12'; ?>

@@ -213,14 +214,14 @@ jQuery('
')
- packageInfo); ?> + owner($this->packageInfo); ?>
- packageInfo['name']) && ComponentbuilderHelper::checkArray($this->packageInfo['name'])) : ?> + packageInfo['name']) && ArrayHelper::check($this->packageInfo['name'])) : ?> - packageInfo); ?> + components($this->packageInfo); ?> @@ -278,7 +279,7 @@ jQuery('
') - vdmPackages) && ComponentbuilderHelper::checkArray($this->vdmPackages)): ?> + vdmPackages) && ArrayHelper::check($this->vdmPackages)): ?>
@@ -309,7 +310,7 @@ jQuery('
') - jcbPackages) && ComponentbuilderHelper::checkArray($this->jcbPackages)) : ?> + jcbPackages) && ArrayHelper::check($this->jcbPackages)) : ?>
@@ -350,12 +351,12 @@ jQuery('
')
diff --git a/admin/views/powers/tmpl/default_body.php b/admin/views/powers/tmpl/default_body.php index 830c1199d..8d8d7708b 100644 --- a/admin/views/powers/tmpl/default_body.php +++ b/admin/views/powers/tmpl/default_body.php @@ -67,11 +67,11 @@ $edit = "index.php?option=com_componentbuilder&view=powers&task=power.edit"; escape($item->system_name); ?>
GUID: - escape($item->guid); ?> + escape($item->guid); ?>super_power_key)): ?>
SPK: super_power_key; ?>
- escape($item->namespace); ?> + namespace; ?>
: @@ -80,7 +80,9 @@ $edit = "index.php?option=com_componentbuilder&view=powers&task=power.edit"; escape($item->extends_name); ?> escape($item->extends_name); ?> - + extends === '-1') : ?>
: + escape($item->extends_custom); ?>
: + approved); ?>
diff --git a/admin/views/powers/view.html.php b/admin/views/powers/view.html.php index 93a32c5e5..8855f4ef7 100644 --- a/admin/views/powers/view.html.php +++ b/admin/views/powers/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewPowers extends HtmlView $this->canState = $this->canDo->get('power.edit.state'); $this->canCreate = $this->canDo->get('power.create'); $this->canDelete = $this->canDo->get('power.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('power.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') @@ -141,6 +141,16 @@ class ComponentbuilderViewPowers extends HtmlView // add Run Expansion button. JToolBarHelper::custom('powers.runExpansion', 'expand-2 custom-button-runexpansion', '', 'COM_COMPONENTBUILDER_RUN_EXPANSION', false); } + if ($this->user->authorise('power.init', 'com_componentbuilder')) + { + // add Init button. + JToolBarHelper::custom('powers.initPowers', 'health custom-button-initpowers', '', 'COM_COMPONENTBUILDER_INIT', false); + } + if ($this->user->authorise('power.reset', 'com_componentbuilder')) + { + // add Reset button. + JToolBarHelper::custom('powers.resetPowers', 'joomla custom-button-resetpowers', '', 'COM_COMPONENTBUILDER_RESET', false); + } // set help url for this view if found $this->help_url = ComponentbuilderHelper::getHelpUrl('powers'); @@ -195,43 +205,23 @@ class ComponentbuilderViewPowers extends HtmlView ); } - // Only load Power Version batch if create, edit, and batch is allowed + // Only load Approved batch if create, edit, and batch is allowed if ($this->canBatch && $this->canCreate && $this->canEdit) { - // Set Power Version Selection - $this->power_versionOptions = JFormHelper::loadFieldType('powersfilterpowerversion')->options; - // We do some sanitation for Power Version filter - if (ComponentbuilderHelper::checkArray($this->power_versionOptions) && - isset($this->power_versionOptions[0]->value) && - !ComponentbuilderHelper::checkString($this->power_versionOptions[0]->value)) + // Set Approved Selection + $this->approvedOptions = JFormHelper::loadFieldType('powersfilterapproved')->options; + // We do some sanitation for Approved filter + if (ComponentbuilderHelper::checkArray($this->approvedOptions) && + isset($this->approvedOptions[0]->value) && + !ComponentbuilderHelper::checkString($this->approvedOptions[0]->value)) { - unset($this->power_versionOptions[0]); + unset($this->approvedOptions[0]); } - // Power Version Batch Selection + // Approved Batch Selection JHtmlBatch_::addListSelection( - '- Keep Original '.JText::_('COM_COMPONENTBUILDER_POWER_POWER_VERSION_LABEL').' -', - 'batch[power_version]', - JHtml::_('select.options', $this->power_versionOptions, 'value', 'text') - ); - } - - // Only load Extends Name batch if create, edit, and batch is allowed - if ($this->canBatch && $this->canCreate && $this->canEdit) - { - // Set Extends Name Selection - $this->extendsNameOptions = JFormHelper::loadFieldType('Classpowers')->options; - // We do some sanitation for Extends Name filter - if (ComponentbuilderHelper::checkArray($this->extendsNameOptions) && - isset($this->extendsNameOptions[0]->value) && - !ComponentbuilderHelper::checkString($this->extendsNameOptions[0]->value)) - { - unset($this->extendsNameOptions[0]); - } - // Extends Name Batch Selection - JHtmlBatch_::addListSelection( - '- Keep Original '.JText::_('COM_COMPONENTBUILDER_POWER_EXTENDS_LABEL').' -', - 'batch[extends]', - JHtml::_('select.options', $this->extendsNameOptions, 'value', 'text') + '- Keep Original '.JText::_('COM_COMPONENTBUILDER_POWER_APPROVED_LABEL').' -', + 'batch[approved]', + JHtml::_('select.options', $this->approvedOptions, 'value', 'text') ); } } diff --git a/libraries/jcb_powers/VDM.Gitea/index.html b/admin/views/search/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/index.html rename to admin/views/search/index.html diff --git a/admin/views/search/tmpl/default.php b/admin/views/search/tmpl/default.php new file mode 100644 index 000000000..bd9da3ca1 --- /dev/null +++ b/admin/views/search/tmpl/default.php @@ -0,0 +1,342 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\ArrayHelper; + +JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); +JHtml::_('behavior.formvalidator'); +JHtml::_('formbehavior.chosen', 'select'); +JHtml::_('behavior.keepalive'); + +// allow main menu selection +$this->app->input->set('hidemainmenu', false); + +// set the basu URL +$url_base = JUri::base() . 'index.php?option=com_componentbuilder'; +$url_search = $url_base . '&view=search'; + +// get main search input field +$search_value = $this->form->getField('search_value'); +?> +canDo->get('search.access')): ?> + +item->id)) ? '&id='. (int) $this->item->id : ''; ?> + +sidebar)): ?> +
+ sidebar; ?> +
+
+ +
+ + form): ?> +
+
+ + + +
+
+ form->renderField('type_search'); ?> +
+ input; ?> + + +
+ form->renderField('replace_value'); ?> + +
+
+ form->renderFieldset('settings'); ?> +
+
+
+
+
+ 'search_results_table', 'headers' => $this->table_headers, 'items' => 7, 'init' => false]); ?> +
+
+
+ +
+ form->getInput('item_code'); ?> +
+
+ + +
+ +
+item['tables']) && ArrayHelper::check($this->item['tables'])) : ?> + + + +

+ + diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/index.html b/admin/views/search/tmpl/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/src/Package/Repo/index.html rename to admin/views/search/tmpl/index.html diff --git a/admin/views/search/view.html.php b/admin/views/search/view.html.php new file mode 100644 index 000000000..0b4849dc3 --- /dev/null +++ b/admin/views/search/view.html.php @@ -0,0 +1,440 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +use Joomla\CMS\MVC\View\HtmlView; +use Joomla\CMS\Filesystem\File; +use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory; +use Joomla\CMS\Form\Form; +use VDM\Joomla\Utilities\ArrayHelper; + +/** + * Componentbuilder Html View class for the Search + */ +class ComponentbuilderViewSearch extends HtmlView +{ + // Overwriting JView display method + function display($tpl = null) + { + // get component params + $this->params = JComponentHelper::getParams('com_componentbuilder'); + // get the application + $this->app = JFactory::getApplication(); + // get the user object + $this->user = JFactory::getUser(); + // get global action permissions + $this->canDo = ComponentbuilderHelper::getActions('search'); + // Initialise variables. + $this->item = $this->get('Item'); + $this->urlvalues = $this->get('UrlValues'); + if ($this->getLayout() !== 'modal') + { + // Include helper submenu + ComponentbuilderHelper::addSubmenu('search'); + JHtmlSidebar::setAction('index.php?option=com_componentbuilder&view=search'); + $this->sidebar = JHtmlSidebar::render(); + } + + // get the needed form fields + $this->form = $this->getDynamicForm(); + + // build our table headers + $this->table_headers = array( + 'edit' => 'E', + 'code' => JText::_('COM_COMPONENTBUILDER_FOUND_TEXT'), + 'table' => JText::_('COM_COMPONENTBUILDER_TABLE'), + 'field' => JText::_('COM_COMPONENTBUILDER_FIELD'), + 'id' => JText::_('ID'), + 'line' => JText::_('COM_COMPONENTBUILDER_LINE') + ); + + // set some JavaScript Language + JText::script('COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_ROW'); + JText::script('COM_COMPONENTBUILDER_FIELD_IN_THE'); + JText::script('COM_COMPONENTBUILDER_TABLE'); + JText::script('COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE'); + JText::script('COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_BALLB_VALUES_THAT_CAN_BE_FOUND_IN_THE_DATABASE'); + JText::script('COM_COMPONENTBUILDER_YOU_WILL_REPLACE'); + JText::script('COM_COMPONENTBUILDER_WITH'); + JText::script('COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_BYOU_HAVE_BEEN_WARNEDB'); + JText::script('COM_COMPONENTBUILDER_ARE_YOU_THEREFORE_ABSOLUTELY_SURE_YOU_WANT_TO_CONTINUE'); + JText::script('COM_COMPONENTBUILDER_THE_SEARCH_PROCESS_HAD_AN_ERROR_WITH_TABLE'); + JText::script('COM_COMPONENTBUILDER_THE_REPLACE_PROCESS_HAD_AN_ERROR_WITH_TABLE'); + JText::script('COM_COMPONENTBUILDER_REPLACE_PROCESS_COMPLETE'); + JText::script('COM_COMPONENTBUILDER_SEARCHING'); + JText::script('COM_COMPONENTBUILDER_TABLES_WITH'); + JText::script('COM_COMPONENTBUILDER_FIELDS_THAT_HAD'); + JText::script('COM_COMPONENTBUILDER_LINES'); + JText::script('COM_COMPONENTBUILDER_AND_FINISHED_THE_SEARCH_IN'); + JText::script('COM_COMPONENTBUILDER_SECONDS'); + JText::script('COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_DO_A_REVERSE_SEARCH'); + JText::script('COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_REPEAT_THE_SAME_SEARCH'); + JText::script('COM_COMPONENTBUILDER_YES_UPDATE_ALL'); + JText::script('COM_COMPONENTBUILDER_NO'); + JText::script('COM_COMPONENTBUILDER_YES'); + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + // add the tool bar + $this->addToolBar(); + } + + // set the document + $this->setDocument(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode(PHP_EOL, $errors), 500); + } + + parent::display($tpl); + } + + /** + * Get the dynamic build form fields needed on the page + * + * @return Form|null The array of form fields + * + * @since 3.2.0 + */ + public function getDynamicForm(): ?Form + { + if(ArrayHelper::check($this->item) && + ArrayHelper::check($this->item['tables']) && + ArrayHelper::check($this->item['components'])) + { + // start the form + $form = new Form('Search'); + + $form->load('
+
+
+
+
'); + + // Search Mode + $attributes = [ + 'type' => 'radio', + 'name' => 'type_search', + 'hiddenLabel' => true, + 'label' => 'COM_COMPONENTBUILDER_MODE', + 'class' => 'btn-group', + 'description' => 'COM_COMPONENTBUILDER_SEARCH_OR_SEARCH_AND_REPLACE', + 'default' => $this->urlvalues['type_search']]; + // set the mode options + $options = [ + 1 => 'COM_COMPONENTBUILDER_SEARCH', + 2 => 'COM_COMPONENTBUILDER_REPLACE', + 0 => 'COM_COMPONENTBUILDER_CLEAR']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'search'); + } + + // search text attributes + $attributes = [ + 'type' => 'text', + 'name' => 'search_value', + 'hiddenLabel' => true, + 'label' => 'COM_COMPONENTBUILDER_SEARCH', + 'size' => 150, + 'maxlength' => 200, + 'description' => 'COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_YOUR_SEARCH_TEXT', + 'filter' => 'RAW', + 'class' => 'search-value span11', + 'hint' => 'COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT', + 'autocomplete' => true, + 'default' => $this->urlvalues['search_value']]; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'search'); + } + + // replace text attributes + $attributes = [ + 'type' => 'text', + 'name' => 'replace_value', + 'hiddenLabel' => true, + 'label' => 'COM_COMPONENTBUILDER_REPLACE', + 'size' => 150, + 'maxlength' => 200, + 'description' => 'COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_THE_REPLACE_TEXT_THAT_YOU_WOULD_LIKE_TO_USE_AS_REPLACEMENT_FOR_THE_SEARCH_TEXT_FOUND', + 'filter' => 'RAW', + 'class' => 'replace-value span11', + 'hint' => 'COM_COMPONENTBUILDER_ENTER_YOUR_REPLACE_TEXT', + 'autocomplete' => true, + 'showon' => 'type_search:2', + 'default' => $this->urlvalues['replace_value']]; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'search'); + } + + // Search Behaviour + $default = []; + if ($this->urlvalues['match_case'] == 1) + { + $default[] = 'match_case'; + } + if ($this->urlvalues['whole_word'] == 1) + { + $default[] = 'whole_word'; + } + if ($this->urlvalues['regex_search'] == 1) + { + $default[] = 'regex_search'; + } + $attributes = [ + 'type' => 'checkboxes', + 'name' => 'search_behaviour', + 'label' => 'COM_COMPONENTBUILDER_BEHAVIOUR', + 'description' => 'COM_COMPONENTBUILDER_SET_THE_SEARCH_BEHAVIOUR_HERE']; + if (ArrayHelper::check($default)) + { + $attributes['default'] = implode(',', $default); + } + // set the mode options + $options = [ + 'match_case' => 'COM_COMPONENTBUILDER_MATCH_CASE', + 'whole_word' => 'COM_COMPONENTBUILDER_WHOLE_WORD', + 'regex_search' => 'COM_COMPONENTBUILDER_REGEX_SEARCH']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'settings'); + } + + // component attributes + $attributes = [ + 'type' => 'list', + 'name' => 'component_id', + 'label' => 'COM_COMPONENTBUILDER_COMPONENTS_BR_SMALLDISABLED_SOONSMALL', + 'class' => 'list_class', + 'description' => 'COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_SEARCH', + 'required' => 'true', + 'disable' => 'true', + 'readonly' => 'true', + 'default' => -1]; + // start the component options + $options = []; + $options['-1'] = 'COM_COMPONENTBUILDER__SEARCH_ALL_'; + // load component options from array + foreach($this->item['components'] as $component) + { + $options[(int) $component->id] = $this->escape($component->name); + } + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'settings'); + } + + // table attributes + $attributes = [ + 'type' => 'list', + 'name' => 'table_name', + 'label' => 'COM_COMPONENTBUILDER_TABLES', + 'class' => 'list_class', + 'description' => 'COM_COMPONENTBUILDER_SELECT_THE_TABLE_TO_SEARCH', + 'required' => 'true', + 'default' => $this->urlvalues['table_name']]; + // start the component options + $options = []; + $options['-1'] = 'COM_COMPONENTBUILDER__SEARCH_ALL_'; + // load table options from array + foreach($this->item['tables'] as $table) + { + $options[$table] = $this->escape($table); + } + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'settings'); + } + + // editor attributes + $attributes = [ + 'type' => 'editor', + 'name' => 'item_code', + 'label' => 'COM_COMPONENTBUILDER_ITEM_CODE', + 'width' => '100%', + 'height' => '150px', + 'class' => 'item_code_editor', + 'syntax' => 'php', + 'buttons' => 'false', + 'filter' => 'raw', + 'editor' => 'codemirror|none']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'view'); + } + + // return the form array + return $form; + } + + return null; + } + + + /** + * Prepares the document + */ + protected function setDocument() + { + + // Only load jQuery if needed. (default is true) + if ($this->params->get('add_jquery_framework', 1) == 1) + { + JHtml::_('jquery.framework'); + } + // Load the header checker class. + require_once( JPATH_COMPONENT_ADMINISTRATOR.'/helpers/headercheck.php' ); + // Initialize the header checker. + $HeaderCheck = new componentbuilderHeaderCheck; + + // always load these files. + JHtml::_('stylesheet', "media/com_componentbuilder/datatable/css/datatables.min.css", ['version' => 'auto']); + JHtml::_('script', "media/com_componentbuilder/datatable/js/pdfmake.min.js", ['version' => 'auto']); + JHtml::_('script', "media/com_componentbuilder/datatable/js/vfs_fonts.js", ['version' => 'auto']); + JHtml::_('script', "media/com_componentbuilder/datatable/js/datatables.min.js", ['version' => 'auto']); + + // Add View JavaScript File + JHtml::_('script', "administrator/components/com_componentbuilder/assets/js/search.js", ['version' => 'auto']); + + // Load uikit options. + $uikit = $this->params->get('uikit_load'); + // Set script size. + $size = $this->params->get('uikit_min'); + // Set css style. + $style = $this->params->get('uikit_style'); + + // The uikit css. + if ((!$HeaderCheck->css_loaded('uikit.min') || $uikit == 1) && $uikit != 2 && $uikit != 3) + { + JHtml::_('stylesheet', 'media/com_componentbuilder/uikit-v2/css/uikit'.$style.$size.'.css', ['version' => 'auto']); + } + // The uikit js. + if ((!$HeaderCheck->js_loaded('uikit.min') || $uikit == 1) && $uikit != 2 && $uikit != 3) + { + JHtml::_('script', 'media/com_componentbuilder/uikit-v2/js/uikit'.$size.'.js', ['version' => 'auto']); + } + + // Load the script to find all uikit components needed. + if ($uikit != 2) + { + // Set the default uikit components in this view. + $uikitComp = array(); + $uikitComp[] = 'UIkit.notify'; + $uikitComp[] = 'uk-progress'; + } + + // Load the needed uikit components in this view. + if ($uikit != 2 && isset($uikitComp) && ComponentbuilderHelper::checkArray($uikitComp)) + { + // load just in case. + jimport('joomla.filesystem.file'); + // loading... + foreach ($uikitComp as $class) + { + foreach (ComponentbuilderHelper::$uk_components[$class] as $name) + { + // check if the CSS file exists. + if (File::exists(JPATH_ROOT.'/media/com_componentbuilder/uikit-v2/css/components/'.$name.$style.$size.'.css')) + { + // load the css. + JHtml::_('stylesheet', 'media/com_componentbuilder/uikit-v2/css/components/'.$name.$style.$size.'.css', ['version' => 'auto']); + } + // check if the JavaScript file exists. + if (File::exists(JPATH_ROOT.'/media/com_componentbuilder/uikit-v2/js/components/'.$name.$size.'.js')) + { + // load the js. + JHtml::_('script', 'media/com_componentbuilder/uikit-v2/js/components/'.$name.$size.'.js', ['version' => 'auto'], ['type' => 'text/javascript', 'async' => 'async']); + } + } + } + } + // add the document default css file + JHtml::_('stylesheet', 'administrator/components/com_componentbuilder/assets/css/search.css', ['version' => 'auto']); + } + + /** + * Setting the toolbar + */ + protected function addToolBar() + { + // hide the main menu + $this->app->input->set('hidemainmenu', true); + // set the title + if (isset($this->item->name) && $this->item->name) + { + $title = $this->item->name; + } + // Check for empty title and add view name if param is set + if (empty($title)) + { + $title = JText::_('COM_COMPONENTBUILDER_SEARCH'); + } + // add title to the page + JToolbarHelper::title($title,'search'); + // add cpanel button + JToolBarHelper::custom('search.dashboard', 'grid-2', '', 'COM_COMPONENTBUILDER_DASH', false); + if ($this->canDo->get('search.compiler')) + { + // add Compiler button. + JToolBarHelper::custom('search.openCompiler', 'cogs custom-button-opencompiler', '', 'COM_COMPONENTBUILDER_COMPILER', false); + } + + // set help url for this view if found + $this->help_url = ComponentbuilderHelper::getHelpUrl('search'); + if (ComponentbuilderHelper::checkString($this->help_url)) + { + JToolbarHelper::help('COM_COMPONENTBUILDER_HELP_MANAGER', false, $this->help_url); + } + + // add the options comp button + if ($this->canDo->get('core.admin') || $this->canDo->get('core.options')) + { + JToolBarHelper::preferences('com_componentbuilder'); + } + } + + /** + * Escapes a value for output in a view script. + * + * @param mixed $var The output to escape. + * + * @return mixed The escaped value. + */ + public function escape($var) + { + // use the helper htmlEscape method instead. + return ComponentbuilderHelper::htmlEscape($var, $this->_charset); + } +} +?> diff --git a/admin/views/servers/view.html.php b/admin/views/servers/view.html.php index 036c47a53..7db0acf89 100644 --- a/admin/views/servers/view.html.php +++ b/admin/views/servers/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewServers extends HtmlView $this->canState = $this->canDo->get('server.edit.state'); $this->canCreate = $this->canDo->get('server.create'); $this->canDelete = $this->canDo->get('server.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('server.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/site_views/tmpl/default_body.php b/admin/views/site_views/tmpl/default_body.php index 0352401f7..53f6fd84c 100644 --- a/admin/views/site_views/tmpl/default_body.php +++ b/admin/views/site_views/tmpl/default_body.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; $edit = "index.php?option=com_componentbuilder&view=site_views&task=site_view.edit"; @@ -74,7 +75,7 @@ $edit = "index.php?option=com_componentbuilder&view=site_views&task=site_view.ed escape($item->name); ?>
: escape($item->codename); ?>
- context)): ?> + context)): ?> : escape($item->context); ?> diff --git a/admin/views/site_views/view.html.php b/admin/views/site_views/view.html.php index d93fbc885..02a3b2ece 100644 --- a/admin/views/site_views/view.html.php +++ b/admin/views/site_views/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewSite_views extends HtmlView $this->canState = $this->canDo->get('core.edit.state'); $this->canCreate = $this->canDo->get('core.create'); $this->canDelete = $this->canDo->get('core.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('site_view.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/snippet_types/view.html.php b/admin/views/snippet_types/view.html.php index 9e3a89ed8..79f1fe119 100644 --- a/admin/views/snippet_types/view.html.php +++ b/admin/views/snippet_types/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewSnippet_types extends HtmlView $this->canState = $this->canDo->get('snippet_type.edit.state'); $this->canCreate = $this->canDo->get('snippet_type.create'); $this->canDelete = $this->canDo->get('snippet_type.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('snippet_type.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/snippets/view.html.php b/admin/views/snippets/view.html.php index a9a60d767..8e4745b49 100644 --- a/admin/views/snippets/view.html.php +++ b/admin/views/snippets/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewSnippets extends HtmlView $this->canState = $this->canDo->get('core.edit.state'); $this->canCreate = $this->canDo->get('core.create'); $this->canDelete = $this->canDo->get('core.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('snippet.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/templates/tmpl/default_body.php b/admin/views/templates/tmpl/default_body.php index 2afd32aae..75559d769 100644 --- a/admin/views/templates/tmpl/default_body.php +++ b/admin/views/templates/tmpl/default_body.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; $edit = "index.php?option=com_componentbuilder&view=templates&task=template.edit"; @@ -67,7 +68,7 @@ $edit = "index.php?option=com_componentbuilder&view=templates&task=template.edit escape($item->name); ?>
- <?php echo $this->loadTemplate('alias); ?>'); ?> + <?php echo $this->loadTemplate('alias); ?>'); ?>
diff --git a/admin/views/templates/view.html.php b/admin/views/templates/view.html.php index 4f8b8ed08..a478b3ac8 100644 --- a/admin/views/templates/view.html.php +++ b/admin/views/templates/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewTemplates extends HtmlView $this->canState = $this->canDo->get('core.edit.state'); $this->canCreate = $this->canDo->get('core.create'); $this->canDelete = $this->canDo->get('core.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('template.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/admin/views/validation_rules/view.html.php b/admin/views/validation_rules/view.html.php index 32ef17c5b..7b5467f0d 100644 --- a/admin/views/validation_rules/view.html.php +++ b/admin/views/validation_rules/view.html.php @@ -52,7 +52,7 @@ class ComponentbuilderViewValidation_rules extends HtmlView $this->canState = $this->canDo->get('validation_rule.edit.state'); $this->canCreate = $this->canDo->get('validation_rule.create'); $this->canDelete = $this->canDo->get('validation_rule.delete'); - $this->canBatch = $this->canDo->get('core.batch'); + $this->canBatch = ($this->canDo->get('validation_rule.batch') && $this->canDo->get('core.batch')); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') diff --git a/componentbuilder.xml b/componentbuilder.xml index 46eecc7b9..cec731d25 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,15 +1,15 @@ COM_COMPONENTBUILDER - 9th July, 2022 + 24th October, 2023 Llewellyn van der Merwe joomla@vdm.io https://dev.vdm.io Copyright (C) 2015 Vast Development Method. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt - 3.1.4 + 3.1.28 Component Builder (v.3.1.4) +

Component Builder (v.3.1.28)

The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time. @@ -39,6 +39,7 @@ Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/compo js css images + datatable uikit-v2 footable-v3 @@ -78,6 +79,7 @@ Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/compo

COM_COMPONENTBUILDER_MENU_JOOMLA_MODULES COM_COMPONENTBUILDER_MENU_JOOMLA_PLUGINS COM_COMPONENTBUILDER_MENU_POWERS + COM_COMPONENTBUILDER_MENU_SEARCH COM_COMPONENTBUILDER_MENU_ADMIN_VIEWS COM_COMPONENTBUILDER_MENU_CUSTOM_ADMIN_VIEWS COM_COMPONENTBUILDER_MENU_SITE_VIEWS diff --git a/componentbuilder_update_server.xml b/componentbuilder_update_server.xml index 2cd47afe7..0130d0525 100644 --- a/componentbuilder_update_server.xml +++ b/componentbuilder_update_server.xml @@ -1079,10 +1079,154 @@ pkg_component_builder package site - 3.1.4 + 3.1.5 https://dev.vdm.io - https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.4.zip + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.5.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.12 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.12.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.19 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.19.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.21 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla-beta/pkg-component-builder/archive/v3.1.22.zip + + + beta + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.24 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.24.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.25 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla-beta/pkg-component-builder/archive/v3.1.25.zip + + + beta + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.26 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.26.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.27 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.27.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.28 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.28.zip stable diff --git a/libraries/jcb_powers/VDM.Gitea/src/AbstractGiteaObject.php b/libraries/jcb_powers/VDM.Gitea/src/AbstractGiteaObject.php deleted file mode 100644 index 431662a7e..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/AbstractGiteaObject.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace VDM\Gitea; - - -use Joomla\CMS\Http\Http as BaseHttp; -use Joomla\CMS\Http\HttpFactory; -use Joomla\CMS\Http\Response; -use Joomla\Registry\Registry; -use Joomla\Uri\Uri; -use VDM\Joomla\Utilities\JsonHelper; - -abstract class AbstractGiteaObject -{ - /** - * Options for the Gitea object. - * - * @var Registry - * @since 1.0 - */ - protected $options; - - /** - * The HTTP client object to use in sending HTTP requests. - * - * @var BaseHttp - * @since 1.0 - */ - protected $client; - - /** - * The package the object resides in - * - * @var string - * @since 1.0 - */ - protected $package = ''; - - /** - * Constructor. - * - * @param Registry $options Gitea options object. - * @param BaseHttp $client The HTTP client object. - * - * @since 1.0 - */ - public function __construct(Registry $options = null, BaseHttp $client = null) - { - $this->options = $options ?: new Registry; - $this->client = $client ?: (new HttpFactory)->getHttp($this->options); - - $this->package = \get_class($this); - $this->package = substr($this->package, strrpos($this->package, '\\') + 1); - } - - /** - * Method to build and return a full request URL for the request. This method will - * add appropriate pagination details if necessary and also prepend the API url - * to have a complete URL for the request. - * - * @param string $path URL to inflect - * @param integer $page Page to request - * @param integer $limit Number of results to return per page - * - * @return Uri - * - * @since 1.0 - */ - protected function fetchUrl($path, $page = 0, $limit = 0) - { - // Get a new Uri object focusing the api url and given path. - $uri = new Uri($this->options->get('api.url') . $path); - - if ($this->options->get('access.token', false)) - { - // Use oAuth authentication - $headers = $this->client->getOption('headers', array()); - - if (!isset($headers['Authorization'])) - { - $headers['Authorization'] = 'token ' . $this->options->get('access.token'); - $this->client->setOption('headers', $headers); - } - } - else - { - // Use basic authentication - if ($this->options->get('api.username', false)) - { - $uri->setUser($this->options->get('api.username')); - } - - if ($this->options->get('api.password', false)) - { - $uri->setPass($this->options->get('api.password')); - } - } - - // If we have a defined page number add it to the JUri object. - if ($page > 0) - { - $uri->setVar('page', (int) $page); - } - - // If we have a defined items per page add it to the JUri object. - if ($limit > 0) - { - $uri->setVar('limit', (int) $limit); - } - - return $uri; - } - - /** - * Process the response and decode it. - * - * @param Response $response The response. - * @param integer $expectedCode The expected "good" code. - * - * @return mixed - * - * @since 1.0 - * @throws RuntimeException - */ - protected function processResponse(Response $response, $expectedCode = 200) - { - // Validate the response code. - if ($response->code != $expectedCode) - { - // Decode the error response and throw an exception. - $error = json_decode($response->body); - $message = isset($error->message) ? $error->message : 'Invalid response received from Gitea.'; - - throw new \DomainException($message, $response->code); - } - - if (JsonHelper::check($response->body)) - { - $body = json_decode($response->body); - - if (isset($body->content_base64)) - { - $body->content = base64_decode($body->content_base64); - } - } - else - { - $body = $response->body; - } - - return $body; - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/AbstractPackage.php b/libraries/jcb_powers/VDM.Gitea/src/AbstractPackage.php deleted file mode 100644 index 682a7867a..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/AbstractPackage.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace VDM\Gitea; - - -use Joomla\CMS\Http\Http as BaseHttp; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractGiteaObject; - -abstract class AbstractPackage extends AbstractGiteaObject -{ - /** - * Constructor. - * - * @param Registry $options Gitea options object. - * @param Http $client The HTTP client object. - * - * @since 1.0 - */ - public function __construct(Registry $options = null, BaseHttp $client = null) - { - parent::__construct($options, $client); - - $this->package = \get_class($this); - $this->package = substr($this->package, strrpos($this->package, '\\') + 1); - } - - /** - * Magic method to lazily create API objects - * - * @param string $name Name of property to retrieve - * - * @since 1.0 - * @throws \InvalidArgumentException - * - * @return AbstractPackage Gitea API package object. - */ - public function __get($name) - { - $class = '\\VDM\\Gitea\\Package\\' . $this->package . '\\' . ucfirst($name); - - if (class_exists($class) == false) - { - throw new \InvalidArgumentException( - sprintf( - 'Argument %1$s produced an invalid class name: %2$s in package %3$s', - $name, $class, $this->package - ) - ); - } - - if (isset($this->$name) == false) - { - $this->$name = new $class($this->options, $this->client); - } - - return $this->$name; - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Gitea.php b/libraries/jcb_powers/VDM.Gitea/src/Gitea.php deleted file mode 100644 index d84477ce2..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Gitea.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace VDM\Gitea; - - -use Joomla\CMS\Http\Http as BaseHttp; -use Joomla\CMS\Http\HttpFactory; -use Joomla\Registry\Registry; - -class Gitea -{ - /** - * Options for the Gitea object. - * - * @var array - * @since 1.0 - */ - protected $options; - - /** - * The HTTP client object to use in sending HTTP requests. - * - * @var BaseHttp - * @since 1.0 - */ - protected $client; - - /** - * Constructor. - * - * @param Registry $options Gitea options object. - * @param Http $client The HTTP client object. - * - * @since 1.0 - */ - public function __construct(Registry $options = null, BaseHttp $client = null) - { - $this->options = $options ?: new Registry; - - // Setup the default user agent if not already set. - if (!$this->getOption('userAgent')) - { - $this->setOption('userAgent', 'JGitea/1.0'); - } - - // Setup the default API url if not already set. - if (!$this->getOption('api.url')) - { - $this->setOption('api.url', 'https://git.vdm.dev/api/v1'); - } - - $this->client = $client ?: (new HttpFactory)->getHttp($this->options); - } - - /** - * Magic method to lazily create API objects - * - * @param string $name Name of property to retrieve - * - * @return AbstractGiteaObject Gitea API object (issues, pulls, etc). - * - * @since 1.0 - * @throws \InvalidArgumentException If $name is not a valid sub class. - */ - public function __get($name) - { - $class = '\\VDM\\Gitea\\Package\\' . ucfirst($name); - - if (class_exists($class)) - { - if (isset($this->$name) == false) - { - $this->$name = new $class($this->options, $this->client); - } - - return $this->$name; - } - - throw new \InvalidArgumentException(sprintf('Argument %s produced an invalid class name: %s', $name, $class)); - } - - /** - * Get an option from the Gitea instance. - * - * @param string $key The name of the option to get. - * - * @return mixed The option value. - * - * @since 1.0 - */ - public function getOption($key) - { - return isset($this->options[$key]) ? $this->options[$key] : null; - } - - /** - * Set an option for the Gitea instance. - * - * @param string $key The name of the option to set. - * @param mixed $value The option value to set. - * - * @return Gitea This object for method chaining. - * - * @since 1.0 - */ - public function setOption($key, $value) - { - $this->options[$key] = $value; - - return $this; - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo.php b/libraries/jcb_powers/VDM.Gitea/src/Package/Repo.php deleted file mode 100644 index 409c6f536..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo.php +++ /dev/null @@ -1,266 +0,0 @@ - - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace VDM\Gitea\Package; - - -use Joomla\CMS\Http\Http; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractPackage; - -class Repo extends AbstractPackage -{ - /** - * List your repositories. - * - * List repositories for the authenticated user. - * - * @return object - * - * @since 1.0 - */ - public function getListOwn() - { - // Build the request path. - $uri = $this->fetchUrl('/user/repos'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * List user repositories. - * - * List public repositories for the specified user. - * - * @param string $user The user name. - * - * @return object - * - * @since 1.0 - */ - public function getListUser($user) - { - // Build the request path. - $uri = $this->fetchUrl('/users/' . $user . '/repos'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * List organization repositories. - * - * List repositories for the specified org. - * - * @param string $org The name of the organization. - * - * @return object - * - * @since 1.0 - */ - public function getListOrg($org) - { - // Build the request path. - $uri = $this->fetchUrl('/orgs/' . $org . '/repos'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * Create. - * - * Create a new repository for the authenticated user or an organization. OAuth users must supply repo scope. - * - * @param string $name The repository name. - * @param string $org The organization name (if needed). - * @param string $description The repository description. - * @param string $readme Readme of the repository to create. - * @param boolean $private Set true to create a private repository, false to create a public one. - * @param string $defaultBranch DefaultBranch of the repository (used when initializes and in template). - * @param string $license License to use. - * @param boolean $autoInit Whether the repository should auto init. - * @param boolean $template Whether the repository is template. - * @param string $gitignores Gitignores to use. - * options: [ Joomla, JetBrains ] and much more... - * @param string $issueLabels Label-Set to use. - * @param string $trustModel TrustModel of the repository. - * options: [ default, collaborator, committer, collaboratorcommitter ] - * - * @return object - * - * @since 1.0 - */ - public function create($name, $org = '', $description = '', $readme = 'Default', $private = false, $defaultBranch = 'master', - $license = 'GPL-2.0-or-later', $autoInit = true, $template = false, $trustModel = 'default', $gitignores = '', $issueLabels = '' - ) - { - $path = ($org) - // Create a repository for an organization - ? '/orgs/' . $org . '/repos' - // Create a repository for a user - : '/user/repos'; - - $data = [ - 'name' => $name, - 'description' => $description, - 'readme' => $readme, - 'private' => $private, - 'auto_init' => $autoInit, - 'default_branch' => $defaultBranch, - 'issue_labels' => $issueLabels, - 'license' => $license, - 'template' => $template, - 'gitignores' => $gitignores, - 'trust_model' => $trustModel - ]; - - // Send the request. - return $this->processResponse( - $this->client->post($this->fetchUrl($path), json_encode($data)), - 201 - ); - } - - /** - * Get. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function get($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * List contributors. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function getListContributors($owner, $repo) - { - // Build the request path. - $uri = $this->fetchUrl('/repos/' . $owner . '/' . $repo . '/contributors'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * List languages. - * - * List languages for the specified repository. The value on the right of a language is the number of bytes of code - * written in that language. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function getListLanguages($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/languages'; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * List Teams - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function getListTeams($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/teams'; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * List Tags. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * @param integer $page Page to request - * @param integer $limit Number of results to return per page - * - * @return object - * - * @since 1.0 - */ - public function getListTags($owner, $repo, $page = 0, $limit = 0) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/tags'; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path, $page, $limit)) - ); - } - - /** - * Delete a Repository. - * - * Deleting a repository requires admin access. If OAuth is used, the delete_repo scope is required. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function delete($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo; - - // Send the request. - return $this->processResponse( - $this->client->delete($this->fetchUrl($path)) - ); - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/File.php b/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/File.php deleted file mode 100644 index ddbe63da9..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/File.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace VDM\Gitea\Package\Repo; - - -use Joomla\CMS\Http\Http; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractPackage; - - -/** - * Start looking here: - * https://git.vdm.dev/api/swagger#/repository/repoGetContents - */ -class File extends AbstractPackage -{ - /** - * Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * @param string $filepath Repository file path. - * - * @return object - * - * @since 1.0 - */ - public function get($owner, $repo, $filepath) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/contents/' . $filepath; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/Wiki.php b/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/Wiki.php deleted file mode 100644 index ec55eabeb..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/Wiki.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace VDM\Gitea\Package\Repo; - - -use Joomla\CMS\Http\Http; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractPackage; - - -/** - * Start looking here: - * https://git.vdm.dev/api/swagger#/repository/repoCreateWikiPage - */ -class Wiki extends AbstractPackage -{ - /** - * Get a repository wiki page - * - * @param string $owner The repository owner - * @param string $repo The repository name - * @param string $pageName The page name - * - * @return object - * - * @since 1.0 - */ - public function get(string $owner, string $repo, string $pageName) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/wiki/page/' . $pageName; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * Get a repository wiki html page - * - * @param string $owner The repository owner - * @param string $repo The repository name - * @param string $pageName The page name - * - * @return object - * - * @since 1.0 - */ - public function getHtml(string $owner, string $repo, string $pageName) - { - // get the gitea wiki page - $page = $this->get($owner, $repo, $pageName); - - if (empty($page->content)) - { - throw new \Exception('Wiki page could not be found.'); - } - - // Build the request path. - $path = '/markdown'; - - // Get headers - $headers = $this->client->getOption('headers', array()); - - $headers['accept'] = 'text/html'; - $headers['Content-Type'] = 'application/json'; - - // build the post body - $data = [ - 'Context' => 'string', - 'Mode' => 'string', - 'Text' => $page->content, - 'Wiki' => true - ]; - - // Post the request. - return $this->processResponse( - $this->client->post($this->fetchUrl($path), json_encode($data), $headers) - ); - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/index.html b/libraries/jcb_powers/VDM.Joomla.FOF/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/src/Package/index.html rename to libraries/jcb_powers/VDM.Joomla.FOF/index.html diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES.php new file mode 100644 index 000000000..00618f8af --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES.php @@ -0,0 +1,300 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt; + + +use VDM\Joomla\FOF\Encrypt\AES\AesInterface; +use VDM\Joomla\FOF\Encrypt\AES\Mcrypt; +use VDM\Joomla\FOF\Encrypt\AES\Openssl; +use VDM\Joomla\FOF\Utils\Phpfunc; + + +/** + * AES encryption class + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +class AES +{ + /** + * The cipher key. + * + * @var string + */ + protected $key = ''; + + /** + * The AES encryption adapter in use. + * + * @var AesInterface + */ + protected $adapter; + + /** + * Initialise the AES encryption object. + * + * Note: If the key is not 16 bytes this class will do a stupid key expansion for legacy reasons (produce the + * SHA-256 of the key string and throw away half of it). + * + * @param string $key The encryption key (password). It can be a raw key (16 bytes) or a passphrase. + * @param int $strength Bit strength (128, 192 or 256) – ALWAYS USE 128 BITS. THIS PARAMETER IS DEPRECATED. + * @param string $mode Encryption mode. Can be ebc or cbc. We recommend using cbc. + * @param Phpfunc $phpfunc For testing + * @param string $priority Priority which adapter we should try first + */ + public function __construct($key, $strength = 128, $mode = 'cbc', Phpfunc $phpfunc = null, $priority = 'openssl') + { + if ($priority == 'openssl') + { + $this->adapter = new Openssl(); + + if (!$this->adapter->isSupported($phpfunc)) + { + $this->adapter = new Mcrypt(); + } + } + else + { + $this->adapter = new Mcrypt(); + + if (!$this->adapter->isSupported($phpfunc)) + { + $this->adapter = new Openssl(); + } + } + + $this->adapter->setEncryptionMode($mode, $strength); + $this->setPassword($key, true); + } + + /** + * Sets the password for this instance. + * + * WARNING: Do not use the legacy mode, it's insecure + * + * @param string $password The password (either user-provided password or binary encryption key) to use + * @param bool $legacyMode True to use the legacy key expansion. We recommend against using it. + */ + public function setPassword($password, $legacyMode = false) + { + $this->key = $password; + + $passLength = strlen($password); + + if (function_exists('mb_strlen')) + { + $passLength = mb_strlen($password, 'ASCII'); + } + + // Legacy mode was doing something stupid, requiring a key of 32 bytes. DO NOT USE LEGACY MODE! + if ($legacyMode && ($passLength != 32)) + { + // Legacy mode: use the sha256 of the password + $this->key = hash('sha256', $password, true); + // We have to trim or zero pad the password (we end up throwing half of it away in Rijndael-128 / AES...) + $this->key = $this->adapter->resizeKey($this->key, $this->adapter->getBlockSize()); + } + } + + /** + * Encrypts a string using AES + * + * @param string $stringToEncrypt The plaintext to encrypt + * @param bool $base64encoded Should I Base64-encode the result? + * + * @return string The cryptotext. Please note that the first 16 bytes of + * the raw string is the IV (initialisation vector) which + * is necessary for decoding the string. + */ + public function encryptString($stringToEncrypt, $base64encoded = true) + { + $blockSize = $this->adapter->getBlockSize(); + $randVal = new Randval(); + $iv = $randVal->generate($blockSize); + + $key = $this->getExpandedKey($blockSize, $iv); + $cipherText = $this->adapter->encrypt($stringToEncrypt, $key, $iv); + + // Optionally pass the result through Base64 encoding + if ($base64encoded) + { + $cipherText = base64_encode((string) $cipherText); + } + + // Return the result + return $cipherText; + } + + /** + * Decrypts a ciphertext into a plaintext string using AES + * + * @param string $stringToDecrypt The ciphertext to decrypt. The first 16 bytes of the raw string must contain + * the IV (initialisation vector). + * @param bool $base64encoded Should I Base64-decode the data before decryption? + * + * @return string The plain text string + */ + public function decryptString($stringToDecrypt, $base64encoded = true) + { + if ($base64encoded) + { + $stringToDecrypt = base64_decode($stringToDecrypt); + } + + // Extract IV + $iv_size = $this->adapter->getBlockSize(); + $iv = substr($stringToDecrypt, 0, $iv_size); + $key = $this->getExpandedKey($iv_size, $iv); + + // Decrypt the data + $plainText = $this->adapter->decrypt($stringToDecrypt, $key); + + return $plainText; + } + + /** + * Is AES encryption supported by this PHP installation? + * + * @param Phpfunc $phpfunc + * + * @return boolean + */ + public static function isSupported(Phpfunc $phpfunc = null) + { + if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) + { + $phpfunc = new Phpfunc(); + } + + $adapter = new Openssl(); + + if (!$adapter->isSupported($phpfunc)) + { + $adapter = new Mcrypt(); + + if (!$adapter->isSupported($phpfunc)) + { + return false; + } + } + + if (!$phpfunc->function_exists('base64_encode')) + { + return false; + } + + if (!$phpfunc->function_exists('base64_decode')) + { + return false; + } + + if (!$phpfunc->function_exists('hash_algos')) + { + return false; + } + + $algorightms = $phpfunc->hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + /** + * @param $blockSize + * @param $iv + * + * @return string + */ + public function getExpandedKey($blockSize, $iv) + { + $key = $this->key; + $passLength = strlen($key); + + if (function_exists('mb_strlen')) + { + $passLength = mb_strlen($key, 'ASCII'); + } + + if ($passLength != $blockSize) + { + $iterations = 1000; + $salt = $this->adapter->resizeKey($iv, 16); + $key = hash_pbkdf2('sha256', $this->key, $salt, $iterations, $blockSize, true); + } + + return $key; + } +} + +if (!function_exists('hash_pbkdf2')) +{ + function hash_pbkdf2($algo, $password, $salt, $count, $length = 0, $raw_output = false) + { + if (!in_array(strtolower((string) $algo), hash_algos())) + { + trigger_error(__FUNCTION__ . '(): Unknown hashing algorithm: ' . $algo, E_USER_WARNING); + } + + if (!is_numeric($count)) + { + trigger_error(__FUNCTION__ . '(): expects parameter 4 to be long, ' . gettype($count) . ' given', E_USER_WARNING); + } + + if (!is_numeric($length)) + { + trigger_error(__FUNCTION__ . '(): expects parameter 5 to be long, ' . gettype($length) . ' given', E_USER_WARNING); + } + + if ($count <= 0) + { + trigger_error(__FUNCTION__ . '(): Iterations must be a positive integer: ' . $count, E_USER_WARNING); + } + + if ($length < 0) + { + trigger_error(__FUNCTION__ . '(): Length must be greater than or equal to 0: ' . $length, E_USER_WARNING); + } + + $output = ''; + $block_count = $length ? ceil($length / strlen(hash((string) $algo, '', $raw_output))) : 1; + + for ($i = 1; $i <= $block_count; $i++) + { + $last = $xorsum = hash_hmac((string) $algo, $salt . pack('N', $i), (string) $password, true); + + for ($j = 1; $j < $count; $j++) + { + $xorsum ^= ($last = hash_hmac((string) $algo, $last, (string) $password, true)); + } + + $output .= $xorsum; + } + + if (!$raw_output) + { + $output = bin2hex($output); + } + + return $length ? substr($output, 0, $length) : $output; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Abstraction.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Abstraction.php new file mode 100644 index 000000000..4d665118a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Abstraction.php @@ -0,0 +1,100 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt\AES; + + +/** + * Abstract AES encryption class + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +abstract class Abstraction +{ + /** + * Trims or zero-pads a key / IV + * + * @param string $key The key or IV to treat + * @param int $size The block size of the currently used algorithm + * + * @return null|string Null if $key is null, treated string of $size byte length otherwise + */ + public function resizeKey($key, $size) + { + if (empty($key)) + { + return null; + } + + $keyLength = strlen($key); + + if (function_exists('mb_strlen')) + { + $keyLength = mb_strlen($key, 'ASCII'); + } + + if ($keyLength == $size) + { + return $key; + } + + if ($keyLength > $size) + { + if (function_exists('mb_substr')) + { + return mb_substr($key, 0, $size, 'ASCII'); + } + + return substr($key, 0, $size); + } + + return $key . str_repeat("\0", ($size - $keyLength)); + } + + /** + * Returns null bytes to append to the string so that it's zero padded to the specified block size + * + * @param string $string The binary string which will be zero padded + * @param int $blockSize The block size + * + * @return string The zero bytes to append to the string to zero pad it to $blockSize + */ + protected function getZeroPadding($string, $blockSize) + { + $stringSize = strlen($string); + + if (function_exists('mb_strlen')) + { + $stringSize = mb_strlen($string, 'ASCII'); + } + + if ($stringSize == $blockSize) + { + return ''; + } + + if ($stringSize < $blockSize) + { + return str_repeat("\0", $blockSize - $stringSize); + } + + $paddingBytes = $stringSize % $blockSize; + + return str_repeat("\0", $blockSize - $paddingBytes); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/AesInterface.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/AesInterface.php new file mode 100644 index 000000000..a4c193cfa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/AesInterface.php @@ -0,0 +1,98 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt\AES; + + +use VDM\Joomla\FOF\Utils\Phpfunc; + + +/** + * Interface for AES encryption adapters + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +interface AesInterface +{ + /** + * Sets the AES encryption mode. + * + * WARNING: The strength is deprecated as it has a different effect in MCrypt and OpenSSL. MCrypt was abandoned in + * 2003 before the Rijndael-128 algorithm was officially the Advanced Encryption Standard (AES). MCrypt also offered + * Rijndael-192 and Rijndael-256 algorithms with different block sizes. These are NOT used in AES. OpenSSL, however, + * implements AES correctly. It always uses a 128-bit (16 byte) block. The 192 and 256 bit strengths refer to the + * key size, not the block size. Therefore using different strengths in MCrypt and OpenSSL will result in different + * and incompatible ciphertexts. + * + * TL;DR: Always use $strength = 128! + * + * @param string $mode Choose between CBC (recommended) or ECB + * @param int $strength Bit strength of the key (128, 192 or 256 bits). DEPRECATED. READ NOTES ABOVE. + * + * @return mixed + */ + public function setEncryptionMode($mode = 'cbc', $strength = 128); + + /** + * Encrypts a string. Returns the raw binary ciphertext. + * + * WARNING: The plaintext is zero-padded to the algorithm's block size. You are advised to store the size of the + * plaintext and trim the string to that length upon decryption. + * + * @param string $plainText The plaintext to encrypt + * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) + * @param null|string $iv The initialization vector (for CBC mode algorithms) + * + * @return string The raw encrypted binary string. + */ + public function encrypt($plainText, $key, $iv = null); + + /** + * Decrypts a string. Returns the raw binary plaintext. + * + * $ciphertext MUST start with the IV followed by the ciphertext, even for EBC data (the first block of data is + * dropped in EBC mode since there is no concept of IV in EBC). + * + * WARNING: The returned plaintext is zero-padded to the algorithm's block size during encryption. You are advised + * to trim the string to the original plaintext's length upon decryption. While rtrim($decrypted, "\0") sounds + * appealing it's NOT the correct approach for binary data (zero bytes may actually be part of your plaintext, not + * just padding!). + * + * @param string $cipherText The ciphertext to encrypt + * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) + * + * @return string The raw unencrypted binary string. + */ + public function decrypt($cipherText, $key); + + /** + * Returns the encryption block size in bytes + * + * @return int + */ + public function getBlockSize(); + + /** + * Is this adapter supported? + * + * @param Phpfunc $phpfunc + * + * @return bool + */ + public function isSupported(Phpfunc $phpfunc = null); +} + diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Mcrypt.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Mcrypt.php new file mode 100644 index 000000000..94900d16a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Mcrypt.php @@ -0,0 +1,178 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt\AES; + + +use VDM\Joomla\FOF\Encrypt\Randval; +use VDM\Joomla\FOF\Utils\Phpfunc; +use VDM\Joomla\FOF\Encrypt\AES\AesInterface; +use VDM\Joomla\FOF\Encrypt\AES\Abstraction; + + +/** + * Mcrypt AES encryption class + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +class Mcrypt extends Abstraction implements AesInterface +{ + protected $cipherType = MCRYPT_RIJNDAEL_128; + + protected $cipherMode = MCRYPT_MODE_CBC; + + public function setEncryptionMode($mode = 'cbc', $strength = 128) + { + switch ((int) $strength) + { + default: + case '128': + $this->cipherType = MCRYPT_RIJNDAEL_128; + break; + + case '192': + $this->cipherType = MCRYPT_RIJNDAEL_192; + break; + + case '256': + $this->cipherType = MCRYPT_RIJNDAEL_256; + break; + } + + switch (strtolower($mode)) + { + case 'ecb': + $this->cipherMode = MCRYPT_MODE_ECB; + break; + + default: + case 'cbc': + $this->cipherMode = MCRYPT_MODE_CBC; + break; + } + + } + + public function encrypt($plainText, $key, $iv = null) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = $this->resizeKey($iv, $iv_size); + + if (empty($iv)) + { + $randVal = new Randval(); + $iv = $randVal->generate($iv_size); + } + + $cipherText = mcrypt_encrypt($this->cipherType, $key, $plainText, $this->cipherMode, $iv); + $cipherText = $iv . $cipherText; + + return $cipherText; + } + + public function decrypt($cipherText, $key) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = substr($cipherText, 0, $iv_size); + $cipherText = substr($cipherText, $iv_size); + $plainText = mcrypt_decrypt($this->cipherType, $key, $cipherText, $this->cipherMode, $iv); + + return $plainText; + } + + public function isSupported(Phpfunc $phpfunc = null) + { + if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) + { + $phpfunc = new Phpfunc(); + } + + if (!$phpfunc->function_exists('mcrypt_get_key_size')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_get_iv_size')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_create_iv')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_encrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_decrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_list_algorithms')) + { + return false; + } + + if (!$phpfunc->function_exists('hash')) + { + return false; + } + + if (!$phpfunc->function_exists('hash_algos')) + { + return false; + } + + $algorightms = $phpfunc->mcrypt_list_algorithms(); + + if (!in_array('rijndael-128', $algorightms)) + { + return false; + } + + if (!in_array('rijndael-192', $algorightms)) + { + return false; + } + + if (!in_array('rijndael-256', $algorightms)) + { + return false; + } + + $algorightms = $phpfunc->hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + public function getBlockSize() + { + return mcrypt_get_iv_size($this->cipherType, $this->cipherMode); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Openssl.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Openssl.php new file mode 100644 index 000000000..4d13d5ebc --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/Openssl.php @@ -0,0 +1,193 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt\AES; + + +use VDM\Joomla\FOF\Encrypt\Randval; +use VDM\Joomla\FOF\Utils\Phpfunc; +use VDM\Joomla\FOF\Encrypt\AES\AesInterface; +use VDM\Joomla\FOF\Encrypt\AES\Abstraction; + + +/** + * Openssl AES encryption class + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +class Openssl extends Abstraction implements AesInterface +{ + /** + * The OpenSSL options for encryption / decryption + * + * @var int + */ + protected $openSSLOptions = 0; + + /** + * The encryption method to use + * + * @var string + */ + protected $method = 'aes-128-cbc'; + + public function __construct() + { + $this->openSSLOptions = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; + } + + public function setEncryptionMode($mode = 'cbc', $strength = 128) + { + static $availableAlgorithms = null; + static $defaultAlgo = 'aes-128-cbc'; + + if (!is_array($availableAlgorithms)) + { + $availableAlgorithms = openssl_get_cipher_methods(); + + foreach (array('aes-256-cbc', 'aes-256-ecb', 'aes-192-cbc', + 'aes-192-ecb', 'aes-128-cbc', 'aes-128-ecb') as $algo) + { + if (in_array($algo, $availableAlgorithms)) + { + $defaultAlgo = $algo; + break; + } + } + } + + $strength = (int) $strength; + $mode = strtolower($mode); + + if (!in_array($strength, array(128, 192, 256))) + { + $strength = 256; + } + + if (!in_array($mode, array('cbc', 'ebc'))) + { + $mode = 'cbc'; + } + + $algo = 'aes-' . $strength . '-' . $mode; + + if (!in_array($algo, $availableAlgorithms)) + { + $algo = $defaultAlgo; + } + + $this->method = $algo; + } + + public function encrypt($plainText, $key, $iv = null) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = $this->resizeKey($iv, $iv_size); + + if (empty($iv)) + { + $randVal = new Randval(); + $iv = $randVal->generate($iv_size); + } + + $plainText .= $this->getZeroPadding($plainText, $iv_size); + $cipherText = openssl_encrypt($plainText, $this->method, $key, $this->openSSLOptions, $iv); + $cipherText = $iv . $cipherText; + + return $cipherText; + } + + public function decrypt($cipherText, $key) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = substr($cipherText, 0, $iv_size); + $cipherText = substr($cipherText, $iv_size); + $plainText = openssl_decrypt($cipherText, $this->method, $key, $this->openSSLOptions, $iv); + + return $plainText; + } + + public function isSupported(Phpfunc $phpfunc = null) + { + if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) + { + $phpfunc = new Phpfunc(); + } + + if (!$phpfunc->function_exists('openssl_get_cipher_methods')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_random_pseudo_bytes')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_cipher_iv_length')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_encrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_decrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('hash')) + { + return false; + } + + if (!$phpfunc->function_exists('hash_algos')) + { + return false; + } + + $algorightms = $phpfunc->openssl_get_cipher_methods(); + + if (!in_array('aes-128-cbc', $algorightms)) + { + return false; + } + + $algorightms = $phpfunc->hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + /** + * @return int + */ + public function getBlockSize() + { + return openssl_cipher_iv_length($this->method); + } +} + diff --git a/libraries/jcb_powers/VDM.Gitea/src/index.html b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/src/index.html rename to libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/AES/index.html diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/Randval.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/Randval.php new file mode 100644 index 000000000..8d57ccc9a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/Randval.php @@ -0,0 +1,69 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt; + + +use VDM\Joomla\FOF\Encrypt\Randvalinterface; + + +/** + * Generates cryptographically-secure random values. + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +class Randval implements Randvalinterface +{ + /** + * Returns a cryptographically secure random value. + * + * Since we only run on PHP 7+ we can use random_bytes(), which internally uses a crypto safe PRNG. If the function + * doesn't exist, Joomla already loads a secure polyfill. + * + * The reason this method exists is backwards compatibility with older versions of FOF. It also allows us to quickly + * address any future issues if Joomla drops the polyfill or otherwise find problems with PHP's random_bytes() on + * some weird host (you can't be too careful when releasing mass-distributed software). + * + * @param integer $bytes How many bytes to return + * + * @return string + */ + public function generate($bytes = 32) + { + return random_bytes($bytes); + } + + /** + * Generate random bytes. Adapted from Joomla! 3.2. + * + * Since we only run on PHP 7+ we can use random_bytes(), which internally uses a crypto safe PRNG. If the function + * doesn't exist, Joomla already loads a secure polyfill. + * + * The reason this method exists is backwards compatibility with older versions of FOF. It also allows us to quickly + * address any future issues if Joomla drops the polyfill or otherwise find problems with PHP's random_bytes() on + * some weird host (you can't be too careful when releasing mass-distributed software). + * + * @param integer $length Length of the random data to generate + * + * @return string Random binary data + */ + public function genRandomBytes($length = 32) + { + return random_bytes($length); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/Randvalinterface.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/Randvalinterface.php new file mode 100644 index 000000000..c6642cd3b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/Randvalinterface.php @@ -0,0 +1,37 @@ + + */ +namespace VDM\Joomla\FOF\Encrypt; + + +/** + * Randvalinterface + * + * @package FrameworkOnFramework + * @since 1.0 + * @deprecated Use phpseclib/phpseclib version 3 Instead. + */ +interface Randvalinterface +{ + /** + * + * Returns a cryptographically secure random value. + * + * @return string + * + */ + public function generate(); +} + diff --git a/libraries/phpseclib/index.html b/libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/index.html similarity index 100% rename from libraries/phpseclib/index.html rename to libraries/jcb_powers/VDM.Joomla.FOF/src/Encrypt/index.html diff --git a/libraries/jcb_powers/VDM.Joomla.FOF/src/Utils/Phpfunc.php b/libraries/jcb_powers/VDM.Joomla.FOF/src/Utils/Phpfunc.php new file mode 100644 index 000000000..657e695e7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.FOF/src/Utils/Phpfunc.php @@ -0,0 +1,44 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/Api.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/Api.php new file mode 100644 index 000000000..ecd5787c0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/Api.php @@ -0,0 +1,154 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Abstraction; + + +use VDM\Joomla\Gitea\Utilities\Http; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Response; + + +/** + * The Gitea Api + * + * @since 3.2.0 + */ +abstract class Api +{ + /** + * The Http class + * + * @var Http + * @since 3.2.0 + */ + protected Http $http; + + /** + * The Uri class + * + * @var Uri + * @since 3.2.0 + */ + protected Uri $uri; + + /** + * The Response class + * + * @var Response + * @since 3.2.0 + */ + protected Response $response; + + /** + * The Url string + * + * @var string|null + * @since 3.2.0 + */ + protected ?string $url = null; + + /** + * The token string + * + * @var string|null + * @since 3.2.0 + */ + protected ?string $token = null; + + /** + * Constructor. + * + * @param Http $http The http class. + * @param Uri $uri The uri class. + * @param Response $response The response class. + * + * @since 3.2.0 + **/ + public function __construct(Http $http, Uri $uri, Response $response) + { + $this->http = $http; + $this->uri = $uri; + $this->response = $response; + } + + /** + * Load/Reload API. + * + * @param string|null $url The url. + * @param token|null $token The token. + * @param bool $backup The backup swapping switch. + * + * @return void + * @since 3.2.0 + **/ + public function load_(?string $url = null, ?string $token = null, bool $backup = true): void + { + // we keep the old values + // so we can reset after our call + // for the rest of the container + if ($backup) + { + if ($url !== null) + { + $this->url = $this->uri->getUrl(); + } + + if ($token !== null) + { + $this->token = $this->http->getToken(); + } + } + + if ($url !== null) + { + $this->uri->setUrl($url); + } + + if ($token !== null) + { + $this->http->setToken($token); + } + } + + /** + * Reset to previous toke, url it set + * + * @return void + * @since 3.2.0 + **/ + public function reset_(): void + { + if ($this->url !== null) + { + $this->uri->setUrl($this->url); + $this->url = null; + } + + if ($this->token !== null) + { + $this->http->setToken($this->token); + $this->token = null; + } + } + + /** + * Get the API url + * + * @return string + * @since 3.2.0 + **/ + public function api() + { + return $this->uri->api(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Cron.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Cron.php new file mode 100644 index 000000000..04031c26a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Cron.php @@ -0,0 +1,72 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Cron + * + * @since 3.2.0 + */ +class Cron extends Api +{ + /** + * List cron tasks. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/admin/cron"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Run cron task. + * + * @param string $task The cron task to run. + * + * @return string + * @since 3.2.0 + **/ + public function run(string $task): string + { + // Build the request path. + $path = "/admin/cron/{$task}"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Organizations.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Organizations.php new file mode 100644 index 000000000..df1e6b444 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Organizations.php @@ -0,0 +1,51 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Organizations + * + * @since 3.2.0 + */ +class Organizations extends Api +{ + /** + * List all organizations. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/admin/orgs"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Unadopted.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Unadopted.php new file mode 100644 index 000000000..c73cf3ebe --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Unadopted.php @@ -0,0 +1,101 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Unadopted + * + * @since 3.2.0 + */ +class Unadopted extends Api +{ + /** + * List unadopted repositories. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * @param string $pattern Pattern of repositories to search for. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10, string $pattern = ''): ?array + { + // Build the request path. + $path = "/admin/unadopted"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + if (!empty($pattern)) + { + $uri->setVar('pattern', $pattern); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Adopt unadopted files as a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function adopt(string $owner, string $repo): string + { + // Build the request path. + $path = "/admin/unadopted/{$owner}/{$repo}"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Delete unadopted files. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo): string + { + // Build the request path. + $path = "/admin/unadopted/{$owner}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users.php new file mode 100644 index 000000000..47ec3e54a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users.php @@ -0,0 +1,207 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users + * + * @since 3.2.0 + */ +class Users extends Api +{ + /** + * List all users. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/admin/users"; + + // build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Create a user with extended options. + * + * @param string $loginName The user's login name. + * @param string $email The user's email address. + * @param string $password The user's password. + * @param string|null $username The username. + * @param string|null $fullName The user's full name (optional). + * @param bool|null $mustChangePassword User must change password on next login (optional). + * @param bool|null $restricted Restrict the user (optional). + * @param bool|null $sendNotify Send a notification email to the user (optional). + * @param int|null $sourceId Source ID (optional). + * @param string|null $visibility The user's visibility (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $loginName, + string $email, + string $password, + string $username, + ?string $fullName = null, + ?bool $mustChangePassword = null, + ?bool $restricted = null, + ?bool $sendNotify = null, + ?int $sourceId = null, + ?string $visibility = null + ): ?object + { + // Build the request path. + $path = "/admin/users"; + + // Set the user data. + $data = new \stdClass(); + $data->login_name = $loginName; + $data->email = $email; + $data->password = $password; + $data->username = $username; + $data->full_name = $fullName; + $data->must_change_password = $mustChangePassword; + $data->restricted = $restricted; + $data->send_notify = $sendNotify; + $data->source_id = $sourceId; + $data->visibility = $visibility; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Delete a user. + * + * @param string $username The user's display name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $username): string + { + // Build the request path. + $path = "/admin/users/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit an existing user. + * + * @param string $username The user's display name. + * @param string $loginName The user's login name. + * @param int $sourceId The user's source ID. + * @param bool $active Optional. Is the user active? Default: false. + * @param bool $admin Optional. Is the user an admin? Default: false. + * @param bool $allowCreateOrganization Optional. Can the user create an organization? Default: false. + * @param bool $allowGitHook Optional. Can the user create Git hooks? Default: false. + * @param bool $allowImportLocal Optional. Can the user import local repositories? Default: false. + * @param string $description Optional. The user's description. Default: ''. + * @param string $email Optional. The user's email address. Default: ''. + * @param string $fullName Optional. The user's full name. Default: ''. + * @param string $location Optional. The user's location. Default: ''. + * @param int $maxRepoCreation Optional. Maximum repositories the user can create. Default: 0. + * @param bool $mustChangePassword Optional. Must the user change their password? Default: false. + * @param string $password Optional. The user's password. Default: ''. + * @param bool $prohibitLogin Optional. Is the user's login prohibited? Default: false. + * @param bool $restricted Optional. Is the user restricted? Default: false. + * @param string $visibility Optional. The user's visibility setting. Default: ''. + * @param string $website Optional. The user's website. Default: ''. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $username, + string $loginName, + int $sourceId, + bool $active = false, + bool $admin = false, + bool $allowCreateOrganization = false, + bool $allowGitHook = false, + bool $allowImportLocal = false, + string $description = '', + string $email = '', + string $fullName = '', + string $location = '', + int $maxRepoCreation = 0, + bool $mustChangePassword = false, + string $password = '', + bool $prohibitLogin = false, + bool $restricted = false, + string $visibility = '', + string $website = '' + ): ?object + { + // Build the request path. + $path = "/admin/users/{$username}"; + + // Set the data. + $data = [ + 'login_name' => $loginName, + 'source_id' => $sourceId, + 'active' => $active, + 'admin' => $admin, + 'allow_create_organization' => $allowCreateOrganization, + 'allow_git_hook' => $allowGitHook, + 'allow_import_local' => $allowImportLocal, + 'description' => $description, + 'email' => $email, + 'full_name' => $fullName, + 'location' => $location, + 'max_repo_creation' => $maxRepoCreation, + 'must_change_password' => $mustChangePassword, + 'password' => $password, + 'prohibit_login' => $prohibitLogin, + 'restricted' => $restricted, + 'visibility' => $visibility, + 'website' => $website + ]; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Keys.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Keys.php new file mode 100644 index 000000000..bea01deb0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Keys.php @@ -0,0 +1,86 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin\Users; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users Keys + * + * @since 3.2.0 + */ +class Keys extends Api +{ + /** + * Add a public key on behalf of a user. + * + * @param string $userName The user's display name. + * @param string $publicKey The public key to add. + * @param string $keyTitle Title of the key to add. + * @param bool $readOnly Whether the key has only read access or read/write (optional). + * @param string|null $description Description of the key (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function add( + string $userName, + string $publicKey, + string $keyTitle, + bool $readOnly = false, + ?string $description = null + ): ?object + { + // Build the request path. + $path = "/admin/users/{$userName}/keys"; + + // Set the key data. + $data = new \stdClass(); + $data->key = $publicKey; + $data->title = $keyTitle; + $data->read_only = $readOnly; + $data->description = $description; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Delete a user's public key. + * + * @param string $username The user's display name. + * @param int $id The public key ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $username, int $id): string + { + // Build the request path. + $path = "/admin/users/{$username}/keys/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Organization.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Organization.php new file mode 100644 index 000000000..ec1843ff9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Organization.php @@ -0,0 +1,70 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin\Users; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users Organization + * + * @since 3.2.0 + */ +class Organization extends Api +{ + /** + * Create an organization on behalf of a user. + * + * @param string $username The user's display name. + * @param string $fullName The organization full name. + * @param string|null $description The organization description (optional). + * @param string|null $location The organization location (optional). + * @param bool $repoAdminChangeTeamAccess Whether repo admin can change team access (optional). + * @param string $visibility The organization visibility (optional). + * @param string|null $website The organization website (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $username, + string $fullName, + ?string $description = null, + ?string $location = null, + bool $repoAdminChangeTeamAccess = false, + string $visibility = 'public', + ?string $website = null + ): ?object + { + // Build the request path. + $path = "/admin/users/{$username}/orgs"; + + // Set the organization data. + $data = new \stdClass(); + $data->full_name = $fullName; + $data->description = $description; + $data->location = $location; + $data->repo_admin_change_team_access = $repoAdminChangeTeamAccess; + $data->visibility = $visibility; + $data->website = $website; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Repository.php new file mode 100644 index 000000000..bfade26a8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Repository.php @@ -0,0 +1,85 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Admin\Users; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * Create a repository on behalf of a user. + * + * @param string $username The user's display name. + * @param string $repoName The repository name. + * @param string|null $description The repository description (optional). + * @param bool $auto_init Whether the repository should be auto-initialized? (optional). + * @param string|null $default_branch Default branch of the repository (optional). + * @param string|null $gitignores Gitignores to use (optional). + * @param string|null $issue_labels Label-Set to use (optional). + * @param string|null $license License to use (optional). + * @param bool $private Whether the repository is private (optional). + * @param string|null $readme Readme of the repository to create (optional). + * @param bool $template Whether the repository is template (optional). + * @param string|null $trust_model TrustModel of the repository (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $username, + string $repoName, + ?string $description = null, + bool $auto_init = false, + ?string $default_branch = null, + ?string $gitignores = null, + ?string $issue_labels = null, + ?string $license = null, + bool $private = false, + ?string $readme = null, + bool $template = false, + ?string $trust_model = null + ): ?object + { + // Build the request path. + $path = "/admin/users/{$username}/repos"; + + // Set the repository data. + $data = new \stdClass(); + $data->name = $repoName; + $data->description = $description; + $data->auto_init = $auto_init; + $data->default_branch = $default_branch; + $data->gitignores = $gitignores; + $data->issue_labels = $issue_labels; + $data->license = $license; + $data->private = $private; + $data->readme = $readme; + $data->template = $template; + $data->trust_model = $trust_model; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Factory.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Factory.php new file mode 100644 index 000000000..78918e811 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Factory.php @@ -0,0 +1,97 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use Joomla\DI\Container; +use VDM\Joomla\Gitea\Service\Utilities; +use VDM\Joomla\Gitea\Service\Jcb; +use VDM\Joomla\Gitea\Service\Settings; +use VDM\Joomla\Gitea\Service\Organization; +use VDM\Joomla\Gitea\Service\User; +use VDM\Joomla\Gitea\Service\Repository; +use VDM\Joomla\Gitea\Service\Package; +use VDM\Joomla\Gitea\Service\Issue; +use VDM\Joomla\Gitea\Service\Notifications; +use VDM\Joomla\Gitea\Service\Miscellaneous; +use VDM\Joomla\Gitea\Service\Admin; +use VDM\Joomla\Interfaces\FactoryInterface; + + +/** + * Gitea Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Package Container + * + * @var Container + * @since 3.2.0 + **/ + protected static $container = null; + + /** + * Get any class from the package container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _($key) + { + return self::getContainer()->get($key); + } + + /** + * Get the global package container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Utilities()) + ->registerServiceProvider(new Jcb()) + ->registerServiceProvider(new Settings()) + ->registerServiceProvider(new Organization()) + ->registerServiceProvider(new User()) + ->registerServiceProvider(new Repository()) + ->registerServiceProvider(new Package()) + ->registerServiceProvider(new Issue()) + ->registerServiceProvider(new Notifications()) + ->registerServiceProvider(new Miscellaneous()) + ->registerServiceProvider(new Admin()); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue.php new file mode 100644 index 000000000..bfeb418ea --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue.php @@ -0,0 +1,406 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue + * + * @since 3.2.0 + */ +class Issue extends Api +{ + /** + * List a repository's issues. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $state The state of the issues to get, defaults to 'open'. + * @param int $page The page to get, defaults to null. + * @param int $limit The number of issues per page, defaults to null. + * @param string|null $labels Comma-separated list of labels, defaults to null. + * @param string|null $q The search string, defaults to null. + * @param string|null $type The type to filter by (issues/pulls), defaults to null. + * @param string|null $milestones Comma-separated list of milestone names or IDs, defaults to null. + * @param string|null $since Only show items updated after the given time, defaults to null. + * @param string|null $before Only show items updated before the given time, defaults to null. + * @param string|null $createdBy Only show items created by the given user, defaults to null. + * @param string|null $assignedBy Only show items assigned to the given user, defaults to null. + * @param string|null $mentionedBy Only show items where the given user is mentioned, defaults to null. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + string $state = 'open', + int $page = 1, + int $limit = 10, + ?string $labels = null, + ?string $q = null, + ?string $type = null, + ?string $milestones = null, + ?string $since = null, + ?string $before = null, + ?string $createdBy = null, + ?string $assignedBy = null, + ?string $mentionedBy = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Set the query parameters + $uri->setVar('state', $state); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + $uri->setVar('labels', $labels); + $uri->setVar('q', $q); + $uri->setVar('type', $type); + $uri->setVar('milestones', $milestones); + $uri->setVar('since', $since); + $uri->setVar('before', $before); + $uri->setVar('created_by', $createdBy); + $uri->setVar('assigned_by', $assignedBy); + $uri->setVar('mentioned_by', $mentionedBy); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $index): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create an issue. If using deadline only the date will be taken into account, and time of day ignored. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $issueTitle The issue title. + * @param array|null $assignees The array of assignees, defaults to null. + * @param string|null $issueBody The issue body, defaults to null. + * @param bool|null $closed If the issue is closed, defaults to null. + * @param string|null $dueDate The deadline for the issue, format: "YYYY-MM-DD", defaults to null. + * @param array|null $labelIds The array of label IDs to attach to the issue, defaults to null. + * @param int|null $milestoneId The milestone ID, defaults to null. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $issueTitle, + ?array $assignees = null, + ?string $issueBody = null, + ?bool $closed = null, + ?string $dueDate = null, + ?array $labelIds = null, + ?int $milestoneId = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues"; + + // Build the request data. + $data = new \stdClass(); + $data->title = $issueTitle; + $data->body = $issueBody; + $data->assignees = $assignees; + $data->closed = $closed; + $data->due_date = $dueDate; + $data->labels = $labelIds; + $data->milestone = $milestoneId; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Search for issues across the repositories that the user has access to. + * + * @param string $q Search query. + * @param int $page Page number (default 1). + * @param int $limit Page size (default 10, max 50). + * @param string|null $state Issue state (default open). + * @param string|null $labels Label filter, comma-separated. + * @param string|null $milestones Milestone filter, comma-separated. + * @param int|null $priorityRepoId Repository to prioritize in the results. + * @param string|null $type Filter by type (issues/pulls). + * @param string|null $since Only show notifications updated after the given time (RFC 3339 format). + * @param string|null $before Only show notifications updated before the given time (RFC 3339 format). + * @param bool|null $assigned Filter assigned to you (default false). + * @param bool|null $created Filter created by you (default false). + * @param bool|null $mentioned Filter mentioning you (default false). + * @param bool|null $reviewRequested Filter pulls requesting your review (default false). + * @param string|null $owner Filter by owner. + * @param string|null $team Filter by team (requires organization owner parameter). + * + * @return array|null + * @since 3.2.0 + **/ + public function search( + string $q, + int $page = 1, + int $limit = 10, + ?string $state = 'open', + ?string $labels = null, + ?string $milestones = null, + ?int $priorityRepoId = null, + ?string $type = null, + ?string $since = null, + ?string $before = null, + ?bool $assigned = null, + ?bool $created = null, + ?bool $mentioned = null, + ?bool $reviewRequested = null, + ?string $owner = null, + ?string $team = null + ): ?array + { + // Build the request path. + $path = "/repos/issues/search"; + + // Set the URL parameters. + $uri = $this->uri->get($path); + $uri->setVar('q', $q); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + $uri->setVar('state', $state); + + if ($labels !== null) + { + $uri->setVar('labels', $labels); + } + + if ($milestones !== null) + { + $uri->setVar('milestones', $milestones); + } + + if ($priorityRepoId !== null) + { + $uri->setVar('priority_repo_id', $priorityRepoId); + } + + if ($type !== null) + { + $uri->setVar('type', $type); + } + + if ($since !== null) + { + $uri->setVar('since', $since); + } + + if ($before !== null) + { + $uri->setVar('before', $before); + } + + if ($assigned !== null) + { + $uri->setVar('assigned', $assigned); + } + + if ($created !== null) + { + $uri->setVar('created', $created); + } + + if ($mentioned !== null) + { + $uri->setVar('mentioned', $mentioned); + } + + if ($reviewRequested !== null) + { + $uri->setVar('review_requested', $reviewRequested); + } + + if ($owner !== null) + { + $uri->setVar('owner', $owner); + } + + if ($team !== null) + { + $uri->setVar('team', $team); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Edit an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string|null $assignee The assignee, defaults to null. + * @param array|null $assignees The assignees, defaults to null. + * @param string|null $body The issue body, defaults to null. + * @param string|null $dueDate The due date, defaults to null. + * @param int|null $milestone The milestone, defaults to null. + * @param string|null $ref The reference, defaults to null. + * @param string|null $state The issue state, defaults to null. + * @param string|null $title The issue title, defaults to null. + * @param bool|null $unsetDueDate The flag to unset due date, defaults to null. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + int $index, + ?string $assignee = null, + ?array $assignees = null, + ?string $body = null, + ?string $dueDate = null, + ?int $milestone = null, + ?string $ref = null, + ?string $state = null, + ?string $title = null, + ?bool $unsetDueDate = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}"; + + // Prepare the issue data. + $editIssueData = new \stdClass(); + + if ($assignee !== null || $assignees !== null) + { + $editIssueData->assignee = new \stdClass(); + + if ($assignee !== null) + { + $editIssueData->assignee->name = $assignee; + } + + if ($assignees !== null) + { + $editIssueData->assignee->names = $assignees; + } + } + + if ($body !== null) + { + $editIssueData->body = $body; + } + + if ($dueDate !== null || $unsetDueDate !== null) + { + $editIssueData->dueDate = new \stdClass(); + + if ($dueDate !== null) + { + $editIssueData->dueDate->date = $dueDate; + } + + if ($unsetDueDate !== null) + { + $editIssueData->dueDate->unset = $unsetDueDate; + } + } + + if ($milestone !== null) + { + $editIssueData->milestone = $milestone; + } + + if ($ref !== null) + { + $editIssueData->ref = $ref; + } + + if ($state !== null) + { + $editIssueData->state = $state; + } + + if ($title !== null) + { + $editIssueData->title = $title; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($editIssueData) + ) + ); + } + + /** + * Delete an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Comments.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Comments.php new file mode 100644 index 000000000..c244035c9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Comments.php @@ -0,0 +1,176 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Comments + * + * @since 3.2.0 + */ +class Comments extends Api +{ + /** + * List all comments on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $page The page number to get, defaults to 1. + * @param int $limit The number of comments per page, defaults to 10. + * @param string|null $since The date-time since when to get comments, defaults to null. + * @param string|null $before The date-time before when to get comments, defaults to null. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $index, + int $page = 1, + int $limit = 10, + ?string $since = null, + ?string $before = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/comments"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Set the 'since' and 'before' parameters if not null. + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a comment. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $commentId): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a comment. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $commentId): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a comment. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * @param string $commentBody The new comment body. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit(string $owner, string $repo, int $commentId, string $commentBody): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}"; + + // Build the request data. + $data = new \stdClass(); + $data->body = $commentBody; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Add a comment to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $issueIndex The issue index. + * @param string $commentBody The comment body. + * + * @return object|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $issueIndex, string $commentBody): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$issueIndex}/comments"; + + // Build the request data. + $data = new \stdClass(); + $data->body = $commentBody; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Deadline.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Deadline.php new file mode 100644 index 000000000..6c13d07a4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Deadline.php @@ -0,0 +1,54 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Deadline + * + * @since 3.2.0 + */ +class Deadline extends Api +{ + /** + * Set an issue deadline. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string|null $dueDate The deadline date string in the format YYYY-MM-DD or null to delete the deadline. + * + * @return object + * @since 3.2.0 + **/ + public function set(string $owner, string $repo, int $index, ?string $dueDate): object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/deadline"; + + // Build the request data. + $data = new \stdClass(); + $data->due_date = $dueDate; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Labels.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Labels.php new file mode 100644 index 000000000..fda80dce9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Labels.php @@ -0,0 +1,181 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Labels + * + * @since 3.2.0 + */ +class Labels extends Api +{ + /** + * Get all of a repository's labels. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels"; + + // Get the URI object with the request path. + $uri = $this->uri->get($path); + + // Add the page and limit query parameters if provided. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get an issue's labels. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return array|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $index): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Replace an issue's labels. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param array $labels An array of labels to replace the current issue labels. + * + * @return object + * @since 3.2.0 + **/ + public function replace(string $owner, string $repo, int $index, array $labels): object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Build the request data. + $data = new \stdClass(); + $data->labels = $labels; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Add a label to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param array $labels An array of label IDs to add. + * + * @return array|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $index, array $labels): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Build the request data. + $data = new \stdClass(); + $data->labels = $labels; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Remove a label from an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $labelId The ID of the label to remove. + * + * @return string + * @since 3.2.0 + **/ + public function remove(string $owner, string $repo, int $index, int $labelId): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels/{$labelId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Remove all labels from an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function clear(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Milestones.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Milestones.php new file mode 100644 index 000000000..5178a7371 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Milestones.php @@ -0,0 +1,230 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Milestones + * + * @since 3.2.0 + */ +class Milestones extends Api +{ + /** + * Create a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $title The title of the milestone. + * @param string|null $description Optional. The description of the milestone. + * @param string|null $dueOn Optional. The due date of the milestone. + * @param string|null $state Optional. The state of the milestone. Default is 'open'. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $title, + ?string $description = null, + ?string $dueOn = null, + ?string $state = 'open' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the required data. + $data->title = $title; + + // Set all the optional data that has been provided. + if ($description !== null) + { + $data->description = $description; + } + if ($dueOn !== null) + { + $data->due_on = $dueOn; + } + if ($state !== null) + { + $data->state = $state; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get all of a repository's opened milestones. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string|null $state Optional. Milestone state. Recognized values are open, closed, and all. Defaults to "open". + * @param string|null $name Optional. Filter by milestone name. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + ?string $state = 'open', + ?string $name = null, + ?int $page = null, + ?int $limit = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('state', $state); + if ($name !== null) + { + $uri->setVar('name', $name); + } + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $milestoneId The ID of the milestone. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $milestoneId): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones/{$milestoneId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $milestoneId The ID of the milestone to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, string $milestoneId): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones/{$milestoneId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $milestoneId The ID of the milestone to update. + * @param string $title Optional. The new title of the milestone. + * @param string $description Optional. The new description of the milestone. + * @param string $dueOn Optional. The new due date of the milestone. + * @param string $state Optional. The new state of the milestone. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + string $milestoneId, + string $title = null, + string $description = null, + string $dueOn = null, + string $state = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the optional data that has been provided. + if ($title !== null) + { + $data->title = $title; + } + if ($description !== null) + { + $data->description = $description; + } + if ($dueOn !== null) + { + $data->due_on = $dueOn; + } + if ($state !== null) + { + $data->state = $state; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones/{$milestoneId}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions.php new file mode 100644 index 000000000..759529592 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions.php @@ -0,0 +1,110 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Reactions + * + * @since 3.2.0 + */ +class Reactions extends Api +{ + /** + * Get a list reactions of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $page The page to get, defaults to 1. + * @param int $limit The number of reactions per page, defaults to 10. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $index, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/reactions"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Set the URI variables. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a reaction to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $content The name of the reaction to add. + * + * @return object|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $index, string $content): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/reactions"; + + // Build the request data. + $data = new \stdClass(); + $data->content = $content; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Remove a reaction from an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $content The name of the reaction to remove. + * + * @return string + * @since 3.2.0 + **/ + public function remove(string $owner, string $repo, int $index, string $content): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/reactions"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('content', $content); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/Comment.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/Comment.php new file mode 100644 index 000000000..0f2ca7818 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/Comment.php @@ -0,0 +1,103 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue\Reactions; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Reactions Comment + * + * @since 3.2.0 + */ +class Comment extends Api +{ + /** + * Get a list of reactions from a comment of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $commentId): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}/reactions"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add a reaction to a comment of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * @param string $content The reaction to add, e.g. "+1". + * + * @return object|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $commentId, string $content): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}/reactions"; + + // Build the request data. + $data = new \stdClass(); + $data->content = $content; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Remove a reaction from a comment of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * @param string $content The reaction to remove, e.g. "+1". + * + * @return string + * @since 3.2.0 + **/ + public function remove(string $owner, string $repo, int $commentId, string $content): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}/reactions"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('content', $content); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/Comments.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/Comments.php new file mode 100644 index 000000000..3ca83fc75 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/Comments.php @@ -0,0 +1,67 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Repository Comments + * + * @since 3.2.0 + */ +class Comments extends Api +{ + /** + * List all comments in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $page The page to get, defaults to 1. + * @param int $limit The number of comments per page, defaults to 10. + * @param string|null $since The date-time string to filter updated comments since, defaults to null. + * @param string|null $before The date-time string to filter updated comments before, defaults to null. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $page = 1, int $limit = 10, ?string $since = null, ?string $before = null): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Set the URI variables. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + if ($since !== null) + { + $uri->setVar('since', $since); + } + + if ($before !== null) + { + $uri->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Stopwatch.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Stopwatch.php new file mode 100644 index 000000000..674541641 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Stopwatch.php @@ -0,0 +1,95 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Stopwatch + * + * @since 3.2.0 + */ +class Stopwatch extends Api +{ + /** + * Start stopwatch on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function start(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/stopwatch/start"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), '' + ), 201, 'success' + ); + } + + /** + * Stop an issue's existing stopwatch. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function stop(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/stopwatch/stop"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), '' + ), 201, 'success' + ); + } + + /** + * Delete an issue's existing stopwatch. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/stopwatch/delete"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Subscriptions.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Subscriptions.php new file mode 100644 index 000000000..c29bfb680 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Subscriptions.php @@ -0,0 +1,137 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Subscriptions + * + * @since 3.2.0 + */ +class Subscriptions extends Api +{ + /** + * Get users who subscribed on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $index, + ?int $page = null, + ?int $limit = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions"; + + // Set the query parameters. + $uri = $this->uri->get($path); + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if user is subscribed to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return object|null + * @since 3.2.0 + **/ + public function check(string $owner, string $repo, int $index): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions/check"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Subscribe user to issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $user The username to subscribe. + * + * @return string + * @since 3.2.0 + **/ + public function subscribe(string $owner, string $repo, int $index, string $user): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions/{$user}"; + + // Send the put request. + return $this->response->get_( + $this->http->put( + $this->uri->get($path), '' + ), [200 => 'already subscribed', 201 => 'success'] + ); + } + + /** + * Unsubscribe user from issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $user The username to unsubscribe. + * + * @return string + * @since 3.2.0 + **/ + public function unsubscribe(string $owner, string $repo, int $index, string $user): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions/{$user}"; + + // Send the delete request. + return $this->response->get_( + $this->http->delete( + $this->uri->get($path) + ), [200 => 'already unsubscribed', 201 => 'success'] + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Timeline.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Timeline.php new file mode 100644 index 000000000..4c54937b4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Timeline.php @@ -0,0 +1,78 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Timeline + * + * @since 3.2.0 + */ +class Timeline extends Api +{ + /** + * List all comments and events on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string|null $since Optional. If provided, only comments updated since the specified time are returned. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * @param string|null $before Optional. If provided, only comments updated before the provided time are returned. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $index, + ?string $since = null, + ?int $page = null, + ?int $limit = null, + ?string $before = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/timeline"; + + // Set the query parameters. + $uri = $this->uri->get($path); + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Times.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Times.php new file mode 100644 index 000000000..7c33c2ab6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Times.php @@ -0,0 +1,179 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Times + * + * @since 3.2.0 + */ +class Times extends Api +{ + /** + * List an issue's tracked times. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $user Optional. Filter by user. + * @param string $since Optional. Show times updated after the given time. + * @param string $before Optional. Show times updated before the given time. + * @param int $page Optional. Page number of results to return (1-based). + * @param int $limit Optional. Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $index, + string $user = null, + string $since = null, + string $before = null, + int $page = null, + int $limit = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times"; + + // Prepare the query parameters. + $uri = $this->uri->get($path); + if ($user !== null) + { + $uri->setVar('user', $user); + } + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request with the query parameters. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add tracked time to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $time The tracked time in seconds. + * @param string $created Optional. The date and time of the tracked time in RFC 3339 format. + * @param string $userName Optional. User who spent the time. + * + * @return object|null + * @since 3.2.0 + **/ + public function add( + string $owner, + string $repo, + int $index, + int $time, + string $created = null, + string $userName = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the needed data. + $data->time = $time; + if ($created !== null) + { + $data->created = $created; + } + if ($userName !== null) + { + $data->user_name = $userName; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Reset a tracked time of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function reset(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Delete specific tracked time. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $id The ID of the tracked time to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $index, int $id): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Labels.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Labels.php new file mode 100644 index 000000000..43f2c9f6f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Labels.php @@ -0,0 +1,162 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Labels + * + * @since 3.2.0 + */ +class Labels extends Api +{ + /** + * Create a label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $labelName The name of the label. + * @param string $labelColor The color of the label, in hexadecimal format with the leading '#'. + * @param string $labelDescription Optional. The description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function create(string $owner, string $repo, string $labelName, string $labelColor, string $labelDescription = ''): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the needed data. + $data->name = $labelName; + $data->color = $labelColor; + if (!empty($labelDescription)) + { + $data->description = $labelDescription; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a single label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $id The ID of the label to retrieve. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $id): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $id The ID of the label to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, string $id): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $id The ID of the label to update. + * @param string $labelName Optional. The new name of the label. + * @param string $labelColor Optional. The new color of the label, in hexadecimal format without the leading '#'. + * @param string $labelDescription Optional. The new description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + string $id, + string $labelName = '', + string $labelColor = '', + string $labelDescription = '' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the optional data that has been provided. + if (!empty($labelName)) + { + $data->name = $labelName; + } + + if (!empty($labelColor)) + { + $data->color = $labelColor; + } + + if (!empty($labelDescription)) + { + $data->description = $labelDescription; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels/{$id}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Activitypub.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Activitypub.php new file mode 100644 index 000000000..78c6d270b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Activitypub.php @@ -0,0 +1,69 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Activitypub + * + * @since 3.2.0 + */ +class Activitypub extends Api +{ + /** + * Returns the Person actor for a user. + * + * @param string $username The user's username. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $username): ?object + { + // Build the request path. + $path = "/activitypub/user/{$username}"; + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Send to the user's inbox. + * + * @param string $username The user's username. + * @param object $postData The post data. + * + * @return string + * @since 3.2.0 + **/ + public function send(string $username, object $postData): string + { + // Build the request path. + $path = "/activitypub/user/{$username}/inbox"; + + // Send the POST request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($postData) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Gpg.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Gpg.php new file mode 100644 index 000000000..5a92c54a6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Gpg.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Gpg + * + * @since 3.2.0 + */ +class Gpg extends Api +{ + /** + * Get default signing-key.gpg. + * + * @return string|null + * @since 3.2.0 + **/ + public function get(): ?string + { + // Build the request path. + $path = "/signing-key.gpg"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Markdown.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Markdown.php new file mode 100644 index 000000000..f6f54e5b9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Markdown.php @@ -0,0 +1,87 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Markdown + * + * @since 3.2.0 + */ +class Markdown extends Api +{ + /** + * Render a markdown document as HTML. + * + * @param string $markdownText The markdown text to render. + * @param bool $isWikiPage Is it a wiki page? + * @param string $context Context to render. + * @param string $mode Mode to render. + * + * @return string|null + * @since 3.2.0 + **/ + public function render( + string $markdownText, + bool $isWikiPage = false, + string $context = 'string', + string $mode = 'string' + ): ?string + { + // Build the request path. + $path = "/markdown"; + + // Set the markdown data. + $data = new \stdClass(); + $data->Text = $markdownText; + $data->Wiki = $isWikiPage; + $data->Context = $context; + $data->Mode = $mode; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data), + ['accept' => 'text/html'] + ) + ); + } + + /** + * Render raw markdown as HTML. + * + * @param string $rawMarkdown The raw markdown text to render. + * + * @return string|null + * @since 3.2.0 + **/ + public function raw(string $rawMarkdown): ?string + { + // Build the request path. + $path = "/markdown/raw"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + $rawMarkdown, + ['Content-Type' => 'text/plain', 'accept' => 'text/html'] + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/NodeInfo.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/NodeInfo.php new file mode 100644 index 000000000..fe714b220 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/NodeInfo.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous NodeInfo + * + * @since 3.2.0 + */ +class NodeInfo extends Api +{ + /** + * Returns the nodeinfo of the Gitea application. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/nodeinfo"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Version.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Version.php new file mode 100644 index 000000000..696db50e9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Version.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Version + * + * @since 3.2.0 + */ +class Version extends Api +{ + /** + * Returns the version of the Gitea application. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/version"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications.php new file mode 100644 index 000000000..ffe33a83b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications.php @@ -0,0 +1,149 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Notifications + * + * @since 3.2.0 + */ +class Notifications extends Api +{ + /** + * List user's notification threads. + * + * @param bool|null $all Show notifications marked as read (optional). + * @param array|null $statusTypes Show notifications with the provided status types (optional). + * @param array|null $subjectType Filter notifications by subject type (optional). + * @param string|null $since Show notifications updated after the given time (optional). + * @param string|null $before Show notifications updated before the given time (optional). + * @param int $page Page number of results to return (optional). + * @param int $limit Page size of results (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + ?bool $all = null, + ?array $statusTypes = null, + ?array $subjectType = null, + ?string $since = null, + ?string $before = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($subjectType !== null) + { + $uri->setVar('subject-type', implode(',', $subjectType)); + } + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Mark notification threads as read, pinned, or unread. + * + * @param string|null $lastReadAt Describes the last point that notifications were checked (optional). + * @param bool|null $all If true, mark all notifications on this repo (optional). + * @param array|null $statusTypes Mark notifications with the provided status types (optional). + * @param string|null $toStatus Status to mark notifications as (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function update( + ?string $lastReadAt = null, + ?bool $all = null, + ?array $statusTypes = null, + ?string $toStatus = null + ): ?array + { + // Build the request path. + $path = "/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($lastReadAt !== null) + { + $uri->setVar('last_read_at', $lastReadAt); + } + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($toStatus !== null) + { + $uri->setVar('to-status', $toStatus); + } + + // Send the put request. + return $this->response->get( + $this->http->put($uri, ''), 205 + ); + } + + /** + * Check if unread notifications exist. + * + * @return object|null + * @since 3.2.0 + **/ + public function check(): ?object + { + // Build the request path. + $path = "/notifications/new"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Repository.php new file mode 100644 index 000000000..452039144 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Repository.php @@ -0,0 +1,144 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Notifications; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Notifications Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * List user's notification threads on a specific repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param bool $all Show notifications marked as read. + * @param array $statusTypes Show notifications with the provided status types. + * @param array $subjectTypes Filter notifications by subject type. + * @param string $since Show notifications updated after the given time. + * @param string $before Show notifications updated before the given time. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + bool $all = false, + array $statusTypes = [], + array $subjectTypes = [], + string $since = '', + string $before = '', + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + + if ($all) + { + $uri->setVar('all', $all); + } + + if (!empty($statusTypes)) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + + if (!empty($subjectTypes)) + { + $uri->setVar('subject-type', implode(',', $subjectTypes)); + } + + if (!empty($since)) + { + $uri->setVar('since', $since); + } + + if (!empty($before)) + { + $uri->setVar('before', $before); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Mark notification threads as read, pinned, or unread on a specific repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param bool|null $all Mark all notifications on this repo (optional). + * @param array|null $statusTypes Mark notifications with the provided status types (optional). + * @param string|null $toStatus Status to mark notifications as (optional). + * @param string|null $lastReadAt Last point that notifications were checked (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + ?bool $all = null, + ?array $statusTypes = null, + ?string $toStatus = null, + ?string $lastReadAt = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($toStatus !== null) + { + $uri->setVar('to-status', $toStatus); + } + if ($lastReadAt !== null) + { + $uri->setVar('last_read_at', $lastReadAt); + } + + // Send the put request. + return $this->response->get( + $this->http->put($uri, ''), 205 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Thread.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Thread.php new file mode 100644 index 000000000..ae8daaab0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Thread.php @@ -0,0 +1,96 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Notifications; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Notifications Thread + * + * @since 3.2.0 + */ +class Thread extends Api +{ + /** + * Get notification thread by ID. + * + * @param int $id The notification thread ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/notifications/threads/{$id}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Mark notification threads as read, pinned, or unread by ID. + * + * @param int $id The notification thread ID. + * @param string|null $lastReadAt Last point that notifications were checked (optional). + * @param bool|null $all Mark all notifications on this repo (optional). + * @param array|null $statusTypes Mark notifications with the provided status types (optional). + * @param string|null $toStatus Status to mark notifications as (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function mark( + int $id, + ?string $lastReadAt = null, + ?bool $all = null, + ?array $statusTypes = null, + ?string $toStatus = null + ): ?object + { + // Build the request path. + $path = "/notifications/threads/{$id}"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($lastReadAt !== null) + { + $uri->setVar('last_read_at', $lastReadAt); + } + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($toStatus !== null) + { + $uri->setVar('to-status', $toStatus); + } + + // Send the put request. + return $this->response->get( + $this->http->put($uri, ''), 205 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization.php new file mode 100644 index 000000000..0e7255cea --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization.php @@ -0,0 +1,209 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization + * + * @since 3.2.0 + */ +class Organization extends Api +{ + /** + * Create an organization. + * + * @param string $login Required. The organization's username. + * @param string $fullName Required. The full name of the organization. + * @param string $email Required. The email of the organization. + * @param string $description Optional. The description of the organization. + * @param bool $repoAdmin Optional. Whether the user has repository admin access. + * @param bool $teamAdmin Optional. Whether the user has team admin access. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $login, + string $fullName, + string $email, + string $description = '', + bool $repoAdmin = false, + bool $teamAdmin = false + ): ?object + { + // Set the lines data + $data = new \stdClass(); + $data->username = $login; + $data->full_name = $fullName; + $data->email = $email; + $data->description = $description; + $data->repo_admin_change_team_access = $repoAdmin; + $data->team_admin_change_team_access = $teamAdmin; + + // Build the request path. + $path = '/orgs'; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get an organization. + * + * @param string $org The organization name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $org): ?object + { + // Build the request path. + $path = "/orgs/{$org}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get a list of organizations. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/orgs'; + + // Get the URI and set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete an organization. + * + * @param string $org The organization name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $org): string + { + // Build the request path. + $path = "/orgs/{$org}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit an organization. + * + * @param string $org The organization name. + * @param string $fullName Optional. The full name of the organization. + * @param string $location Optional. The location of the organization. + * @param string $description Optional. The description of the organization. + * @param bool $repoAdmin Optional. Whether the user has repository admin access. + * @param string $visibility Optional. The visibility of the organization (public, limited, or private). + * @param string $website Optional. The website of the organization. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $org, + ?string $fullName = null, + ?string $email = null, + ?string $location = null, + ?string $description = null, + ?bool $repoAdmin = null, + ?string $visibility = null, + ?string $website = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + if ($fullName !== null) + { + $data->full_name = $fullName; + } + + if ($location !== null) + { + $data->location = $location; + } + + if ($description !== null) + { + $data->description = $description; + } + + if ($repoAdmin !== null) + { + $data->repo_admin_change_team_access = $repoAdmin; + } + + if ($visibility !== null) + { + $data->visibility = $visibility; + } + + if ($website !== null) + { + $data->website = $website; + } + + // Build the request path. + $path = "/orgs/{$org}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Hooks.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Hooks.php new file mode 100644 index 000000000..981c065d5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Hooks.php @@ -0,0 +1,200 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Organization Hooks + * + * @since 3.2.0 + */ +class Hooks extends Api +{ + /** + * List an organization's webhooks. + * + * @param string $orgName The organization name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $orgName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/hooks"; + + // Get the URI and set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a hook for an organization. + * + * @param string $org The organization name. + * @param string $type The type of hook (e.g. "gitea", "slack", "discord", etc.). + * @param string $url The URL of the hook. + * @param string $secret Optional. The secret for the hook. + * @param bool $events Optional. The events that trigger the hook. + * @param bool $active Optional. Whether the hook is active. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $org, + string $type, + string $url, + string $secret = '', + bool $events = true, + bool $active = true + ): ?object + { + // Set the lines data + $data = new \stdClass(); + $data->type = $type; + $data->config = new \stdClass(); + $data->config->url = $url; + $data->config->secret = $secret; + $data->events = []; + $data->active = $active; + + // Build the request path. + $path = "/orgs/{$org}/hooks"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a hook for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the hook. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $org, int $id): ?object + { + // Build the request path. + $path = "/orgs/{$org}/hooks/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a hook for an organization. + * + * @param string $org The organization name. + * @param int $id The hook ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $org, int $id): string + { + // Build the request path. + $path = "/orgs/{$org}/hooks/{$id}"; + + // Send the DELETE request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a hook for an organization. + * + * @param string $orgName The organization name. + * @param int $hookId The ID of the hook. + * @param bool|null $active Optional. Whether the hook is active. + * @param string|null $branchFilter Optional. Branch filter for the hook. + * @param array|null $config Optional. Configuration for the hook. + * @param array|null $events Optional. Events for the hook. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $orgName, + int $hookId, + ?bool $active = null, + ?string $branchFilter = null, + ?array $config = null, + ?array $events = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + if ($active !== null) + { + $data->active = $active; + } + + if ($branchFilter !== null) + { + $data->branch_filter = $branchFilter; + } + + if ($config !== null) + { + $data->config = (object) $config; + } + + if ($events !== null) + { + $data->events = $events; + } + + // Build the request path. + $path = "/orgs/{$orgName}/hooks/{$hookId}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Labels.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Labels.php new file mode 100644 index 000000000..0836501aa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Labels.php @@ -0,0 +1,183 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Labels + * + * @since 3.2.0 + */ +class Labels extends Api +{ + /** + * List an organization's labels. + * + * @param string $orgName The organization name. + * @param int $pageNum Page number of results to return (1-based). + * @param int $pageSize Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $orgName, + int $pageNum = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/labels"; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $pageNum); + $url->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Create a label for an organization. + * + * @param string $org The organization name. + * @param string $name The name of the label. + * @param string $color The color of the label. + * @param string $description Optional. The description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $org, + string $name, + string $color, + string $description = '' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + $data->name = $name; + $data->color = $color; + $data->description = $description; + + // Build the request path. + $path = "/orgs/{$org}/labels"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a single label for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $org, int $id): ?object + { + // Build the request path. + $path = "/orgs/{$org}/labels/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a label for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the label. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $org, int $id): string + { + // Build the request path. + $path = "/orgs/{$org}/labels/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a label for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the label. + * @param string $name Optional. The name of the label. + * @param string $color Optional. The color of the label. + * @param string $description Optional. The description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $org, + int $id, + string $name = '', + string $color = '', + string $description = '' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + if ($name) { + $data->name = $name; + } + + if ($color) { + $data->color = $color; + } + + if ($description) { + $data->description = $description; + } + + // Build the request path. + $path = "/orgs/{$org}/labels/{$id}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Members.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Members.php new file mode 100644 index 000000000..97bf82bd8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Members.php @@ -0,0 +1,100 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Members + * + * @since 3.2.0 + */ +class Members extends Api +{ + /** + * Get a list of members of an organization. + * + * @param string $orgName The organization name. + * @param int $page The page number. + * @param int $limit The number of members per page. + * + * @return array|null The organization members. + * @since 3.2.0 + */ + public function list( + string $orgName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/members"; + + // Get the URI and set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if a user is a member of an organization. + * + * @param string $org The organization name. + * @param string $username The username. + * + * @return string Whether the user is a member of the organization. + * @since 3.2.0 + */ + public function check(string $org, string $username): string + { + // Build the request path. + $path = "/orgs/{$org}/members/{$username}"; + + // Send the request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Remove a member from an organization. + * + * @param string $org The organization name. + * @param string $username The username of the user to remove. + * + * @return string Whether the user was successfully removed from the organization. + * @since 3.2.0 + */ + public function remove(string $org, string $username): string + { + // Build the request path. + $path = "/orgs/{$org}/members/{$username}"; + + // Send the request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/PublicMembers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/PublicMembers.php new file mode 100644 index 000000000..c82853249 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/PublicMembers.php @@ -0,0 +1,119 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Public Members + * + * @since 3.2.0 + */ +class PublicMembers extends Api +{ + /** + * List an organization's public members. + * + * @param string $orgName The organization name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $orgName, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/public_members"; + + // Configure the request URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + + /** + * Check if a user is a public member of an organization. + * + * @param string $org The organization name. + * @param string $username The user's username. + * + * @return string|null + * @since 3.2.0 + **/ + public function check(string $org, string $username): ?string + { + // Build the request path. + $path = "/orgs/{$org}/public_members/{$username}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204 + ); + } + + /** + * Publicize a user's membership. + * + * @param string $org The organization name. + * @param string $username The user's username. + * + * @return string|null + * @since 3.2.0 + **/ + public function publicize(string $org, string $username): ?string + { + // Build the request path. + $path = "/orgs/{$org}/public_members/{$username}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204 + ); + } + + /** + * Conceal a user's membership. + * + * @param string $org The organization name. + * @param string $username The user's username. + * + * @return string + * @since 3.2.0 + **/ + public function conceal(string $org, string $username): string + { + // Build the request path. + $path = "/orgs/{$org}/public_members/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Repository.php new file mode 100644 index 000000000..18c53840e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Repository.php @@ -0,0 +1,145 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * List an organization's repos. + * + * @param string $org The organization name. + * @param int $pageNumber The page number. + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $org, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$org}/repos"; + + // Configure the request URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a repository in an organization. + * + * @param string $org The organization name. + * @param string $repoName The name of the repository. + * @param string|null $description The description of the repository (optional). + * @param bool|null $autoInit Whether the repository should be auto-initialized (optional). + * @param string|null $defaultBranch Default branch of the repository (optional). + * @param string|null $gitignores Gitignores to use (optional). + * @param string|null $issueLabels Label-set to use (optional). + * @param string|null $license License to use (optional). + * @param bool|null $private Whether the repository is private (optional). + * @param string|null $readme Readme of the repository to create (optional). + * @param bool|null $template Whether the repository is a template (optional). + * @param string|null $trustModel Trust model of the repository (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $org, + string $repoName, + ?string $description = null, + ?bool $autoInit = null, + ?string $defaultBranch = null, + ?string $gitignores = null, + ?string $issueLabels = null, + ?string $license = null, + ?bool $private = null, + ?string $readme = null, + ?bool $template = null, + ?string $trustModel = null + ): ?object + { + // Build the request path. + $path = "/orgs/{$org}/repos"; + + // Set the repository data. + $data = new \stdClass(); + $data->name = $repoName; + if ($description !== null) + { + $data->description = $description; + } + if ($autoInit !== null) + { + $data->auto_init = $autoInit; + } + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + if ($gitignores !== null) + { + $data->gitignores = $gitignores; + } + if ($issueLabels !== null) + { + $data->issue_labels = $issueLabels; + } + if ($license !== null) + { + $data->license = $license; + } + if ($private !== null) + { + $data->private = $private; + } + if ($readme !== null) + { + $data->readme = $readme; + } + if ($template !== null) + { + $data->template = $template; + } + if ($trustModel !== null) + { + $data->trust_model = $trustModel; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams.php new file mode 100644 index 000000000..46a27b078 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams.php @@ -0,0 +1,274 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Teams + * + * @since 3.2.0 + */ +class Teams extends Api +{ + /** + * List an organization's teams. + * + * @param string $organization The organization name. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $organization, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$organization}/teams"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a team. + * + * @param int $id The team ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/teams/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create a team. + * + * @param string $organization The organization name. + * @param string $name The name of the team. + * @param string $description The description of the team. + * @param array $repoNames An array of repository names for the team (optional). + * @param string $permission The team's permission level (optional). + * @param array $units Units for the team (optional). + * @param array $unitsMap Units map for the team (optional). + * @param bool $canCreateOrgRepo Can create organization repository flag (optional). + * @param bool $includesAllRepositories Includes all repositories flag (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $organization, + string $name, + string $description, + array $repoNames = [], + string $permission = 'read', + array $units = [], + array $unitsMap = [], + bool $canCreateOrgRepo = null, + bool $includesAllRepositories = null + ): ?object + { + // Build the request path. + $path = "/orgs/{$organization}/teams"; + + // Set the team data. + $data = new \stdClass(); + $data->name = $name; + $data->description = $description; + $data->permission = $permission; + + if (!empty($repoNames)) + { + $data->repo_names = $repoNames; + } + + if (!empty($units)) + { + $data->units = $units; + } + + if (!empty($unitsMap)) + { + $data->units_map = (object)$unitsMap; + } + + if ($canCreateOrgRepo !== null) + { + $data->can_create_org_repo = $canCreateOrgRepo; + } + + if ($includesAllRepositories !== null) + { + $data->includes_all_repositories = $includesAllRepositories; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Search for teams within an organization. + * + * @param string $organization The organization name. + * @param string $keywords The search keywords. + * @param bool $includeDesc Include search within team description (defaults to true). + * @param int $page The page number. + * @param int $limit The number of results per page. + * + * @return object|null + * @since 3.2.0 + **/ + public function search( + string $organization, + string $keywords, + bool $includeDesc = true, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = "/orgs/{$organization}/teams/search"; + + // Configure the request URI. + $uri = $this->uri->get($path); + $uri->setVar('q', $keywords); + $uri->setVar('include_desc', $includeDesc); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a team. + * + * @param int $id The team ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(int $id): string + { + // Build the request path. + $path = "/teams/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a team. + * + * @param int $teamId The team ID. + * @param string|null $teamName The team name (optional). + * @param string|null $teamDescription The team description (optional). + * @param string|null $teamPermission The team's permission level (optional). + * @param bool|null $canCreateOrgRepo Can team create organization repositories (optional). + * @param bool|null $includesAllRepositories Include all repositories (optional). + * @param array|null $units List of units (optional). + * @param array|null $unitsMap Units map (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + int $teamId, + ?string $teamName = null, + ?string $teamDescription = null, + ?string $teamPermission = null, + ?bool $canCreateOrgRepo = null, + ?bool $includesAllRepositories = null, + ?array $units = null, + ?array $unitsMap = null + ): ?object + { + // Build the request path. + $path = "/teams/{$teamId}"; + + // Set the team data. + $data = new \stdClass(); + if ($teamName !== null) + { + $data->name = $teamName; + } + if ($teamDescription !== null) + { + $data->description = $teamDescription; + } + if ($teamPermission !== null) + { + $data->permission = $teamPermission; + } + if ($canCreateOrgRepo !== null) + { + $data->can_create_org_repo = $canCreateOrgRepo; + } + if ($includesAllRepositories !== null) + { + $data->includes_all_repositories = $includesAllRepositories; + } + if ($units !== null) + { + $data->units = $units; + } + if ($unitsMap !== null) + { + $data->units_map = $unitsMap; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Members.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Members.php new file mode 100644 index 000000000..89e914518 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Members.php @@ -0,0 +1,124 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization\Teams; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Teams Members + * + * @since 3.2.0 + */ +class Members extends Api +{ + /** + * List a team's members. + * + * @param int $teamId The team ID. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $teamId, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/teams/{$teamId}/members"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List a particular member of the team. + * + * @param int $id The team ID. + * @param string $username The user's username. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id, string $username): ?object + { + // Build the request path. + $path = "/teams/{$id}/members/{$username}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add a team member. + * + * @param int $id The team ID. + * @param string $username The user's username. + * + * @return string + * @since 3.2.0 + **/ + public function add(int $id, string $username): string + { + // Build the request path. + $path = "/teams/{$id}/members/{$username}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Remove a team member. + * + * @param int $id The team ID. + * @param string $username The user's username. + * + * @return string + * @since 3.2.0 + **/ + public function remove(int $id, string $username): string + { + // Build the request path. + $path = "/teams/{$id}/members/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Repository.php new file mode 100644 index 000000000..f485c0972 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Repository.php @@ -0,0 +1,135 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization\Teams; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Teams Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * List a team's repos. + * + * @param int $teamId The team ID. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $teamId, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/teams/{$teamId}/repos"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List a particular repo of the team. + * + * @param int $teamId The team ID. + * @param string $organization The organization name. + * @param string $repository The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + int $teamId, + string $organization, + string $repository + ): ?object + { + // Build the request path. + $path = "/teams/{$teamId}/repos/{$organization}/{$repository}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add a repository to a team. + * + * @param int $id The team ID. + * @param string $org The organization name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function add( + int $id, + string $org, + string $repo + ): string + { + // Build the request path. + $path = "/teams/{$id}/repos/{$org}/{$repo}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ),204, 'success' + ); + } + + /** + * Remove a repository from a team. + * + * @param int $id The team ID. + * @param string $org The organization name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function remove(int $id, string $org, string $repo): string + { + // Build the request path. + $path = "/teams/{$id}/repos/{$org}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/User.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/User.php new file mode 100644 index 000000000..b59fe9b6f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/User.php @@ -0,0 +1,111 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization User + * + * @since 3.2.0 + */ +class User extends Api +{ + /** + * List the current user's organizations. + * + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/user/orgs"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List a user's organizations. + * + * @param string $username The user's username. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $username, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$username}/orgs"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get user permissions in an organization. + * + * @param string $username The user's username. + * @param string $org The organization name. + * + * @return object|null + * @since 3.2.0 + **/ + public function permissions(string $username, string $org): ?object + { + // Build the request path. + $path = "/users/{$username}/orgs/{$org}/permissions"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package.php new file mode 100644 index 000000000..8fb1ac22a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package.php @@ -0,0 +1,84 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Package + * + * @since 3.2.0 + */ +class Package extends Api +{ + /** + * Gets a package. + * + * @param string $owner The owner of the package. + * @param string $type The type of the package. + * @param string $name The name of the package. + * @param string $version The version of the package. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $type, + string $name, + string $version + ): ?object + { + // Build the request path. + $path = "/packages/{$owner}/{$type}/{$name}/{$version}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a package. + * + * @param string $owner The owner of the package. + * @param string $type The type of the package. + * @param string $name The name of the package. + * @param string $version The version of the package. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $type, + string $name, + string $version + ): string + { + // Build the request path. + $path = "/packages/{$owner}/{$type}/{$name}/{$version}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Files.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Files.php new file mode 100644 index 000000000..c3851c070 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Files.php @@ -0,0 +1,55 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Package; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Package Files + * + * @since 3.2.0 + */ +class Files extends Api +{ + /** + * Gets all files of a package. + * + * @param string $owner The owner of the package. + * @param string $type The type of the package. + * @param string $name The name of the package. + * @param string $version The version of the package. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $type, + string $name, + string $version + ): ?object + { + // Build the request path. + $path = "/packages/{$owner}/{$type}/{$name}/{$version}/files"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Owner.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Owner.php new file mode 100644 index 000000000..93960d12c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Owner.php @@ -0,0 +1,68 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Package; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Package Owner + * + * @since 3.2.0 + */ +class Owner extends Api +{ + /** + * Gets all packages of an owner. + * + * @param string $owner The owner of the packages. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * @param string|null $type Package type filter (optional). + * @param string|null $name Filter Name filter (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + int $page = 1, + int $limit = 10, + ?string $type = null, + ?string $nameFilter = null + ): ?array + { + // Build the request path. + $path = "/packages/{$owner}"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + if ($type !== null) + { + $uri->setVar('type', $type); + } + if ($nameFilter !== null) + { + $uri->setVar('q', $nameFilter); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository.php new file mode 100644 index 000000000..c1e71264f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository.php @@ -0,0 +1,439 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * Search for repositories. + * + * @param string $q The search query. + * @param array $options Additional search options (optional). + * @param int $page The page number (optional). + * @param int $limit The number of items per page (optional). + * @param string $sort The sort order (optional). + * @param string $order The order direction (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function search( + string $q, + array $options = [], + int $page = 1, + int $limit = 10, + string $sort = 'alpha', + string $order = 'asc' + ): ?object + { + // Build the request path. + $path = '/repos/search'; + + // Create the URI object and set URL values. + $uri = $this->uri->get($path); + $uri->setVar('q', $q); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + $uri->setVar('sort', $sort); + $uri->setVar('order', $order); + + foreach ($options as $key => $val) + { + $uri->setVar($key, $val); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get a repository by owner and repo name. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function id(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a repository's properties. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string|null $description The repository description (optional). + * @param string|null $website The repository website (optional). + * @param bool|null $private Set the repository to private (optional). + * @param bool|null $hasIssues Set the repository to have issues (optional). + * @param bool|null $hasWiki Set the repository to have a wiki (optional). + * @param bool|null $hasProjects Set the repository to have projects (optional). + * @param bool|null $allowManualMerge Allow manual merge of pull requests (optional). + * @param bool|null $allowMergeCommits Allow merge commits for pull requests (optional). + * @param bool|null $allowRebase Allow rebase-merging pull requests (optional). + * @param bool|null $allowRebaseExplicit Allow rebase with explicit merge commits (optional). + * @param bool|null $allowRebaseUpdate Allow updating pull request branch by rebase (optional). + * @param bool|null $allowSquashMerge Allow squash-merging pull requests (optional). + * @param bool|null $archived + * @param bool|null $archived Set to true to archive this repository (optional). + * @param bool|null $autodetectManualMerge Enable AutodetectManualMerge (optional). + * @param string|null $defaultBranch Sets the default branch for this repository (optional). + * @param bool|null $defaultDeleteBranchAfterMerge Set to true to delete pr branch after merge by default (optional). + * @param string|null $defaultMergeStyle Set to a merge style to be used by this repository (optional). + * @param bool|null $enablePrune Enable prune - remove obsolete remote-tracking references (optional). + * @param object|null $externalTracker External tracker settings (optional). + * @param object|null $externalWiki External wiki settings (optional). + * @param bool|null $hasPullRequests Set the repository to have pull requests (optional). + * @param bool|null $ignoreWhitespaceConflicts Ignore whitespace for conflicts (optional). + * @param object|null $internalTracker Internal tracker settings (optional). + * @param string|null $mirrorInterval Set the mirror interval time (optional). + * @param bool|null $template Set to true to make this repository a template (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + ?string $description = null, + ?string $website = null, + ?bool $private = null, + ?bool $hasIssues = null, + ?bool $hasWiki = null, + ?bool $hasProjects = null, + ?bool $allowManualMerge = null, + ?bool $allowMergeCommits = null, + ?bool $allowRebase = null, + ?bool $allowRebaseExplicit = null, + ?bool $allowRebaseUpdate = null, + ?bool $allowSquashMerge = null, + ?bool $archived = null, + ?bool $autodetectManualMerge = null, + ?string $defaultBranch = null, + ?bool $defaultDeleteBranchAfterMerge = null, + ?string $defaultMergeStyle = null, + ?bool $enablePrune = null, + ?object $externalTracker = null, + ?object $externalWiki = null, + ?bool $hasPullRequests = null, + ?bool $ignoreWhitespaceConflicts = null, + ?object $internalTracker = null, + ?string $mirrorInterval = null, + ?bool $template = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Set the repository properties to update. + $data = new \stdClass(); + + if ($description !== null) + { + $data->description = $description; + } + + if ($website !== null) + { + $data->website = $website; + } + + if ($private !== null) + { + $data->private = $private; + } + + if ($hasIssues !== null) + { + $data->has_issues = $hasIssues; + } + + if ($hasWiki !== null) + { + $data->has_wiki = $hasWiki; + } + + if ($hasProjects !== null) + { + $data->has_projects = $hasProjects; + } + + // Add the additional properties to update. + if ($allowManualMerge !== null) + { + $data->allow_manual_merge = $allowManualMerge; + } + + if ($allowMergeCommits !== null) + { + $data->allow_merge_commits = $allowMergeCommits; + } + + if ($allowRebase !== null) + { + $data->allow_rebase = $allowRebase; + } + + if ($allowRebaseExplicit !== null) + { + $data->allow_rebase_explicit = $allowRebaseExplicit; + } + + if ($allowRebaseUpdate !== null) + { + $data->allow_rebase_update = $allowRebaseUpdate; + } + + if ($allowSquashMerge !== null) + { + $data->allow_squash_merge = $allowSquashMerge; + } + + if ($archived !== null) + { + $data->archived = $archived; + } + + if ($autodetectManualMerge !== null) + { + $data->autodetect_manual_merge = $autodetectManualMerge; + } + + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + + if ($defaultDeleteBranchAfterMerge !== null) + { + $data->default_delete_branch_after_merge = $defaultDeleteBranchAfterMerge; + } + + if ($defaultMergeStyle !== + null) + { + $data->default_merge_style = $defaultMergeStyle; + } + + if ($enablePrune !== null) + { + $data->enable_prune = $enablePrune; + } + + if ($externalTracker !== null) + { + $data->external_tracker = $externalTracker; + } + + if ($externalWiki !== null) + { + $data->external_wiki = $externalWiki; + } + + if ($hasPullRequests !== null) + { + $data->has_pull_requests = $hasPullRequests; + } + + if ($ignoreWhitespaceConflicts !== null) + { + $data->ignore_whitespace_conflicts = $ignoreWhitespaceConflicts; + } + + if ($internalTracker !== null) + { + $data->internal_tracker = $internalTracker; + } + + if ($mirrorInterval !== null) + { + $data->mirror_interval = $mirrorInterval; + } + + if ($template !== null) + { + $data->template = $template; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Create a repository. + * + * @param string $name The name of the new repository. + * @param string|null $description Optional. The description of the new repository. + * @param bool|null $private Optional. Set to true if the new repository should be private. + * @param bool|null $autoInit Optional. Set to true to initialize the repository with a README. + * @param string|null $defaultBranch Optional. Default branch of the repository (used when initializes and in template). + * @param string|null $gitignores Optional. The desired .gitignore templates to apply. + * @param string|null $issueLabels Optional. Label-Set to use. + * @param string|null $license Optional. The desired license for the repository. + * @param string|null $readme Optional. Readme of the repository to create. + * @param bool|null $template Optional. Set to true if the repository is a template. + * @param string|null $trustModel Optional. TrustModel of the repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $name, + ?string $description = null, + ?bool $private = null, + ?bool $autoInit = null, + ?string $defaultBranch = null, + ?string $gitignores = null, + ?string $issueLabels = null, + ?string $license = null, + ?string $readme = null, + ?bool $template = null, + ?string $trustModel = null + ): ?object { + // Build the request path. + $path = "/user/repos"; + + // Set the repo data. + $data = new \stdClass(); + $data->name = $name; + + if ($description !== null) + { + $data->description = $description; + } + + if ($private !== null) + { + $data->private = $private; + } + + if ($autoInit !== null) + { + $data->auto_init = $autoInit; + } + + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + + if ($gitignores !== null) + { + $data->gitignores = $gitignores; + } + + if ($issueLabels !== null) + { + $data->issue_labels = $issueLabels; + } + + if ($license !== null) + { + $data->license = $license; + } + + if ($readme !== null) + { + $data->readme = $readme; + } + + if ($template !== null) + { + $data->template = $template; + } + + if ($trustModel !== null) + { + $data->trust_model = $trustModel; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Archive.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Archive.php new file mode 100644 index 000000000..8cc349973 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Archive.php @@ -0,0 +1,58 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Archive + * + * @since 3.2.0 + */ +class Archive extends Api +{ + /** + * Get an archive of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $archive The archive format, e.g., "zip" or "tar.gz". + * + * @return string + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $archive + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/archive/{$archive}"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('archive', $archive); + + // Send the get request. + return $this->response->get( + $this->http->get($uri), 200, 'success' + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Assignees.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Assignees.php new file mode 100644 index 000000000..f6c8c751f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Assignees.php @@ -0,0 +1,51 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Assignees + * + * @since 3.2.0 + */ +class Assignees extends Api +{ + /** + * Return all users that have write access and can be assigned to issues. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/assignees"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Attachments.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Attachments.php new file mode 100644 index 000000000..121da5d78 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Attachments.php @@ -0,0 +1,196 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Attachments + * + * @since 3.2.0 + */ +class Attachments extends Api +{ + /** + * List release's attachments. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + int $releaseId + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}/assets"; + + // Retrieve the URI object with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a release attachment. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * @param string $attachmentFile The attachment file content. + * @param string $attachmentName The attachment file name. + * @param string $contentType The attachment content type. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $ownerName, + string $repoName, + int $releaseId, + string $attachmentFile, + string $attachmentName, + string $contentType + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}/assets"; + + // Retrieve the URI object with the path. + $uri = $this->uri->get($path); + + // Add the attachment name as a query parameter. + $uri->setVar('name', $attachmentName); + + // Set the request headers. + $headers = [ + "Content-Type: {$contentType}", + "Content-Disposition: attachment; filename={$attachmentName}" + ]; + + // Send the post request. + return $this->response->get( + $this->http->post( + $uri, $attachmentFile, $headers + ), 201 + ); + } + + /** + * Get a release attachment. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The release ID. + * @param int $attachmentId The attachment ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $id, + int $attachmentId + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/releases/{$id}/assets/{$attachmentId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a release attachment. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The release ID. + * @param int $attachmentId The attachment ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + int $id, + int $attachmentId + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/releases/{$id}/assets/{$attachmentId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a release attachment. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The release ID. + * @param int $attachmentId The attachment ID. + * @param string|null $name The new name of the attachment (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + int $id, + int $attachmentId, + ?string $name = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/releases/{$id}/assets/{$attachmentId}"; + + // Set the attachment data + $data = new \stdClass(); + + if ($name !== null) + { + $data->name = $name; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch.php new file mode 100644 index 000000000..0936bbe3c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch.php @@ -0,0 +1,148 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Branch + * + * @since 3.2.0 + */ +class Branch extends Api +{ + /** + * List a repository's branches. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a branch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branch_name The name of the new branch. + * @param string $old_branch The name of the existing branch from which to create the new branch. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $branch_name, + string $old_branch + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches"; + + // Set the branch data. + $data = new \stdClass(); + $data->branch_name = $branch_name; + $data->old_branch = $old_branch; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Retrieve a specific branch from a repository, including its effective branch protection. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branch The branch name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $branch): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches/{$branch}"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('branch', $branch); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a specific branch from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branch The branch name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $branch + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches/{$branch}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/Protection.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/Protection.php new file mode 100644 index 000000000..946bce20a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/Protection.php @@ -0,0 +1,380 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository\Branch; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Branch Protection + * + * @since 3.2.0 + */ +class Protection extends Api +{ + /** + * List branch protections for a repository. + * + * @param string $ownerName The owner name. + * @param string $repositoryName The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $ownerName, string $repositoryName): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repositoryName}/branch_protections"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a branch protection for a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branchName The name of the branch to protect. + * @param array $approvalsWhitelistUsernames An array of usernames that can approve. + * @param array $approvalsWhitelistTeams An array of team names that can approve. + * @param bool $blockOnOfficialReviewRequests Enable/disable blocking on official review requests (optional, default false). + * @param bool $blockOnOutdatedBranch Enable/disable blocking on outdated branch (optional, default false). + * @param bool $blockOnRejectedReviews Enable/disable blocking on rejected reviews (optional, default false). + * @param bool $dismissStaleApprovals Enable/disable dismissing stale approvals (optional, default false). + * @param bool $enableApprovalsWhitelist Enable/disable approvals whitelist (optional, default false). + * @param bool $enableMergeWhitelist Enable/disable merge whitelist (optional, default false). + * @param bool $enablePush Enable/disable push (optional, default true). + * @param bool $enablePushWhitelist Enable/disable push whitelist (optional, default false). + * @param bool $enableStatusCheck Enable/disable status check (optional, default false). + * @param array $mergeWhitelistUsernames An array of usernames that can merge (optional). + * @param array $mergeWhitelistTeams An array of team names that can merge (optional). + * @param string $protectedFilePatterns Protected file patterns (optional). + * @param bool $pushWhitelistDeployKeys Enable/disable push whitelist deploy keys (optional, default false). + * @param array $pushWhitelistUsernames An array of usernames that can push (optional). + * @param array $pushWhitelistTeams An array of team names that can push (optional). + * @param bool $requireSignedCommits Enable/disable requiring signed commits (optional, default false). + * @param int $requiredApprovals Number of required approvals (optional, default 0). + * @param array $statusCheckContexts An array of status check contexts (optional). + * @param string $unprotectedFilePatterns Unprotected file patterns (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $branchName, + array $approvalsWhitelistUsernames, + array $approvalsWhitelistTeams, + bool $blockOnOfficialReviewRequests = false, + bool $blockOnOutdatedBranch = false, + bool $blockOnRejectedReviews = false, + bool $dismissStaleApprovals = false, + bool $enableApprovalsWhitelist = false, + bool $enableMergeWhitelist = false, + bool $enablePush = true, + bool $enablePushWhitelist = false, + bool $enableStatusCheck = false, + array $mergeWhitelistUsernames = [], + array $mergeWhitelistTeams = [], + string $protectedFilePatterns = '', + bool $pushWhitelistDeployKeys = false, + array $pushWhitelistUsernames = [], + array $pushWhitelistTeams = [], + bool $requireSignedCommits = false, + int $requiredApprovals = 0, + array $statusCheckContexts = [], + string $unprotectedFilePatterns = '' + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branch_protections"; + + // Set the branch protection data. + $data = new \stdClass(); + $data->branch_name = $branchName; + $data->approvals_whitelist_usernames = $approvalsWhitelistUsernames; + $data->approvals_whitelist_teams = $approvalsWhitelistTeams; + $data->block_on_official_review_requests = $blockOnOfficialReviewRequests; + $data->block_on_outdated_branch = $blockOnOutdatedBranch; + $data->block_on_rejected_reviews = $blockOnRejectedReviews; + $data->dismiss_stale_approvals = $dismissStaleApprovals; + $data->enable_approvals_whitelist = $enableApprovalsWhitelist; + $data->enable_merge_whitelist = $enableMergeWhitelist; + $data->enable_push = $enablePush; + $data->enable_push_whitelist = $enablePushWhitelist; + $data->enable_status_check = $enableStatusCheck; + $data->merge_whitelist_usernames = $mergeWhitelistUsernames; + $data->merge_whitelist_teams = $mergeWhitelistTeams; + $data->protected_file_patterns = $protectedFilePatterns; + $data->push_whitelist_deploy_keys = $pushWhitelistDeployKeys; + $data->push_whitelist_usernames = $pushWhitelistUsernames; + $data->push_whitelist_teams = $pushWhitelistTeams; + $data->require_signed_commits = $requireSignedCommits; + $data->required_approvals = $requiredApprovals; + $data->status_check_contexts = $statusCheckContexts; + $data->unprotected_file_patterns = $unprotectedFilePatterns; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a specific branch protection for the repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branchName The branch protection name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $branchName + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branch_protections/{$branchName}"; + + // Get the URI object with the given path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a specific branch protection for the repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $branchName The branch protection name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + string $branchName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/branch_protections/{$branchName}"; + + // Set the required variables in the URI. + $this->uri->setVar('owner', $ownerName); + $this->uri->setVar('repo', $repoName); + $this->uri->setVar('name', $branchName); + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a branch protection for a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $name The branch protection name. + * @param array|null $approvalsWhitelistTeams An array of team names that are allowed to approve (optional). + * @param array|null $approvalsWhitelistUsernames An array of usernames that are allowed to approve (optional). + * @param bool|null $blockOnOfficialReviewRequests Block when official review requests are pending (optional). + * @param bool|null $blockOnOutdatedBranch Block when the branch is outdated (optional). + * @param bool|null $blockOnRejectedReviews Block when reviews are rejected (optional). + * @param bool|null $dismissStaleApprovals Dismiss stale approvals when new commits are pushed (optional). + * @param bool|null $enableApprovalsWhitelist Enable/disable approvals whitelist (optional). + * @param bool|null $enableMergeWhitelist Enable/disable merge whitelist (optional). + * @param bool|null $enablePush Enable/disable push (optional). + * @param bool|null $enablePushWhitelist Enable/disable push whitelist (optional). + * @param bool|null $enableStatusCheck Enable/disable status check (optional). + * @param array|null $mergeWhitelistTeams An array of team names that are allowed to merge (optional). + * @param array|null $mergeWhitelistUsernames An array of usernames that are allowed to merge (optional). + * @param string|null $protectedFilePatterns A string pattern for protected files (optional). + * @param bool|null $pushWhitelistDeployKeys Enable/disable push whitelist for deploy keys (optional). + * @param array|null $pushWhitelistTeams An array of team names that are allowed to push (optional). + * @param array|null $pushWhitelistUsernames An array of usernames that are allowed to push (optional). + * @param bool|null $requireSignedCommits Require signed commits (optional). + * @param int|null $requiredApprovals Number of required approvals (optional). + * @param array|null $statusCheckContexts An array of status check contexts (optional). + * @param string|null $unprotectedFilePatterns A string pattern for unprotected files (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + string $name, + ?array $approvalsWhitelistTeams = null, + ?array $approvalsWhitelistUsernames = null, + ?bool $blockOnOfficialReviewRequests = null, + ?bool $blockOnOutdatedBranch = null, + ?bool $blockOnRejectedReviews = null, + ?bool $dismissStaleApprovals = null, + ?bool $enableApprovalsWhitelist = null, + ?bool $enableMergeWhitelist = null, + ?bool $enablePush = null, + ?bool $enablePushWhitelist = null, + ?bool $enableStatusCheck = null, + ?array $mergeWhitelistTeams = null, + ?array $mergeWhitelistUsernames = null, + ?string $protectedFilePatterns = null, + ?bool $pushWhitelistDeployKeys = null, + ?array $pushWhitelistTeams = null, + ?array $pushWhitelistUsernames = null, + ?bool $requireSignedCommits = null, + ?int $requiredApprovals = null, + ?array $statusCheckContexts = null, + ?string $unprotectedFilePatterns = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branch_protections/{$name}"; + + // Set the branch protection data. + $data = new \stdClass(); + + if ($approvalsWhitelistTeams !== null) + { + $data->approvals_whitelist_teams = $approvalsWhitelistTeams; + } + + if ($approvalsWhitelistUsernames !== null) + { + $data->approvals_whitelist_usernames = $approvalsWhitelistUsernames; + } + + if ($blockOnOfficialReviewRequests !== null) + { + $data->block_on_official_review_requests = $blockOnOfficialReviewRequests; + } + + if ($blockOnOutdatedBranch !== null) + { + $data->block_on_outdated_branch = $blockOnOutdatedBranch; + } + + if ($blockOnRejectedReviews !== null) + { + $data->block_on_rejected_reviews = $blockOnRejectedReviews; + } + + if ($dismissStaleApprovals !== null) + { + $data->dismiss_stale_approvals = $dismissStaleApprovals; + } + + if ($enableApprovalsWhitelist !== null) + { + $data->enable_approvals_whitelist = $enableApprovalsWhitelist; + } + + if ($enableMergeWhitelist !== null) + { + $data->enable_merge_whitelist = $enableMergeWhitelist; + } + + if ($enablePush !== null) + { + $data->enable_push = $enablePush; + } + + if ($enablePushWhitelist !== null) + { + $data->enable_push_whitelist = $enablePushWhitelist; + } + + if ($enableStatusCheck !== null) + { + $data->enable_status_check = $enableStatusCheck; + } + + if ($mergeWhitelistTeams !== null) + { + $data->merge_whitelist_teams = $mergeWhitelistTeams; + } + + if ($mergeWhitelistUsernames !== null) + { + $data->merge_whitelist_usernames = $mergeWhitelistUsernames; + } + + if ($protectedFilePatterns !== null) + { + $data->protected_file_patterns = $protectedFilePatterns; + } + + if ($pushWhitelistDeployKeys !== null) + { + $data->push_whitelist_deploy_keys = $pushWhitelistDeployKeys; + } + + if ($pushWhitelistTeams !== null) + { + $data->push_whitelist_teams = $pushWhitelistTeams; + } + + if ($pushWhitelistUsernames !== null) + { + $data->push_whitelist_usernames = $pushWhitelistUsernames; + } + + if ($requireSignedCommits !== null) + { + $data->require_signed_commits = $requireSignedCommits; + } + + if ($requiredApprovals !== null) + { + $data->required_approvals = $requiredApprovals; + } + + if ($statusCheckContexts !== null) + { + $data->status_check_contexts = $statusCheckContexts; + } + + if ($unprotectedFilePatterns !== null) + { + $data->unprotected_file_patterns = $unprotectedFilePatterns; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Collaborator.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Collaborator.php new file mode 100644 index 000000000..38ee5127f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Collaborator.php @@ -0,0 +1,175 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Collaborator + * + * @since 3.2.0 + */ +class Collaborator extends Api +{ + /** + * List a repository's collaborators. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Set the page and limit variables. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if a user is a collaborator of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * + * @return string + * @since 3.2.0 + **/ + public function check( + string $owner, + string $repo, + string $collaborator + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri), 204, 'success' + ); + } + + /** + * Add a collaborator to a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * @param string $permission The permission level for the collaborator (optional). + * + * @return string + * @since 3.2.0 + **/ + public function add( + string $owner, + string $repo, + string $collaborator, + string $permission = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Prepare the request body. + $body = new stdClass(); + if ($permission !== null) { + $body->permission = $permission; + } + $bodyJson = json_encode($body); + + // Send the put request. + return $this->response->get( + $this->http->put($uri, $bodyJson), 204, 'success' + ); + } + + /** + * Delete a collaborator from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $collaborator + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Get repository permissions for a user. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * + * @return object|null + * @since 3.2.0 + **/ + public function permission( + string $owner, + string $repo, + string $collaborator + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}/permission"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Commits.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Commits.php new file mode 100644 index 000000000..d8142c230 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Commits.php @@ -0,0 +1,225 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Commit + * + * @since 3.2.0 + */ +class Commits extends Api +{ + /** + * Get a list of all commits from a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string|null $sha SHA or branch to start listing commits from (usually 'master'). + * @param string|null $path Filepath of a file/dir. + * @param bool|null $stat Include diff stats for every commit (disable for speedup, default 'true'). + * @param int|null $page Page number of results to return (1-based). + * @param int|null $limit Page size of results (ignored if used with 'path'). + * + * @return array|null + * @since 3.2.0 + */ + public function getList( + string $owner, + string $repo, + ?string $sha = null, + ?string $path = null, + ?bool $stat = true, + ?int $page = 1, + ?int $limit = 10 + ): ?object + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/commits"; + + // Set query parameters. + $uri = $this->uri->get($uriPath); + + if ($sha !== null) + { + $uri->setVar('sha', $sha); + } + + if ($path !== null) + { + $uri->setVar('path', $path); + } + + if ($stat !== null) + { + $uri->setVar('stat', $stat ? 'true' : 'false'); + } + + if ($page !== null) + { + $uri->setVar('page', $page); + } + + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a single commit from a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string $sha A git ref or commit sha. + * + * @return object|null + * @since 3.2.0 + */ + public function getCommit(string $owner, string $repo, string $sha): ?object + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/git/commits/{$sha}"; + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($uriPath) + ) + ); + } + + /** + * Get a commit's combined status, by branch/tag/commit reference. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $ref The branch, tag, or commit reference. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function status( + string $owner, + string $repo, + string $ref, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/commits/{$ref}/status"; + + // Set up the URI with the required parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a commit's statuses, by branch/tag/commit reference. + * + * @param string $owner The owner of the repository. + * @param string $repo The name of the repository. + * @param string $ref The branch, tag, or commit reference. + * @param string $sort The type of sort. Available values: oldest, recentupdate, leastupdate, leastindex, highestindex. + * @param string $state The type of state. Available values: pending, success, error, failure, warning. + * @param int $page The page number of results to return (1-based). Default value: 1. + * @param int $limit The page size of results. Default value: 10. + * + * @return array|null + * @since 3.2.0 + */ + public function statuses( + string $owner, + string $repo, + string $ref, + string $sort = null, + string $state = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/commits/{$ref}/statuses"; + + // Add query parameters to the URI. + $uri = $this->uri->get($path); + + if ($sort !== null) + { + $uri->setVar('sort', $sort); + } + + if ($state !== null) + { + $uri->setVar('state', $state); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the GET request. + $response = $this->http->get($uri); + return $this->response->get($response); + } + + /** + * Get a commit's diff or patch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $sha The SHA hash of the commit. + * @param string $diffType The diff type, either 'diff' or 'patch'. + * + * @return string + * @since 3.2.0 + **/ + public function diff( + string $owner, + string $repo, + string $sha, + string $diffType + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/commits/{$sha}"; + + // Set the diffType as a variable in the URI. + $this->uri->setVar('diffType', $diffType); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Contents.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Contents.php new file mode 100644 index 000000000..3f2476b67 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Contents.php @@ -0,0 +1,511 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Contents + * + * @since 3.2.0 + */ +class Contents extends Api +{ + /** + * Get a file from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string|null $ref Optional. The name of the commit/branch/tag. + * Default the repository's default branch (usually master). + * + * @return mixed + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $filepath, ?string $ref = null) + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/raw/{$filepath}"; + + // Get the URI with the specified path. + $uri = $this->uri->get($path); + + // Add the ref parameter if provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get the metadata and contents (if a file) of an entry in a repository, + * or a list of entries if a directory. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file or directory path. + * @param string|null $ref Optional. The name of the commit/branch/tag. + * Default the repository's default branch (usually master). + * + * @return object|null + * @since 3.2.0 + **/ + public function metadata(string $owner, string $repo, string $filepath, ?string $ref = null): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Get the URI with the specified path. + $uri = $this->uri->get($path); + + // Add the ref parameter if provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $content The file content. + * @param string $message The commit message. + * @param string $branch The branch name. Defaults to the repository's default branch. + * @param string|null $authorName The author's name. + * @param string|null $authorEmail The author's email. + * @param string|null $committerName The committer's name. + * @param string|null $committerEmail The committer's email. + * @param bool|null $newBranch Whether to create a new branch. Defaults to false. + * @param string|null $authorDate The author's date. + * @param string|null $committerDate The committer's date. + * @param bool|null $signoff Add a Signed-off-by trailer. Defaults to null. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $filepath, + string $content, + string $message, + string $branch = 'master', + ?string $authorName = null, + ?string $authorEmail = null, + ?string $committerName = null, + ?string $committerEmail = null, + ?bool $newBranch = false, + ?string $authorDate = null, + ?string $committerDate = null, + ?bool $signoff = null + ): ?object { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Set the post data + $data = new \stdClass(); + $data->content = base64_encode($content); + $data->message = $message; + $data->branch = $branch; + + if ($authorName !== null || $authorEmail !== null) + { + $data->author = new \stdClass(); + if ($authorName !== null) + { + $data->author->name = $authorName; + } + if ($authorEmail !== null) + { + $data->author->email = $authorEmail; + } + } + + if ($committerName !== null || $committerEmail !== null) + { + $data->committer = new \stdClass(); + if ($committerName !== null) + { + $data->committer->name = $committerName; + } + if ($committerEmail !== null) + { + $data->committer->email = $committerEmail; + } + } + + if ($newBranch !== null) + { + $data->new_branch = $newBranch; + } + + if ($authorDate !== null || $committerDate !== null) + { + $data->dates = new \stdClass(); + if ($authorDate !== null) + { + $data->dates->author = $authorDate; + } + if ($committerDate !== null) + { + $data->dates->committer = $committerDate; + } + } + + if ($signoff !== null) + { + $data->signoff = $signoff; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get the metadata of all the entries of the root directory. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string|null $ref The name of the commit/branch/tag. Default the repository's default branch (usually master). + * + * @return array|null + * @since 3.2.0 + **/ + public function root(string $owner, string $repo, ?string $ref = null): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents"; + + // Get the URI with the specified path. + $uri = $this->uri->get($path); + + // Add the 'ref' parameter if it's provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get( + $uri + ) + ); + } + + /** + * Update a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $content The file content. + * @param string $message The commit message. + * @param string $sha The blob SHA of the file. + * @param string $branch The branch name. Defaults to the repository's default branch. + * @param string|null $authorName The author name. Defaults to the authenticated user. + * @param string|null $authorEmail The author email. Defaults to the authenticated user. + * @param string|null $committerName The committer name. Defaults to the authenticated user. + * @param string|null $committerEmail The committer email. Defaults to the authenticated user. + * @param string|null $authorDate The author date. + * @param string|null $committerDate The committer date. + * @param string|null $fromPath The original file path to move/rename. + * @param string|null $newBranch The new branch to create from the specified branch. + * @param bool|null $signoff Add a Signed-off-by trailer. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + string $filepath, + string $content, + string $message, + string $sha, + string $branch = 'master', + ?string $authorName = null, + ?string $authorEmail = null, + ?string $committerName = null, + ?string $committerEmail = null, + ?string $authorDate = null, + ?string $committerDate = null, + ?string $fromPath = null, + ?string $newBranch = null, + ?bool $signoff = null + ): ?object { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Set the file data. + $data = new \stdClass(); + $data->content = base64_encode($content); + $data->message = $message; + $data->branch = $branch; + $data->sha = $sha; + + if ($authorName !== null || $authorEmail !== null) + { + $data->author = new \stdClass(); + + if ($authorName !== null) + { + $data->author->name = $authorName; + } + + if ($authorEmail !== null) + { + $data->author->email = $authorEmail; + } + } + + if ($committerName !== null || $committerEmail !== null) + { + $data->committer = new \stdClass(); + + if ($committerName !== null) + { + $data->committer->name = $committerName; + } + + if ($committerEmail !== null) + { + $data->committer->email = $committerEmail; + } + } + + if ($authorDate !== null || $committerDate !== null) + { + $data->dates = new \stdClass(); + + if ($authorDate !== null) + { + $data->dates->author = $authorDate; + } + + if ($committerDate !== null) + { + $data->dates->committer = $committerDate; + } + } + + if ($fromPath !== null) + { + $data->from_path = $fromPath; + } + + if ($newBranch !== null) + { + $data->new_branch = $newBranch; + } + + if ($signoff !== null) + { + $data->signoff = $signoff; + } + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Delete a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $message The commit message. + * @param string $branch The branch name (optional). + * @param string $sha The blob SHA of the file. + * @param string $authorName The author name (optional). + * @param string $authorEmail The author email (optional). + * @param string $committerName The committer name (optional). + * @param string $committerEmail The committer email (optional). + * @param string $authorDate The author date (optional). + * @param string $committerDate The committer date (optional). + * @param string $newBranch The new branch name (optional). + * @param bool $signoff Add a Signed-off-by trailer (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $filepath, + string $message, + string $sha, + ?string $branch = null, + ?string $authorName = null, + ?string $authorEmail = null, + ?string $committerName = null, + ?string $committerEmail = null, + ?string $authorDate = null, + ?string $committerDate = null, + ?string $newBranch = null, + ?bool $signoff = null + ): ?object { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Set the file data. + $data = new \stdClass(); + $data->message = $message; + $data->sha = $sha; + + if ($branch !== null) { + $data->branch = $branch; + } + + if ($authorName !== null || $authorEmail !== null) + { + $data->author = new \stdClass(); + + if ($authorName !== null) + { + $data->author->name = $authorName; + } + + if ($authorEmail !== null) + { + $data->author->email = $authorEmail; + } + } + + if ($committerName !== null || $committerEmail !== null) + { + $data->committer = new \stdClass(); + + if ($committerName !== null) + { + $data->committer->name = $committerName; + } + + if ($committerEmail !== null) + { + $data->committer->email = $committerEmail; + } + } + + if ($authorDate !== null || $committerDate !== null) + { + $data->dates = new \stdClass(); + + if ($authorDate !== null) + { + $data->dates->author = $authorDate; + } + + if ($committerDate !== null) + { + $data->dates->committer = $committerDate; + } + } + + if ($newBranch !== null) + { + $data->new_branch = $newBranch; + } + + if ($signoff !== null) + { + $data->signoff = $signoff; + } + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Get the EditorConfig definitions of a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $ref The name of the commit/branch/tag. + * + * @return string|null + * @since 3.2.0 + **/ + public function editor(string $owner, string $repo, string $filepath, string $ref = null): ?string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/editorconfig/{$filepath}"; + + // Set the request parameters. + $uri = $this->uri->get($path); + + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get the blob of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $sha The SHA hash of the blob. + * + * @return object|null + * @since 3.2.0 + **/ + public function blob(string $owner, string $repo, string $sha): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/blobs/{$sha}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Forks.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Forks.php new file mode 100644 index 000000000..224e286a3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Forks.php @@ -0,0 +1,102 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Forks + * + * @since 3.2.0 + */ +class Forks extends Api +{ + /** + * List a repository's forks. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + */ + public function listForks( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/forks"; + + // Set the query parameters. + $uri = $this->uri->get($uriPath); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Fork a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $forkName The name of the forked repository (optional). + * @param string $organization The organization name (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function repo( + string $owner, + string $repo, + string $forkName = '', + string $organization = '' + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/forks"; + + // Set the fork data. + $data = new \stdClass(); + + if (!empty($forkName)) + { + $data->name = $forkName; + } + + if (!empty($organization)) + { + $data->organization = $organization; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 202 + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Gpg.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Gpg.php new file mode 100644 index 000000000..0a6c317d4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Gpg.php @@ -0,0 +1,48 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Gpg + * + * @since 3.2.0 + */ +class Gpg extends Api +{ + /** + * Get signing-key.gpg for a given repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function get(string $ownerName, string $repoName): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/signing-key.gpg"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks.php new file mode 100644 index 000000000..eadb2e61d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks.php @@ -0,0 +1,214 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Hooks + * + * @since 3.2.0 + */ +class Hooks extends Api +{ + /** + * List the hooks in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks"; + + // Set up the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a hook in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $type The hook type. + * @param array $config The hook configuration. + * @param bool $active The hook's active status (optional, default: false). + * @param array|null $events The events for the hook (optional). + * @param string $branchFilter The branch filter (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $type, + array $config, + string $type, + array $config, + bool $active = false, + ?array $events = null, + string $branchFilter = '' + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks"; + + // Set the hook data. + $data = new \stdClass(); + $data->type = $type; + $data->config = (object) $config; + $data->active = $active; + + if ($events !== null) + { + $data->events = $events; + } + + if (!empty($branchFilter)) + { + $data->branch_filter = $branchFilter; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a hook. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $hookId The hook ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $hookId + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/{$hookId}"; + + // Get the URI for the request path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Edit a hook in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The hook ID. + * @param array $config The hook configuration. + * @param array $events The events to trigger the hook. + * @param bool $active Whether the hook is active. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + int $id, + array $config, + array $events, + bool $active + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/{$id}"; + + // Set the hook data. + $data = new \stdClass(); + $data->config = $config; + $data->events = $events; + $data->active = $active; + + // Send the PATCH request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Test a push webhook. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $hookId The hook ID. + * @param string $ref The name of the commit/branch/tag (optional). + * + * @return string + * @since 3.2.0 + **/ + public function test( + string $owner, + string $repo, + int $hookId, + string $ref = '' + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/{$hookId}/tests"; + + // Get the URI for the request path. + $uri = $this->uri->get($path); + + if (!empty($ref)) + { + $uri->setVar('ref', $ref); + } + + // Send the POST request. + return $this->response->get( + $this->http->post($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/Git.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/Git.php new file mode 100644 index 000000000..0b0a84922 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/Git.php @@ -0,0 +1,137 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository\Hooks; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Hooks Git + * + * @since 3.2.0 + */ +class Git extends Api +{ + /** + * List the Git hooks in a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $ownerName, string $repoName): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/hooks/git"; + + // Get the URI object with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a Git hook. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $hookId The Git hook ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $ownerName, + string $repoName, + int $hookId + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/hooks/git/{$hookId}"; + + // Get the URI object with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a Git hook in a repository. + * + * @param string $ownerName The owner name. + * @param string $repositoryName The repository name. + * @param string $hookId The Git hook ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repositoryName, + string $hookId + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repositoryName}/hooks/git/{$hookId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a Git hook in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $hookId The Git hook ID. + * @param array $hookOptions The hook configuration. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + string $hookId, + array $hookOptions + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/git/{$hookId}"; + + // Set the hook data. + $data = new \stdClass(); + $data->config = (object) $hookOptions; + + // Send the PATCH request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Keys.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Keys.php new file mode 100644 index 000000000..5e7757fd6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Keys.php @@ -0,0 +1,159 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Keys + * + * @since 3.2.0 + */ +class Keys extends Api +{ + /** + * List a repository's keys. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int|null $keyId The key_id to search for. (Optional) + * @param string|null $fingerprint The fingerprint of the key. (Optional) + * @param int $page The page number of results to return. (Default: 1) + * @param int $limit The page size of results. (Default: 10) + * + * @return array|null + * @since 3.2.0 + */ + public function list(string $owner, string $repo, ?int $keyId = null, ?string $fingerprint = null, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys"; + + // Prepare the URI. + $uri = $this->uri->get($path); + + // Add the optional query parameters. + if ($keyId !== null) + { + $uri->setVar('key_id', $keyId); + } + + if ($fingerprint !== null) + { + $uri->setVar('fingerprint', $fingerprint); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a key to a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $key The public key. + * @param string $title The title of the key. + * @param bool $readOnly Whether the key is read-only. + * + * @return object|null + * @since 3.2.0 + **/ + public function add( + string $owner, + string $repo, + string $key, + string $title, + bool $readOnly + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys"; + + // Set the key data. + $data = new \stdClass(); + $data->key = $key; + $data->title = $title; + $data->read_only = $readOnly; + + // Send the POST request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a repository's key by id. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The key ID. + * + * @return object|null + * @since 3.2.0 + */ + public function id( + string $owner, + string $repo, + int $id + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys/{$id}"; + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a key from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The key ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + int $id + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys/{$id}"; + + // Send the DELETE request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Languages.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Languages.php new file mode 100644 index 000000000..e4f4f0e21 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Languages.php @@ -0,0 +1,49 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Languages + * + * @since 3.2.0 + */ +class Languages extends Api +{ + /** + * Get languages and number of bytes of code written in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function getLanguages(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/languages"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Media.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Media.php new file mode 100644 index 000000000..74ea839e0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Media.php @@ -0,0 +1,63 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Media + * + * @since 3.2.0 + */ +class Media extends Api +{ + /** + * Get a file or its LFS object from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string|null $ref The name of the commit/branch/tag. (Optional) + * + * @return string + * @since 3.2.0 + */ + public function get( + string $owner, + string $repo, + string $filepath, + ?string $ref = null + ): string + { + // Build the request path. + $encodedFilepath = rawurlencode($filepath); + $path = "/repos/{$owner}/{$repo}/media/{$encodedFilepath}"; + + // Prepare the URI. + $uri = $this->uri->get($path); + + // Add the 'ref' query parameter if provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the GET request. + return $this->response->get( + $this->http->get($uri), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Merge.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Merge.php new file mode 100644 index 000000000..2b2cd2d1c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Merge.php @@ -0,0 +1,167 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Merge + * + * @since 3.2.0 + */ +class Merge extends Api +{ + /** + * Check if a pull request has been merged. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * + * @return string + * @since 3.2.0 + **/ + public function check( + string $owner, + string $repo, + int $index + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Merge a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $mergeMethod Merge method to use (optional). + * @param string|null $mergeCommitId Merge commit ID (optional). + * @param string|null $mergeMessageField Merge message field (optional). + * @param string|null $mergeTitleField Merge title field (optional). + * @param bool|null $deleteBranchAfterMerge Delete branch after merge (optional). + * @param bool|null $forceMerge Force merge (optional). + * @param string|null $headCommitId Head commit ID (optional). + * @param bool|null $mergeWhenChecksSucceed Merge when checks succeed (optional). + * + * @return string + * @since 3.2.0 + **/ + public function pull( + string $owner, + string $repo, + int $index, + ?string $mergeMethod = null, + ?string $mergeCommitId = null, + ?string $mergeMessageField = null, + ?string $mergeTitleField = null, + ?bool $deleteBranchAfterMerge = null, + ?bool $forceMerge = null, + ?string $headCommitId = null, + ?bool $mergeWhenChecksSucceed = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Set the merge data. + $data = new \stdClass(); + + if ($mergeMethod !== null) + { + $data->do = $mergeMethod; + } + + if ($mergeCommitId !== null) + { + $data->merge_commit_id = $mergeCommitId; + } + + if ($mergeMessageField !== null) + { + $data->merge_message_field = $mergeMessageField; + } + + if ($mergeTitleField !== null) + { + $data->merge_title_field = $mergeTitleField; + } + + if ($deleteBranchAfterMerge !== null) + { + $data->delete_branch_after_merge = $deleteBranchAfterMerge; + } + + if ($forceMerge !== null) + { + $data->force_merge = $forceMerge; + } + + if ($headCommitId !== null) + { + $data->head_commit_id = $headCommitId; + } + + if ($mergeWhenChecksSucceed !== null) + { + $data->merge_when_checks_succeed = $mergeWhenChecksSucceed; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 200, 'success' + ); + } + + /** + * Cancel the scheduled auto merge for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * + * @return string + * @since 3.2.0 + **/ + public function cancel( + string $owner, + string $repo, + int $index + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirror.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirror.php new file mode 100644 index 000000000..37e3b578e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirror.php @@ -0,0 +1,48 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Mirror + * + * @since 3.2.0 + */ +class Mirror extends Api +{ + /** + * Sync a mirrored repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + */ + public function sync(string $owner, string $repo): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/mirror-sync"; + + // Send the POST request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirrors.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirrors.php new file mode 100644 index 000000000..2dd60edce --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirrors.php @@ -0,0 +1,190 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Mirrors + * + * @since 3.2.0 + */ +class Mirrors extends Api +{ + /** + * Get all push mirrors of the repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + */ + public function get( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors"; + + // Set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a push mirror to the repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $remoteAddress The push mirror address. + * @param string|null $remoteUsername The push mirror user. (Optional) + * @param string|null $remotePassword The push mirror password. (Optional) + * @param string $interval The interval for the push mirror. + * @param bool $syncOnCommit Sync on commit option. + * + * @return object|null + * @since 3.2.0 + */ + public function add( + string $owner, + string $repo, + string $remoteAddress, + ?string $remoteUsername = null, + ?string $remotePassword = null, + string $interval, + bool $syncOnCommit + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors"; + + // Set the mirror data. + $data = new \stdClass(); + $data->remote_address = $remoteAddress; + $data->interval = $interval; + $data->sync_on_commit = $syncOnCommit; + + if ($remoteUsername !== null) + { + $data->remote_username = $remoteUsername; + } + + if ($remotePassword !== null) + { + $data->remote_password = $remotePassword; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Sync all push mirrored repositories. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + */ + public function sync( + string $owner, + string $repo + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors-sync"; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 200, 'success' + ); + } + + /** + * Get push mirror of the repository by remoteName. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $name The remote name. + * + * @return object|null + * @since 3.2.0 + */ + public function name( + string $owner, + string $repo, + string $name + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors/{$name}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a push mirror from a repository by remoteName. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $name The remote name. + * + * @return string + * @since 3.2.0 + */ + public function delete( + string $owner, + string $repo, + string $name + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors/{$name}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Notes.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Notes.php new file mode 100644 index 000000000..823d61344 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Notes.php @@ -0,0 +1,53 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Notes + * + * @since 3.2.0 + */ +class Notes extends Api +{ + /** + * Get a note corresponding to a single commit from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $commitSha The SHA hash of the commit. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $commitSha + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/notes/{$commitSha}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Patch.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Patch.php new file mode 100644 index 000000000..d7d80076b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Patch.php @@ -0,0 +1,78 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Patch + * + * @since 3.2.0 + */ +class Patch extends Api +{ + /** + * Apply a diff patch to a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param array $options Options for updating files. + * $options = [ + * 'description' => 'UpdateFileOptions', + * 'body' => [ + * 'content' => 'string', // Content must be base64 encoded. + * 'sha' => 'string', // The SHA for the file that already exists. + * 'branch' => 'string', // Branch (optional) to base this file from. If not given, the default branch is used. + * 'new_branch' => 'string', // New branch (optional) will make a new branch from branch before creating the file. + * 'from_path' => 'string', // From_path (optional) is the path of the original file which will be moved/renamed to the path in the URL. + * 'message' => 'string', // Message (optional) for the commit of this file. If not supplied, a default message will be used. + * 'author' => [ // Identity for a person's identity like an author or committer. + * 'name' => 'string', + * 'email' => 'string($email)' + * ], + * 'committer' => [ // Identity for a person's identity like an author or committer. + * 'name' => 'string', + * 'email' => 'string($email)' + * ], + * 'dates' => [ // Store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE. + * 'author' => 'string($date-time)', + * 'committer' => 'string($date-time)' + * ], + * 'signoff' => 'boolean' // Add a Signed-off-by trailer by the committer at the end of the commit log message. + * ] + * ] + * + * @return object|null + * @since 3.2.0 + */ + public function applyDiffPatch( + string $owner, + string $repo, + array $option + ): ?object + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/diffpatch"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($uriPath), + json_encode($options) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Pulls.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Pulls.php new file mode 100644 index 000000000..a979e797e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Pulls.php @@ -0,0 +1,547 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Pulls + * + * @since 3.2.0 + */ +class Pulls extends Api +{ + /** + * List a repository's pull requests. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string|null $state State of pull request: open, closed, or all (optional). + * @param string|null $sort Type of sort (optional). + * @param int|null $milestone ID of the milestone (optional). + * @param array|null $labels Label IDs (optional). + * @param int $page Page number of results to return (1-based, default: 1). + * @param int $limit Page size of results (default: 10). + * + * @return array|null + * @since 3.2.0 + */ + public function list( + string $owner, + string $repo, + ?string $state = null, + ?string $sort = null, + ?int $milestone = null, + ?array $labels = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls"; + + // Set query parameters. + $this->uri->setVar('page', $page); + $this->uri->setVar('limit', $limit); + + if ($state !== null) + { + $this->uri->setVar('state', $state); + } + + if ($sort !== null) + { + $this->uri->setVar('sort', $sort); + } + + if ($milestone !== null) + { + $this->uri->setVar('milestone', $milestone); + } + + if ($labels !== null) + { + $this->uri->setVar('labels', implode(',', $labels)); + } + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $title The title of the pull request. + * @param string $head The head branch. + * @param string $base The base branch. + * @param string|null $body The description of the pull request (optional). + * @param string|null $assignee The assignee of the pull request (optional). + * @param array|null $assignees Additional assignees (optional). + * @param array|null $labels Label IDs (optional). + * @param int|null $milestone ID of the milestone (optional). + * @param string|null $dueDate Due date of the pull request (optional). + * + * @return object|null + * @since 3.2.0 + */ + public function create( + string $owner, + string $repo, + string $title, + string $head, + string $base, + ?string $body = null, + ?string $assignee = null, + ?array $assignees = null, + ?array $labels = null, + ?int $milestone = null, + ?string $dueDate = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls"; + + // Set the pull request data. + $data = new \stdClass(); + $data->title = $title; + $data->head = $head; + $data->base = $base; + + if ($body !== null) + { + $data->body = $body; + } + + if ($assignee !== null) + { + $data->assignee = $assignee; + } + + if ($assignees !== null) + { + $data->assignees = $assignees; + } + + if ($labels !== null) + { + $data->labels = $labels; + } + + if ($milestone !== null) + { + $data->milestone = $milestone; + } + + if ($dueDate !== null) + { + $data->due_date = $dueDate; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $index): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Update a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $title The title of the pull request (optional). + * @param string|null $body The description of the pull request (optional). + * @param string|null $assignee The assignee of the pull request (optional). + * @param array|null $assignees Additional assignees (optional). + * @param string|null $base The base branch (optional). + * @param string|null $state The state of the pull request (optional). + * @param array|null $labels Label IDs (optional). + * @param int|null $milestone ID of the milestone (optional). + * @param string|null $dueDate Due date of the pull request (optional). + * @param bool|null $unsetDueDate Whether to unset the due date (optional). + * @param bool|null $allowMaintainerEdit Allow maintainer to edit the pull request (optional). + * + * @return object|null + * @since 3.2.0 + */ + public function update( + string $owner, + string $repo, + int $index, + ?string $title = null, + ?string $body = null, + ?string $assignee = null, + ?array $assignees = null, + ?string $base = null, + ?string $state = null, + ?array $labels = null, + ?int $milestone = null, + ?string $dueDate = null, + ?bool $unsetDueDate = null, + ?bool $allowMaintainerEdit = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}"; + + // Set the pull request data. + $data = new \stdClass(); + + if ($title !== null) + { + $data->title = $title; + } + + if ($body !== null) + { + $data->body = $body; + } + + if ($assignee !== null) + { + $data->assignee = $assignee; + } + + if ($assignees !== null) + { + $data->assignees = $assignees; + } + + if ($base !== null) + { + $data->base = $base; + } + + if ($state !== null) + { + $data->state = $state; + } + + if ($labels !== null) + { + $data->labels = $labels; + } + + if ($milestone !== null) + { + $data->milestone = $milestone; + } + + if ($dueDate !== null) + { + $data->due_date = $dueDate; + } + + if ($unsetDueDate !== null) + { + $data->unset_due_date = $unsetDueDate; + } + + if ($allowMaintainerEdit !== null) + { + $data->allow_maintainer_edit = $allowMaintainerEdit; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a pull request diff or patch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string $diffType The type of the requested data, either "diff" or "patch". + * @param bool $binary Whether to include binary file changes. If true, the diff is applicable with git apply. + * + * @return string + * @since 3.2.0 + **/ + public function diff( + string $owner, + string $repo, + int $index, + string $diffType, + bool $binary = false + ): string + { + // Validate the diff type. + if (!in_array($diffType, ['diff', 'patch'])) + { + throw new \InvalidArgumentException('Invalid diff type. Allowed types are "diff" and "patch".'); + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}.{$diffType}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Set the binary query parameter if required. + if ($binary) + { + $uri->setVar('binary', 'true'); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get commits for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function commits( + string $owner, + string $repo, + int $index, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/commits"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Set the page and limit query parameters. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get changed files for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string $skipTo Skip to the given file. + * @param string $whitespace Whitespace behavior. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function files( + string $owner, + string $repo, + int $index, + ?string $skipTo = null, + ?string $whitespace = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/files"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Set the skip-to, whitespace, page, and limit query parameters if needed. + if ($skipTo !== null) + { + $uri->setVar('skip-to', $skipTo); + } + if ($whitespace !== null) + { + $uri->setVar('whitespace', $whitespace); + } + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Merge a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $do Merge method. + * @param string|null $mergeCommitId Merge commit ID. + * @param string|null $mergeMessageField Merge message field. + * @param string|null $mergeTitleField Merge title field. + * @param bool|null $deleteBranchAfterMerge Whether to delete the branch after merge. + * @param bool|null $forceMerge Whether to force merge. + * @param string|null $headCommitId Head commit ID. + * @param bool|null $mergeWhenChecksSucceed Whether to merge when checks succeed. + * + * @return string + * @since 3.2.0 + **/ + public function merge( + string $owner, + string $repo, + int $index, + ?string $do = null, + ?string $mergeCommitId = null, + ?string $mergeMessageField = null, + ?string $mergeTitleField = null, + ?bool $deleteBranchAfterMerge = null, + ?bool $forceMerge = null, + ?string $headCommitId = null, + ?bool $mergeWhenChecksSucceed = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Set the merge data. + $data = new \stdClass(); + + if ($do !== null) + { + $data->do = $do; + } + + if ($mergeCommitId !== null) + { + $data->merge_commit_id = $mergeCommitId; + } + + if ($mergeMessageField !== null) + { + $data->merge_message_field = $mergeMessageField; + } + + if ($mergeTitleField !== null) + { + $data->merge_title_field = $mergeTitleField; + } + + if ($deleteBranchAfterMerge !== null) + { + $data->delete_branch_after_merge = $deleteBranchAfterMerge; + } + + if ($forceMerge !== null) + { + $data->force_merge = $forceMerge; + } + + if ($headCommitId !== null) + { + $data->head_commit_id = $headCommitId; + } + + if ($mergeWhenChecksSucceed !== null) + { + $data->merge_when_checks_succeed = $mergeWhenChecksSucceed; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 200, 'success' + ); + } + + /** + * Merge PR's baseBranch into headBranch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $style How to update the pull request. (Optional) + * + * @return string + * @since 3.2.0 + */ + public function update( + string $owner, + string $repo, + int $index, + ?string $style = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/update"; + + // Set the merge data. + $data = new \stdClass(); + + if ($style !== null) + { + $data->style = $style; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Refs.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Refs.php new file mode 100644 index 000000000..6abc59136 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Refs.php @@ -0,0 +1,77 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Refs + * + * @since 3.2.0 + */ +class Refs extends Api +{ + /** + * Get specified ref or filtered repository's refs. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/refs"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get specified ref. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $ref The ref name. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $ref + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/refs/{$ref}"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Releases.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Releases.php new file mode 100644 index 000000000..5723b5610 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Releases.php @@ -0,0 +1,309 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Releases + * + * @since 3.2.0 + */ +class Releases extends Api +{ + /** + * List a repo's releases. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param bool|null $draft Filter (exclude/include) drafts (optional). + * @param bool|null $preRelease Filter (exclude/include) pre-releases (optional). + * @param int $page Page number of results to return (1-based, optional). + * @param int $limit Page size of results (optional). + * + * @return array|null + * @since 3.2.0 + */ + public function list( + string $ownerName, + string $repoName, + ?bool $draft = null, + ?bool $preRelease = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases"; + + // Set additional URI values. + $this->uri->setVar('page', $page); + $this->uri->setVar('limit', $limit); + + if ($draft !== null) + { + $this->uri->setVar('draft', $draft); + } + + if ($preRelease !== null) + { + $this->uri->setVar('pre-release', $preRelease); + } + + // Send the request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create a release. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $tagName The tag name. + * @param string $targetCommitish The commitish value that determines where the Git tag is created from. + * @param string $releaseName The name of the release. + * @param string $releaseBody The description of the release. + * @param bool $isDraft Whether the release is a draft. + * @param bool $isPrerelease Whether the release is a pre-release. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $ownerName, + string $repoName, + string $tagName, + string $targetCommitish, + string $releaseName, + string $releaseBody, + bool $isDraft = false, + bool $isPrerelease = false + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases"; + + // Set the release data + $data = new \stdClass(); + $data->tag_name = $tagName; + $data->target_commitish = $targetCommitish; + $data->name = $releaseName; + $data->body = $releaseBody; + $data->draft = $isDraft; + $data->prerelease = $isPrerelease; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a release by ID. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $ownerName, + string $repoName, + int $releaseId + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a release by ID. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + int $releaseId + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a release. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * @param string|null $tagName The tag name (optional). + * @param string|null $targetCommitish The commitish value that determines where the Git tag is created from (optional). + * @param string|null $releaseName The name of the release (optional). + * @param string|null $description The description of the release (optional). + * @param bool|null $isDraft Whether the release is a draft (optional). + * @param bool|null $isPrerelease Whether the release is a pre-release (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $ownerName, + string $repoName, + int $releaseId, + ?string $tagName = null, + ?string $targetCommitish = null, + ?string $releaseName = null, + ?string $description = null, + ?bool $isDraft = null, + ?bool $isPrerelease = null + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}"; + + // Set the release data + $data = new \stdClass(); + + if ($tagName !== null || $targetCommitish !== null || $releaseName !== null || $description !== null || $isDraft !== null || $isPrerelease !== null) + { + $data->editReleaseOption = new \stdClass(); + + if ($tagName !== null) + { + $data->editReleaseOption->tag_name = $tagName; + } + + if ($targetCommitish !== null) + { + $data->editReleaseOption->target_commitish = $targetCommitish; + } + + if ($releaseName !== null) + { + $data->editReleaseOption->name = $releaseName; + } + + if ($description !== null) + { + $data->editReleaseOption->body = $description; + } + + if ($isDraft !== null) + { + $data->editReleaseOption->draft = $isDraft; + } + + if ($isPrerelease !== null) + { + $data->editReleaseOption->prerelease = $isPrerelease; + } + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Get a release by tag name. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $tagName The tag name. + * + * @return object|null + * @since 3.2.0 + **/ + public function getByTag( + string $ownerName, + string $repoName, + string $tagName + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/tags/{$tagName}"; + + // Configure the URI with the path. + $this->uri->setVar('owner', $ownerName); + $this->uri->setVar('repo', $repoName); + $this->uri->setVar('tag', $tagName); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a release by tag name. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $tagName The tag name. + * + * @return string + * @since 3.2.0 + **/ + public function deleteByTag( + string $ownerName, + string $repoName, + string $tagName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/tags/{$tagName}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Remote.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Remote.php new file mode 100644 index 000000000..f1bf1145b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Remote.php @@ -0,0 +1,96 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Remote + * + * @since 3.2.0 + */ +class Remote extends Api +{ + /** + * Migrate a remote git repository. + * + * @param string $cloneAddr The URL to clone the repository from. + * @param string $repoName The desired name for the new repository. + * @param string $repoOwner The name of the user or organization who will own the repo after migration. + * @param string $uid The ID of the user that will own the new repository (deprecated). + * @param string $description The description for the new repository (optional). + * @param bool $private Set the repository to private (optional, default false). + * @param string|null $authToken Authentication token (optional). + * @param string|null $authUsername Authentication username (optional). + * @param string|null $authPassword Authentication password (optional). + * @param array $options Additional migration options (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function migrate( + string $cloneAddr, + string $repoName, + string $repoOwner, + string $uid, + string $description = '', + bool $private = false, + ?string $authToken = null, + ?string $authUsername = null, + ?string $authPassword = null, + array $options = [] + ): ?object + { + // Build the request path. + $path = "/repos/migrate"; + + // Set the repository migration data. + $data = new \stdClass(); + $data->cloneAddr = $cloneAddr; + $data->repoName = $repoName; + $data->repoOwner = $repoOwner; + $data->uid = $uid; + $data->description = $description; + $data->private = $private; + + if ($authToken !== null) + { + $data->authToken = $authToken; + } + + if ($authUsername !== null) + { + $data->authUsername = $authUsername; + } + + if ($authPassword !== null) + { + $data->authPassword = $authPassword; + } + + foreach ($options as $key => $val) + { + $data->{$key} = $val; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviewers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviewers.php new file mode 100644 index 000000000..ee0a4a04d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviewers.php @@ -0,0 +1,126 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Reviewers + * + * @since 3.2.0 + */ +class Reviewers extends Api +{ + /** + * Create review requests for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param array $reviewers Array of reviewers usernames. + * @param array|null $teamReviewers Array of team reviewers (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function request( + string $owner, + string $repo, + int $index, + array $reviewers, + ?array $teamReviewers = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/requested_reviewers"; + + // Set the review requests data. + $data = new \stdClass(); + $data->reviewers = $reviewers; + + if ($teamReviewers !== null) + { + $data->team_reviewers = $teamReviewers; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Cancel review requests for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param array $reviewers Array of reviewers usernames. + * @param array|null $teamReviewers Array of team reviewers (optional). + * + * @return string + * @since 3.2.0 + **/ + public function cancel( + string $owner, + string $repo, + int $index, + array $reviewers, + ?array $teamReviewers = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/requested_reviewers"; + + // Get the URI and set the required variables. + $uri = $this->uri->get($path); + $uri->setVar('reviewers', json_encode($reviewers)); + + if ($teamReviewers !== null) + { + $uri->setVar('teamReviewers', json_encode($teamReviewers)); + } + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + + /** + * Return all users that can be requested to review in this repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/reviewers"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviews.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviews.php new file mode 100644 index 000000000..17e3ac319 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviews.php @@ -0,0 +1,321 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Reviews + * + * @since 3.2.0 + */ +class Reviews extends Api +{ + /** + * List all reviews for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $index, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews"; + + // Get the URI. + $uri = $this->uri->get($path); + + // Set query parameters. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string $body The review body text. + * @param string $event The review event type (APPROVE, REQUEST_CHANGES, COMMENT). + * @param array|null $comments An array of CreatePullReviewComment objects. + * @param string|null $commitId The commit ID. + * + * @return object|null + * @since 3.2.0 + */ + public function create( + string $owner, + string $repo, + int $index, + string $body, + string $event, + ?array $comments = null, + ?string $commitId = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews"; + + // Set the review data. + $data = new \stdClass(); + $data->body = $body; + $data->event = $event; + + // Add comments if available. + if ($comments !== null) + { + $data->comments = $comments; + } + + // Add commitId if available. + if ($commitId !== null) + { + $data->commit_id = $commitId; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Get a specific review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return object|null + * @since 3.2.0 + */ + public function get( + string $owner, + string $repo, + int $index, + int $id + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}"; + + // Set the variables for the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('index', $index); + $uri->setVar('id', $id); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Submit a pending review to a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * @param string $body The review body text. + * @param string $event The review event type (APPROVE, REQUEST_CHANGES, COMMENT). + * + * @return object|null + * @since 3.2.0 + */ + public function submit( + string $owner, + string $repo, + int $index, + int $id, + string $body, + string $event + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}"; + + // Set the review data. + $data = new \stdClass(); + $data->body = $body; + $data->event = $event; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Delete a specific review from a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return string + * @since 3.2.0 + */ + public function delete( + string $owner, + string $repo, + int $index, + int $id + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}"; + + // Set the variables for the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('index', $index); + $uri->setVar('id', $id); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + + /** + * Get the comments of a specific review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return array|null + * @since 3.2.0 + */ + public function comments( + string $owner, + string $repo, + int $index, + int $id + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}/comments"; + + // Set the variables for the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('index', $index); + $uri->setVar('id', $id); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Dismiss a review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * @param string $message The dismissal message. + * @param bool $priors The flag to dismiss prior reviews. + * + * @return object|null + * @since 3.2.0 + */ + public function dismiss( + string $owner, + string $repo, + int $index, + int $id, + string $message, + bool $priors = false + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}/dismissals"; + + // Set the dismissal data. + $data = new \stdClass(); + $data->message = $message; + $data->priors = $priors; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Cancel the dismissal of a review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return object|null + * @since 3.2.0 + */ + public function undismiss( + string $owner, + string $repo, + int $index, + int $id + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}/undismissals"; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Stargazers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Stargazers.php new file mode 100644 index 000000000..0c72b6d72 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Stargazers.php @@ -0,0 +1,59 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Stargazers + * + * @since 3.2.0 + */ +class Stargazers extends Api +{ + /** + * List a repo's stargazers. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/stargazers"; + + // Set the page and limit values. + $this->uri->setVar('page', $page); + $this->uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Statuses.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Statuses.php new file mode 100644 index 000000000..ba6e3c16c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Statuses.php @@ -0,0 +1,122 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Statuses + * + * @since 3.2.0 + */ +class Statuses extends Api +{ + /** + * Get a commit's statuses. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $commitSha The commit SHA. + * @param string $sort The type of sort. + * @param string $state The type of state. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $ownerName, + string $repoName, + string $commitSha, + string $sort = 'recentupdate', + string $state = 'pending', + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/statuses/{$commitSha}"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Set the query parameters. + $uri->setVar('sort', $sort); + $uri->setVar('state', $state); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a commit status. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $commitSha The commit SHA. + * @param string $state The commit status state (error, failure, pending, success, or warning). + * @param string|null $context The context of the status (optional). + * @param string|null $statusDescription The status description (optional). + * @param string|null $targetUrl The URL of the associated build status (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $ownerName, + string $repoName, + string $commitSha, + string $state, + ?string $context = null, + ?string $statusDescription = null, + ?string $targetUrl = null + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/statuses/{$commitSha}"; + + // Set the commit status data + $data = new \stdClass(); + $data->state = $state; + + if ($context !== null) + { + $data->context = $context; + } + + if ($statusDescription !== null) + { + $data->description = $statusDescription; + } + + if ($targetUrl !== null) + { + $data->target_url = $targetUrl; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Tags.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Tags.php new file mode 100644 index 000000000..600bfc2b0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Tags.php @@ -0,0 +1,182 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Tags + * + * @since 3.2.0 + */ +class Tags extends Api +{ + /** + * List a repository's tags + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param int|null $page The page number of results to return (1-based). + * @param int|null $limit The page size of results, default maximum page size is 10. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + ?int $page = 1, + ?int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Add query parameters if they are provided. + if ($page !== null) + { + $uri->setVar('page', $page); + } + + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get the tag of a repository by tag name. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $tag The tag name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $tag): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags/{$tag}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get the tag object of an annotated tag (not lightweight tags). + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string $sha The sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags. + * + * @return object|null + * @since 3.2.0 + **/ + public function sha( + string $owner, + string $repo, + string $sha + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/tags/{$sha}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a new git tag in a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string $tagName The name of the tag. + * @param string $target The SHA of the git object this is tagging. + * @param string $message The tag message. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $tagName, + string $target, + string $message + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags"; + + // Set the tag data + $data = new \stdClass(); + $data->tag_name = $tagName; + $data->target = $target; + $data->message = $message; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Delete a repository's tag by name. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $tag The tag name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $tag + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags/{$tag}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'succes' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Teams.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Teams.php new file mode 100644 index 000000000..cb39f7c4f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Teams.php @@ -0,0 +1,133 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Teams + * + * @since 3.2.0 + */ +class Teams extends Api +{ + /** + * List a repository's teams. + * + * @param string $ownerOfRepo The owner name. + * @param string $nameOfRepo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $ownerOfRepo, string $nameOfRepo): ?array + { + // Build the request path. + $path = "/repos/{$ownerOfRepo}/{$nameOfRepo}/teams"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if a team is assigned to a repository. + * + * @param string $ownerOfRepo The owner name. + * @param string $nameOfRepo The repository name. + * @param string $teamName The team name. + * + * @return object|null + * @since 3.2.0 + **/ + public function check( + string $ownerOfRepo, + string $nameOfRepo, + string $teamName + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerOfRepo}/{$nameOfRepo}/teams/{$teamName}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a team to a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $teamName The team name. + * + * @return string + * @since 3.2.0 + **/ + public function add( + string $ownerName, + string $repoName, + string $teamName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/teams/{$teamName}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Delete a team from a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $teamName The team name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + string $teamName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/teams/{$teamName}"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), + 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Templates.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Templates.php new file mode 100644 index 000000000..40246fcc0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Templates.php @@ -0,0 +1,91 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Templates + * + * @since 3.2.0 + */ +class Templates extends Api +{ + /** + * Get available issue templates for a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function issue(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issue_templates"; + + // Get the URI. + $uri = $this->uri->get($path); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a repository using a template. + * + * @param string $templateOwner The template owner's name. + * @param string $templateRepo The template repository name. + * @param string $name The name of the new repository. + * @param array $options Optional. Additional options for the new repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function repo( + string $templateOwner, + string $templateRepo, + string $name, + array $options = [] + ): ?object + { + // Build the request path. + $path = "/repos/{$templateOwner}/{$templateRepo}/generate"; + + // Set the repo data. + $data = new \stdClass(); + $data->name = $name; + + foreach ($options as $key => $value) + { + if ($value !== null) + { + $data->{$key} = $value; + } + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Times.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Times.php new file mode 100644 index 000000000..bae141607 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Times.php @@ -0,0 +1,80 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Times + * + * @since 3.2.0 + */ +class Times extends Api +{ + /** + * List a repo's tracked times. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $user Optional filter by user (available for issue managers). + * @param string $since Only show times updated after the given time. This is a timestamp in RFC 3339 format. + * @param string $before Only show times updated before the given time. This is a timestamp in RFC 3339 format. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + string $user = null, + string $since = null, + string $before = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/times"; + + // Set the query parameters. + $uri = $this->uri->get($path); + + if ($user !== null) + { + $uri->setVar('user', $user); + } + + if ($since !== null) + { + $uri->setVar('since', $since); + } + + if ($before !== null) + { + $uri->setVar('before', $before); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Topics.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Topics.php new file mode 100644 index 000000000..bbd24b874 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Topics.php @@ -0,0 +1,175 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Topics + * + * @since 3.2.0 + */ +class Topics extends Api +{ + /** + * Get the list of topics that a repository has. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/topics"; + + // Set query parameters for pagination. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Replace the list of topics for a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param array $topicNames The new list of topics. + * + * @return string + * @since 3.2.0 + **/ + public function replace( + string $ownerName, + string $repoName, + array $topicNames + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/topics"; + + // Set the topics data. + $data = new \stdClass(); + $data->topics = $topicNames; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), + json_encode($data) + ), 204, 'success' + ); + } + + /** + * Add a topic to a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $topicName The topic to add. + * + * @return string + * @since 3.2.0 + **/ + public function add( + string $ownerName, + string $repoName, + string $topicName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/topics/{$topicName}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Delete a topic from a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $topicName The topic to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + string $topicName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/topics/{$topicName}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Search topics via keyword. + * + * @param string $searchKeyword The keyword to search for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function search( + string $searchKeyword, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/topics/search"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('q', $searchKeyword); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Transfer.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Transfer.php new file mode 100644 index 000000000..b2e80be06 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Transfer.php @@ -0,0 +1,108 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Transfer + * + * @since 3.2.0 + */ +class Transfer extends Api +{ + /** + * Transfer a repo ownership. + * + * @param string $owner The current owner name. + * @param string $repo The repository name. + * @param string $newOwner The new owner's name. + * @param array|null $teamIDs Optional. The IDs of the teams that will be granted access. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $newOwner, + ?array $teamIDs = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/transfer"; + + // Set the transfer data. + $data = new \stdClass(); + $data->new_owner = $newOwner; + if ($teamIDs !== null) + { + $data->team_ids = $teamIDs; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 202 + ); + } + + /** + * Accept a repo transfer. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function accept(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/transfer/accept"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 202 + ); + } + + /** + * Reject a repo transfer. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function reject(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/transfer/reject"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Trees.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Trees.php new file mode 100644 index 000000000..a9e1974c2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Trees.php @@ -0,0 +1,63 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Trees + * + * @since 3.2.0 + */ +class Trees extends Api +{ + /** + * Get the tree of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $sha The commit SHA. + * @param bool $recursive Show all directories and files. + * @param int $page Page number. + * @param int $perPage Number of items per page. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $sha, + bool $recursive = false, + int $page = 1, + int $perPage = 30 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/trees/{$sha}"; + + // Set URI variables. + $uri = $this->uri->get($path); + $uri->setVar('recursive', $recursive); + $uri->setVar('page', $page); + $uri->setVar('per_page', $perPage); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Watchers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Watchers.php new file mode 100644 index 000000000..131482a3b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Watchers.php @@ -0,0 +1,140 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Watchers + * + * @since 3.2.0 + */ +class Watchers extends Api +{ + /** + * List a repo's watchers. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscribers"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Set the page and limit query parameters. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if the current user is watching a repo. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function check(string $ownerName, string $repoName): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscription"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Watch a repo. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param bool $subscribed Determine if notifications should be received from this repository. + * @param bool $ignored Determine if all notifications should be blocked from this repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function watch( + string $ownerName, + string $repoName, + bool $subscribed = true, + bool $ignored = false + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscription"; + + // Set the subscription data + $data = new \stdClass(); + $data->subscribed = $subscribed; + $data->ignored = $ignored; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Unwatch a repo. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function unwatch(string $ownerName, string $repoName): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscription"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Wiki.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Wiki.php new file mode 100644 index 000000000..748860817 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Wiki.php @@ -0,0 +1,232 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Wiki + * + * @since 3.2.0 + */ +class Wiki extends Api +{ + /** + * Create a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $title The title of the wiki page. + * @param string $contentBase64 The base64 encoded content of the wiki page. + * @param string|null $message Optional commit message summarizing the change. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $title, + string $contentBase64, + ?string $message = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/new"; + + // Set the wiki data. + $data = new \stdClass(); + $data->title = $title; + $data->content_base64 = $contentBase64; + + if ($message !== null) + { + $data->message = $message; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $pageName + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/page/{$pageName}"; + + // Set the URI. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get all wiki pages. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function pages( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/pages"; + + // Set the URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $pageName + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/page/{$pageName}"; + + // Get the URI. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + + /** + * Edit a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * @param string $title The new title of the wiki page. + * @param string $content The new content of the wiki page. + * @param string $message The optional commit message summarizing the change. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + string $pageName, + string $title, + string $content, + string $message = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/page/{$pageName}"; + + // Set the wiki data. + $data = new \stdClass(); + $data->title = $title; + $data->content_base64 = base64_encode($content); + + if ($message !== null) + { + $data->message = $message; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Get revisions of a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * @param int $page The page number of results to return (1-based). + * + * @return object|null + * @since 3.2.0 + **/ + public function revisions( + string $owner, + string $repo, + string $pageName, + int $page = 1 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/revisions/{$pageName}"; + + // Set the page number. + $this->uri->setVar('page', $page); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Admin.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Admin.php new file mode 100644 index 000000000..e6fc518bc --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Admin.php @@ -0,0 +1,184 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Admin\Cron; +use VDM\Joomla\Gitea\Admin\Organizations; +use VDM\Joomla\Gitea\Admin\Unadopted; +use VDM\Joomla\Gitea\Admin\Users; +use VDM\Joomla\Gitea\Admin\Users\Keys; +use VDM\Joomla\Gitea\Admin\Users\Organization; +use VDM\Joomla\Gitea\Admin\Users\Repository; + + +/** + * The Gitea Admin Service + * + * @since 3.2.0 + */ +class Admin implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Cron::class, 'Gitea.Admin.Cron') + ->share('Gitea.Admin.Cron', [$this, 'getCron'], true); + + $container->alias(Organizations::class, 'Gitea.Admin.Organizations') + ->share('Gitea.Admin.Organizations', [$this, 'getOrganizations'], true); + + $container->alias(Unadopted::class, 'Gitea.Admin.Unadopted') + ->share('Gitea.Admin.Unadopted', [$this, 'getUnadopted'], true); + + $container->alias(Users::class, 'Gitea.Admin.Users') + ->share('Gitea.Admin.Users', [$this, 'getUsers'], true); + + $container->alias(Keys::class, 'Gitea.Admin.Users.Keys') + ->share('Gitea.Admin.Users.Keys', [$this, 'getKeys'], true); + + $container->alias(Organization::class, 'Gitea.Admin.Users.Organization') + ->share('Gitea.Admin.Users.Organization', [$this, 'getOrganization'], true); + + $container->alias(Repository::class, 'Gitea.Admin.Users.Repository') + ->share('Gitea.Admin.Users.Repository', [$this, 'getRepository'], true); + } + + /** + * Get the Cron class + * + * @param Container $container The DI container. + * + * @return Cron + * @since 3.2.0 + */ + public function getCron(Container $container): Cron + { + return new Cron( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Organizations class + * + * @param Container $container The DI container. + * + * @return Organizations + * @since 3.2.0 + */ + public function getOrganizations(Container $container): Organizations + { + return new Organizations( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Unadopted class + * + * @param Container $container The DI container. + * + * @return Unadopted + * @since 3.2.0 + */ + public function getUnadopted(Container $container): Unadopted + { + return new Unadopted( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Users class + * + * @param Container $container The DI container. + * + * @return Users + * @since 3.2.0 + */ + public function getUsers(Container $container): Users + { + return new Users( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Keys class + * + * @param Container $container The DI container. + * + * @return Keys + * @since 3.2.0 + */ + public function getKeys(Container $container): Keys + { + return new Keys( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Organization class + * + * @param Container $container The DI container. + * + * @return Organization + * @since 3.2.0 + */ + public function getOrganization(Container $container): Organization + { + return new Organization( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Issue.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Issue.php new file mode 100644 index 000000000..9c49a5a3c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Issue.php @@ -0,0 +1,294 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Issue as Issu; +use VDM\Joomla\Gitea\Issue\Comments; +use VDM\Joomla\Gitea\Issue\Repository\Comments as RepoComments; +use VDM\Joomla\Gitea\Issue\Deadline; +use VDM\Joomla\Gitea\Labels; +use VDM\Joomla\Gitea\Issue\Labels as IssueLabels; +use VDM\Joomla\Gitea\Issue\Milestones; +use VDM\Joomla\Gitea\Issue\Reactions; +use VDM\Joomla\Gitea\Issue\Reactions\Comment; +use VDM\Joomla\Gitea\Issue\Stopwatch; +use VDM\Joomla\Gitea\Issue\Subscriptions; +use VDM\Joomla\Gitea\Issue\Timeline; +use VDM\Joomla\Gitea\Issue\Times; + + +/** + * The Gitea Issue Service + * + * @since 3.2.0 + */ +class Issue implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Issu::class, 'Gitea.Issue') + ->share('Gitea.Issue', [$this, 'getIssue'], true); + + $container->alias(Comments::class, 'Gitea.Issue.Comments') + ->share('Gitea.Issue.Comments', [$this, 'getComments'], true); + + $container->alias(RepoComments::class, 'Gitea.Issue.Repository.Comments') + ->share('Gitea.Issue.Repository.Comments', [$this, 'getRepoComments'], true); + + $container->alias(Deadline::class, 'Gitea.Issue.Deadline') + ->share('Gitea.Issue.Deadline', [$this, 'getDeadline'], true); + + $container->alias(Labels::class, 'Gitea.Labels') + ->share('Gitea.Labels', [$this, 'getLabels'], true); + + $container->alias(IssueLabels::class, 'Gitea.Issue.Labels') + ->share('Gitea.Issue.Labels', [$this, 'getIssueLabels'], true); + + $container->alias(Milestones::class, 'Gitea.Issue.Milestones') + ->share('Gitea.Issue.Milestones', [$this, 'getMilestones'], true); + + $container->alias(Reactions::class, 'Gitea.Issue.Reactions') + ->share('Gitea.Issue.Reactions', [$this, 'getReactions'], true); + + $container->alias(Comment::class, 'Gitea.Issue.Reactions.Comment') + ->share('Gitea.Issue.Reactions.Comment', [$this, 'getComment'], true); + + $container->alias(Stopwatch::class, 'Gitea.Issue.Stopwatch') + ->share('Gitea.Issue.Stopwatch', [$this, 'getStopwatch'], true); + + $container->alias(Subscriptions::class, 'Gitea.Issue.Subscriptions') + ->share('Gitea.Issue.Subscriptions', [$this, 'getSubscriptions'], true); + + $container->alias(Timeline::class, 'Gitea.Issue.Timeline') + ->share('Gitea.Issue.Timeline', [$this, 'getTimeline'], true); + + $container->alias(Times::class, 'Gitea.Issue.Times') + ->share('Gitea.Issue.Times', [$this, 'getTimes'], true); + } + + /** + * Get the Issue class + * + * @param Container $container The DI container. + * + * @return Issu + * @since 3.2.0 + */ + public function getIssue(Container $container): Issu + { + return new Issu( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Comments class + * + * @param Container $container The DI container. + * + * @return Comments + * @since 3.2.0 + */ + public function getComments(Container $container): Comments + { + return new Comments( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository Comments class + * + * @param Container $container The DI container. + * + * @return RepoComments + * @since 3.2.0 + */ + public function getRepoComments(Container $container): RepoComments + { + return new RepoComments( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Labels class + * + * @param Container $container The DI container. + * + * @return Labels + * @since 3.2.0 + */ + public function getLabels(Container $container): Labels + { + return new Labels( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Issue Labels class + * + * @param Container $container The DI container. + * + * @return IssueLabels + * @since 3.2.0 + */ + public function getIssueLabels(Container $container): IssueLabels + { + return new IssueLabels( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Milestones class + * + * @param Container $container The DI container. + * + * @return Milestones + * @since 3.2.0 + */ + public function getMilestones(Container $container): Milestones + { + return new Milestones( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reactions class + * + * @param Container $container The DI container. + * + * @return Reactions + * @since 3.2.0 + */ + public function getReactions(Container $container): Reactions + { + return new Reactions( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reactions Comment class + * + * @param Container $container The DI container. + * + * @return Comment + * @since 3.2.0 + */ + public function getComment(Container $container): Comment + { + return new Comment( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Stopwatch class + * + * @param Container $container The DI container. + * + * @return Stopwatch + * @since 3.2.0 + */ + public function getStopwatch(Container $container): Stopwatch + { + return new Stopwatch( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Subscriptions class + * + * @param Container $container The DI container. + * + * @return Subscriptions + * @since 3.2.0 + */ + public function getSubscriptions(Container $container): Subscriptions + { + return new Subscriptions( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Timeline class + * + * @param Container $container The DI container. + * + * @return Timeline + * @since 3.2.0 + */ + public function getTimeline(Container $container): Timeline + { + return new Timeline( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Times class + * + * @param Container $container The DI container. + * + * @return Times + * @since 3.2.0 + */ + public function getTimes(Container $container): Times + { + return new Times( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Jcb.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Jcb.php new file mode 100644 index 000000000..783527505 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Jcb.php @@ -0,0 +1,95 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Http; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * The Gitea Utilities Service + * + * @since 3.2.0 + */ +class Jcb implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Gitea.Dynamic.Uri') + ->share('Gitea.Dynamic.Uri', [$this, 'getUri'], true); + + $container->alias(Http::class, 'Gitea.Utilities.Http') + ->share('Gitea.Utilities.Http', [$this, 'getHttp'], true); + } + + /** + * Get the Dynamic Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + // get the global gitea URL + $add_gitea_url = Helper::getParams('com_componentbuilder')->get('add_custom_gitea_url', 1); + $gitea_url = Helper::getParams('com_componentbuilder')->get('custom_gitea_url'); + + // only load this if we have a custom URL set + if ($add_gitea_url == 2 && !empty($gitea_url) && strpos($gitea_url, 'http') !== false) + { + return new Uri($gitea_url); + } + + return $container->get('Gitea.Utilities.Uri'); + } + + /** + * Get the Http class + * + * @param Container $container The DI container. + * + * @return Http + * @since 3.2.0 + */ + public function getHttp(Container $container): Http + { + $add_gitea_url = Helper::getParams('com_componentbuilder')->get('add_custom_gitea_url', 1); + if ($add_gitea_url == 2) + { + return new Http( + Helper::getParams('com_componentbuilder')->get('custom_gitea_token') + ); + } + else + { + return new Http( + Helper::getParams('com_componentbuilder')->get('gitea_token') + ); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Miscellaneous.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Miscellaneous.php new file mode 100644 index 000000000..14abf45bb --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Miscellaneous.php @@ -0,0 +1,143 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Miscellaneous\Activitypub; +use VDM\Joomla\Gitea\Miscellaneous\Gpg; +use VDM\Joomla\Gitea\Miscellaneous\Markdown; +use VDM\Joomla\Gitea\Miscellaneous\NodeInfo; +use VDM\Joomla\Gitea\Miscellaneous\Version; + + +/** + * The Gitea Miscellaneous Service + * + * @since 3.2.0 + */ +class Miscellaneous implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Activitypub::class, 'Gitea.Miscellaneous.Activitypub') + ->share('Gitea.Miscellaneous.Activitypub', [$this, 'getActivitypub'], true); + + $container->alias(Gpg::class, 'Gitea.Miscellaneous.Gpg') + ->share('Gitea.Miscellaneous.Gpg', [$this, 'getGpg'], true); + + $container->alias(Markdown::class, 'Gitea.Miscellaneous.Markdown') + ->share('Gitea.Miscellaneous.Markdown', [$this, 'getMarkdown'], true); + + $container->alias(NodeInfo::class, 'Gitea.Miscellaneous.NodeInfo') + ->share('Gitea.Miscellaneous.NodeInfo', [$this, 'getNodeInfo'], true); + + $container->alias(Version::class, 'Gitea.Miscellaneous.Version') + ->share('Gitea.Miscellaneous.Version', [$this, 'getVersion'], true); + } + + /** + * Get the Activitypub class + * + * @param Container $container The DI container. + * + * @return Activitypub + * @since 3.2.0 + */ + public function getActivitypub(Container $container): Activitypub + { + return new Activitypub( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Gpg class + * + * @param Container $container The DI container. + * + * @return Gpg + * @since 3.2.0 + */ + public function getGpg(Container $container): Gpg + { + return new Gpg( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Markdown class + * + * @param Container $container The DI container. + * + * @return Markdown + * @since 3.2.0 + */ + public function getMarkdown(Container $container): Markdown + { + return new Markdown( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the NodeInfo class + * + * @param Container $container The DI container. + * + * @return NodeInfo + * @since 3.2.0 + */ + public function getNodeInfo(Container $container): NodeInfo + { + return new NodeInfo( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Version class + * + * @param Container $container The DI container. + * + * @return Version + * @since 3.2.0 + */ + public function getVersion(Container $container): Version + { + return new Version( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Notifications.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Notifications.php new file mode 100644 index 000000000..b6b5a29b2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Notifications.php @@ -0,0 +1,101 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Notifications as Notifi; +use VDM\Joomla\Gitea\Notifications\Repository; +use VDM\Joomla\Gitea\Notifications\Thread; + + +/** + * The Gitea Notifications Service + * + * @since 3.2.0 + */ +class Notifications implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Notifi::class, 'Gitea.Notifications') + ->share('Gitea.Notifications', [$this, 'getNotifications'], true); + + $container->alias(Repository::class, 'Gitea.Notifications.Repository') + ->share('Gitea.Notifications.Repository', [$this, 'getRepository'], true); + + $container->alias(Thread::class, 'Gitea.Notifications.Thread') + ->share('Gitea.Notifications.Thread', [$this, 'getThread'], true); + } + + /** + * Get the Notifications class + * + * @param Container $container The DI container. + * + * @return Notifi + * @since 3.2.0 + */ + public function getNotifications(Container $container): Notifi + { + return new Notifi( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Thread class + * + * @param Container $container The DI container. + * + * @return Thread + * @since 3.2.0 + */ + public function getThread(Container $container): Thread + { + return new Thread( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Organization.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Organization.php new file mode 100644 index 000000000..dab899e8e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Organization.php @@ -0,0 +1,248 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Organization as Org; +use VDM\Joomla\Gitea\Organization\Hooks; +use VDM\Joomla\Gitea\Organization\Labels; +use VDM\Joomla\Gitea\Organization\Members; +use VDM\Joomla\Gitea\Organization\PublicMembers as PublicMembers; +use VDM\Joomla\Gitea\Organization\Repository; +use VDM\Joomla\Gitea\Organization\Teams; +use VDM\Joomla\Gitea\Organization\Teams\Members as TeamsMembers; +use VDM\Joomla\Gitea\Organization\Teams\Repository as TeamsRepository; +use VDM\Joomla\Gitea\Organization\User; + + +/** + * The Gitea Organization Service + * + * @since 3.2.0 + */ +class Organization implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Org::class, 'Gitea.Organization') + ->share('Gitea.Organization', [$this, 'getOrganization'], true); + + $container->alias(Hooks::class, 'Gitea.Organization.Hooks') + ->share('Gitea.Organization.Hooks', [$this, 'getHooks'], true); + + $container->alias(Labels::class, 'Gitea.Organization.Labels') + ->share('Gitea.Organization.Labels', [$this, 'getLabels'], true); + + $container->alias(Members::class, 'Gitea.Organization.Members') + ->share('Gitea.Organization.Members', [$this, 'getMembers'], true); + + $container->alias(PublicMembers::class, 'Gitea.Organization.Public.Members') + ->share('Gitea.Organization.Public.Members', [$this, 'getPublicMembers'], true); + + $container->alias(Repository::class, 'Gitea.Organization.Repository') + ->share('Gitea.Organization.Repository', [$this, 'getRepository'], true); + + $container->alias(Teams::class, 'Gitea.Organization.Teams') + ->share('Gitea.Organization.Teams', [$this, 'getTeams'], true); + + $container->alias(TeamsMembers::class, 'Gitea.Organization.Teams.Members') + ->share('Gitea.Organization.Teams.Members', [$this, 'getTeamsMembers'], true); + + $container->alias(TeamsRepository::class, 'Gitea.Organization.Teams.Repository') + ->share('Gitea.Organization.Teams.Repository', [$this, 'getTeamsRepository'], true); + + $container->alias(User::class, 'Gitea.Organization.User') + ->share('Gitea.Organization.User', [$this, 'getUser'], true); + } + + /** + * Get the Organization class + * + * @param Container $container The DI container. + * + * @return Org + * @since 3.2.0 + */ + public function getOrganization(Container $container): Org + { + return new Org( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Hooks class + * + * @param Container $container The DI container. + * + * @return Hooks + * @since 3.2.0 + */ + public function getHooks(Container $container): Hooks + { + return new Hooks( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Labels class + * + * @param Container $container The DI container. + * + * @return Labels + * @since 3.2.0 + */ + public function getLabels(Container $container): Labels + { + return new Labels( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Members class + * + * @param Container $container The DI container. + * + * @return Members + * @since 3.2.0 + */ + public function getMembers(Container $container): Members + { + return new Members( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Public Members class + * + * @param Container $container The DI container. + * + * @return PublicMembers + * @since 3.2.0 + */ + public function getPublicMembers(Container $container): PublicMembers + { + return new PublicMembers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams class + * + * @param Container $container The DI container. + * + * @return Teams + * @since 3.2.0 + */ + public function getTeams(Container $container): Teams + { + return new Teams( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams Members class + * + * @param Container $container The DI container. + * + * @return TeamsMembers + * @since 3.2.0 + */ + public function getTeamsMembers(Container $container): TeamsMembers + { + return new TeamsMembers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams Repository class + * + * @param Container $container The DI container. + * + * @return TeamsRepository + * @since 3.2.0 + */ + public function getTeamsRepository(Container $container): TeamsRepository + { + return new TeamsRepository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the User class + * + * @param Container $container The DI container. + * + * @return User + * @since 3.2.0 + */ + public function getUser(Container $container): User + { + return new User( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Package.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Package.php new file mode 100644 index 000000000..75d92cb66 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Package.php @@ -0,0 +1,101 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Package as Pack; +use VDM\Joomla\Gitea\Package\Files; +use VDM\Joomla\Gitea\Package\Owner; + + +/** + * The Gitea Package Service + * + * @since 3.2.0 + */ +class Package implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Pack::class, 'Gitea.Package') + ->share('Gitea.Package', [$this, 'getPackage'], true); + + $container->alias(Files::class, 'Gitea.Package.Files') + ->share('Gitea.Package.Files', [$this, 'getFiles'], true); + + $container->alias(Owner::class, 'Gitea.Package.Owner') + ->share('Gitea.Package.Owner', [$this, 'getOwner'], true); + } + + /** + * Get the Package class + * + * @param Container $container The DI container. + * + * @return Pack + * @since 3.2.0 + */ + public function getPackage(Container $container): Pack + { + return new Pack( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Files class + * + * @param Container $container The DI container. + * + * @return Files + * @since 3.2.0 + */ + public function getFiles(Container $container): Files + { + return new Files( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Owner class + * + * @param Container $container The DI container. + * + * @return Owner + * @since 3.2.0 + */ + public function getOwner(Container $container): Owner + { + return new Owner( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Repository.php new file mode 100644 index 000000000..dea2c31ca --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Repository.php @@ -0,0 +1,835 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Repository as Repo; +use VDM\Joomla\Gitea\Repository\Archive; +use VDM\Joomla\Gitea\Repository\Assignees; +use VDM\Joomla\Gitea\Repository\Attachments; +use VDM\Joomla\Gitea\Repository\Branch; +use VDM\Joomla\Gitea\Repository\Branch\Protection; +use VDM\Joomla\Gitea\Repository\Collaborator; +use VDM\Joomla\Gitea\Repository\Commits; +use VDM\Joomla\Gitea\Repository\Contents; +use VDM\Joomla\Gitea\Repository\Forks; +use VDM\Joomla\Gitea\Repository\Gpg; +use VDM\Joomla\Gitea\Repository\Hooks; +use VDM\Joomla\Gitea\Repository\Hooks\Git; +use VDM\Joomla\Gitea\Repository\Keys; +use VDM\Joomla\Gitea\Repository\Languages; +use VDM\Joomla\Gitea\Repository\Media; +use VDM\Joomla\Gitea\Repository\Merge; +use VDM\Joomla\Gitea\Repository\Mirror; +use VDM\Joomla\Gitea\Repository\Mirrors; +use VDM\Joomla\Gitea\Repository\Notes; +use VDM\Joomla\Gitea\Repository\Patch; +use VDM\Joomla\Gitea\Repository\Pulls; +use VDM\Joomla\Gitea\Repository\Refs; +use VDM\Joomla\Gitea\Repository\Releases; +use VDM\Joomla\Gitea\Repository\Remote; +use VDM\Joomla\Gitea\Repository\Reviewers; +use VDM\Joomla\Gitea\Repository\Reviews; +use VDM\Joomla\Gitea\Repository\Stargazers; +use VDM\Joomla\Gitea\Repository\Statuses; +use VDM\Joomla\Gitea\Repository\Tags; +use VDM\Joomla\Gitea\Repository\Teams; +use VDM\Joomla\Gitea\Repository\Templates; +use VDM\Joomla\Gitea\Repository\Times; +use VDM\Joomla\Gitea\Repository\Topics; +use VDM\Joomla\Gitea\Repository\Transfer; +use VDM\Joomla\Gitea\Repository\Trees; +use VDM\Joomla\Gitea\Repository\Watchers; +use VDM\Joomla\Gitea\Repository\Wiki; + + +/** + * The Gitea Repository Service + * + * @since 3.2.0 + */ +class Repository implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Repo::class, 'Gitea.Repository') + ->share('Gitea.Repository', [$this, 'getRepository'], true); + + $container->alias(Archive::class, 'Gitea.Repository.Archive') + ->share('Gitea.Repository.Archive', [$this, 'getArchive'], true); + + $container->alias(Assignees::class, 'Gitea.Repository.Assignees') + ->share('Gitea.Repository.Assignees', [$this, 'getAssignees'], true); + + $container->alias(Attachments::class, 'Gitea.Repository.Attachments') + ->share('Gitea.Repository.Attachments', [$this, 'getAttachments'], true); + + $container->alias(Branch::class, 'Gitea.Repository.Branch') + ->share('Gitea.Repository.Branch', [$this, 'getBranch'], true); + + $container->alias(Protection::class, 'Gitea.Repository.Branch.Protection') + ->share('Gitea.Repository.Branch.Protection', [$this, 'getProtection'], true); + + $container->alias(Collaborator::class, 'Gitea.Repository.Collaborator') + ->share('Gitea.Repository.Collaborator', [$this, 'getCollaborator'], true); + + $container->alias(Commits::class, 'Gitea.Repository.Commits') + ->share('Gitea.Repository.Commits', [$this, 'getCommits'], true); + + $container->alias(Contents::class, 'Gitea.Repository.Contents') + ->share('Gitea.Repository.Contents', [$this, 'getContents'], true); + + $container->alias(Forks::class, 'Gitea.Repository.Forks') + ->share('Gitea.Repository.Forks', [$this, 'getForks'], true); + + $container->alias(Gpg::class, 'Gitea.Repository.Gpg') + ->share('Gitea.Repository.Gpg', [$this, 'getGpg'], true); + + $container->alias(Hooks::class, 'Gitea.Repository.Hooks') + ->share('Gitea.Repository.Hooks', [$this, 'getHooks'], true); + + $container->alias(Git::class, 'Gitea.Repository.Hooks.Git') + ->share('Gitea.Repository.Hooks.Git', [$this, 'getGit'], true); + + $container->alias(Keys::class, 'Gitea.Repository.Keys') + ->share('Gitea.Repository.Keys', [$this, 'getKeys'], true); + + $container->alias(Languages::class, 'Gitea.Repository.Languages') + ->share('Gitea.Repository.Languages', [$this, 'getLanguages'], true); + + $container->alias(Media::class, 'Gitea.Repository.Media') + ->share('Gitea.Repository.Media', [$this, 'getMedia'], true); + + $container->alias(Merge::class, 'Gitea.Repository.Merge') + ->share('Gitea.Repository.Merge', [$this, 'getMerge'], true); + + $container->alias(Mirror::class, 'Gitea.Repository.Mirror') + ->share('Gitea.Repository.Mirror', [$this, 'getMirror'], true); + + $container->alias(Mirrors::class, 'Gitea.Repository.Mirrors') + ->share('Gitea.Repository.Mirrors', [$this, 'getMirrors'], true); + + $container->alias(Notes::class, 'Gitea.Repository.Notes') + ->share('Gitea.Repository.Notes', [$this, 'getNotes'], true); + + $container->alias(Patch::class, 'Gitea.Repository.Patch') + ->share('Gitea.Repository.Patch', [$this, 'getPatch'], true); + + $container->alias(Pulls::class, 'Gitea.Repository.Pulls') + ->share('Gitea.Repository.Pulls', [$this, 'getPulls'], true); + + $container->alias(Refs::class, 'Gitea.Repository.Refs') + ->share('Gitea.Repository.Refs', [$this, 'getRefs'], true); + + $container->alias(Releases::class, 'Gitea.Repository.Releases') + ->share('Gitea.Repository.Releases', [$this, 'getReleases'], true); + + $container->alias(Remote::class, 'Gitea.Repository.Remote') + ->share('Gitea.Repository.Remote', [$this, 'getRemote'], true); + + $container->alias(Reviewers::class, 'Gitea.Repository.Reviewers') + ->share('Gitea.Repository.Reviewers', [$this, 'getReviewers'], true); + + $container->alias(Reviews::class, 'Gitea.Repository.Reviews') + ->share('Gitea.Repository.Reviews', [$this, 'getReviews'], true); + + $container->alias(Stargazers::class, 'Gitea.Repository.Stargazers') + ->share('Gitea.Repository.Stargazers', [$this, 'getStargazers'], true); + + $container->alias(Statuses::class, 'Gitea.Repository.Statuses') + ->share('Gitea.Repository.Statuses', [$this, 'getStatuses'], true); + + $container->alias(Tags::class, 'Gitea.Repository.Tags') + ->share('Gitea.Repository.Tags', [$this, 'getTags'], true); + + $container->alias(Teams::class, 'Gitea.Repository.Teams') + ->share('Gitea.Repository.Teams', [$this, 'getTeams'], true); + + $container->alias(Templates::class, 'Gitea.Repository.Templates') + ->share('Gitea.Repository.Templates', [$this, 'getTemplates'], true); + + $container->alias(Times::class, 'Gitea.Repository.Times') + ->share('Gitea.Repository.Times', [$this, 'getTimes'], true); + + $container->alias(Topics::class, 'Gitea.Repository.Topics') + ->share('Gitea.Repository.Topics', [$this, 'getTopics'], true); + + $container->alias(Transfer::class, 'Gitea.Repository.Transfer') + ->share('Gitea.Repository.Transfer', [$this, 'getTransfer'], true); + + $container->alias(Trees::class, 'Gitea.Repository.Trees') + ->share('Gitea.Repository.Trees', [$this, 'getTrees'], true); + + $container->alias(Watchers::class, 'Gitea.Repository.Watchers') + ->share('Gitea.Repository.Watchers', [$this, 'getWatchers'], true); + + $container->alias(Wiki::class, 'Gitea.Repository.Wiki') + ->share('Gitea.Repository.Wiki', [$this, 'getWiki'], true); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repo + * @since 3.2.0 + */ + public function getRepository(Container $container): Repo + { + return new Repo( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Archive class + * + * @param Container $container The DI container. + * + * @return Archive + * @since 3.2.0 + */ + public function getArchive(Container $container): Archive + { + return new Archive( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Assignees class + * + * @param Container $container The DI container. + * + * @return Assignees + * @since 3.2.0 + */ + public function getAssignees(Container $container): Assignees + { + return new Assignees( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Attachments class + * + * @param Container $container The DI container. + * + * @return Attachments + * @since 3.2.0 + */ + public function getAttachments(Container $container): Attachments + { + return new Attachments( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Branch class + * + * @param Container $container The DI container. + * + * @return Branch + * @since 3.2.0 + */ + public function getBranch(Container $container): Branch + { + return new Branch( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Branch Protection class + * + * @param Container $container The DI container. + * + * @return Protection + * @since 3.2.0 + */ + public function getProtection(Container $container): Protection + { + return new Protection( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Collaborator class + * + * @param Container $container The DI container. + * + * @return Collaborator + * @since 3.2.0 + */ + public function getCollaborator(Container $container): Collaborator + { + return new Collaborator( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Commits class + * + * @param Container $container The DI container. + * + * @return Commits + * @since 3.2.0 + */ + public function getCommits(Container $container): Commits + { + return new Commits( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Contents class + * + * @param Container $container The DI container. + * + * @return Contents + * @since 3.2.0 + */ + public function getContents(Container $container): Contents + { + return new Contents( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Forks class + * + * @param Container $container The DI container. + * + * @return Forks + * @since 3.2.0 + */ + public function getForks(Container $container): Forks + { + return new Forks( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Gpg class + * + * @param Container $container The DI container. + * + * @return Gpg + * @since 3.2.0 + */ + public function getGpg(Container $container): Gpg + { + return new Gpg( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Hooks class + * + * @param Container $container The DI container. + * + * @return Hooks + * @since 3.2.0 + */ + public function getHooks(Container $container): Hooks + { + return new Hooks( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Hooks Git class + * + * @param Container $container The DI container. + * + * @return Git + * @since 3.2.0 + */ + public function getGit(Container $container): Git + { + return new Git( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Keys class + * + * @param Container $container The DI container. + * + * @return Keys + * @since 3.2.0 + */ + public function getKeys(Container $container): Keys + { + return new Keys( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Languages class + * + * @param Container $container The DI container. + * + * @return Languages + * @since 3.2.0 + */ + public function getLanguages(Container $container): Languages + { + return new Languages( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Media class + * + * @param Container $container The DI container. + * + * @return Media + * @since 3.2.0 + */ + public function getMedia(Container $container): Media + { + return new Media( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Merge class + * + * @param Container $container The DI container. + * + * @return Merge + * @since 3.2.0 + */ + public function getMerge(Container $container): Merge + { + return new Merge( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Mirror class + * + * @param Container $container The DI container. + * + * @return Mirror + * @since 3.2.0 + */ + public function getMirror(Container $container): Mirror + { + return new Mirror( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Mirrors class + * + * @param Container $container The DI container. + * + * @return Mirrors + * @since 3.2.0 + */ + public function getMirrors(Container $container): Mirrors + { + return new Mirrors( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Notes class + * + * @param Container $container The DI container. + * + * @return Notes + * @since 3.2.0 + */ + public function getNotes(Container $container): Notes + { + return new Notes( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Patch class + * + * @param Container $container The DI container. + * + * @return Patch + * @since 3.2.0 + */ + public function getPatch(Container $container): Patch + { + return new Patch( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Pulls class + * + * @param Container $container The DI container. + * + * @return Pulls + * @since 3.2.0 + */ + public function getPulls(Container $container): Pulls + { + return new Pulls( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Refs class + * + * @param Container $container The DI container. + * + * @return Refs + * @since 3.2.0 + */ + public function getRefs(Container $container): Refs + { + return new Refs( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Releases class + * + * @param Container $container The DI container. + * + * @return Releases + * @since 3.2.0 + */ + public function getReleases(Container $container): Releases + { + return new Releases( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Remote class + * + * @param Container $container The DI container. + * + * @return Remote + * @since 3.2.0 + */ + public function getRemote(Container $container): Remote + { + return new Remote( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reviewers class + * + * @param Container $container The DI container. + * + * @return Reviewers + * @since 3.2.0 + */ + public function getReviewers(Container $container): Reviewers + { + return new Reviewers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reviews class + * + * @param Container $container The DI container. + * + * @return Reviews + * @since 3.2.0 + */ + public function getReviews(Container $container): Reviews + { + return new Reviews( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Stargazers class + * + * @param Container $container The DI container. + * + * @return Stargazers + * @since 3.2.0 + */ + public function getStargazers(Container $container): Stargazers + { + return new Stargazers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Statuses class + * + * @param Container $container The DI container. + * + * @return Statuses + * @since 3.2.0 + */ + public function getStatuses(Container $container): Statuses + { + return new Statuses( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Tags class + * + * @param Container $container The DI container. + * + * @return Tags + * @since 3.2.0 + */ + public function getTags(Container $container): Tags + { + return new Tags( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams class + * + * @param Container $container The DI container. + * + * @return Teams + * @since 3.2.0 + */ + public function getTeams(Container $container): Teams + { + return new Teams( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Templates class + * + * @param Container $container The DI container. + * + * @return Templates + * @since 3.2.0 + */ + public function getTemplates(Container $container): Templates + { + return new Templates( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Times class + * + * @param Container $container The DI container. + * + * @return Times + * @since 3.2.0 + */ + public function getTimes(Container $container): Times + { + return new Times( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Topics class + * + * @param Container $container The DI container. + * + * @return Topics + * @since 3.2.0 + */ + public function getTopics(Container $container): Topics + { + return new Topics( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Transfer class + * + * @param Container $container The DI container. + * + * @return Transfer + * @since 3.2.0 + */ + public function getTransfer(Container $container): Transfer + { + return new Transfer( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Trees class + * + * @param Container $container The DI container. + * + * @return Trees + * @since 3.2.0 + */ + public function getTrees(Container $container): Trees + { + return new Trees( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Watchers class + * + * @param Container $container The DI container. + * + * @return Watchers + * @since 3.2.0 + */ + public function getWatchers(Container $container): Watchers + { + return new Watchers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Wiki class + * + * @param Container $container The DI container. + * + * @return Wiki + * @since 3.2.0 + */ + public function getWiki(Container $container): Wiki + { + return new Wiki( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Settings.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Settings.php new file mode 100644 index 000000000..e4b1a7e46 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Settings.php @@ -0,0 +1,123 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Settings\Api; +use VDM\Joomla\Gitea\Settings\Attachment; +use VDM\Joomla\Gitea\Settings\Repository; +use VDM\Joomla\Gitea\Settings\Ui; + + +/** + * The Gitea Settings Service + * + * @since 3.2.0 + */ +class Settings implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Api::class, 'Gitea.Settings.Api') + ->share('Gitea.Settings.Api', [$this, 'getApi'], true); + + $container->alias(Attachment::class, 'Gitea.Settings.Attachment') + ->share('Gitea.Settings.Attachment', [$this, 'getAttachment'], true); + + $container->alias(Repository::class, 'Gitea.Settings.Repository') + ->share('Gitea.Settings.Repository', [$this, 'getRepository'], true); + + $container->alias(Ui::class, 'Gitea.Settings.Ui') + ->share('Gitea.Settings.Ui', [$this, 'getUi'], true); + } + + /** + * Get the Api class + * + * @param Container $container The DI container. + * + * @return Api + * @since 3.2.0 + */ + public function getApi(Container $container): Api + { + return new Api( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Attachment class + * + * @param Container $container The DI container. + * + * @return Attachment + * @since 3.2.0 + */ + public function getAttachment(Container $container): Attachment + { + return new Attachment( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Ui class + * + * @param Container $container The DI container. + * + * @return Ui + * @since 3.2.0 + */ + public function getUi(Container $container): Ui + { + return new Ui( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/User.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/User.php new file mode 100644 index 000000000..63bc120a9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/User.php @@ -0,0 +1,332 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\User as Usr; +use VDM\Joomla\Gitea\User\Applications; +use VDM\Joomla\Gitea\User\Emails; +use VDM\Joomla\Gitea\User\Followers; +use VDM\Joomla\Gitea\User\Following; +use VDM\Joomla\Gitea\User\Gpg; +use VDM\Joomla\Gitea\User\Keys; +use VDM\Joomla\Gitea\User\Repos; +use VDM\Joomla\Gitea\User\Settings; +use VDM\Joomla\Gitea\User\Starred; +use VDM\Joomla\Gitea\User\Subscriptions; +use VDM\Joomla\Gitea\User\Teams; +use VDM\Joomla\Gitea\User\Times; +use VDM\Joomla\Gitea\User\Tokens; + + +/** + * The Gitea User Service + * + * @since 3.2.0 + */ +class User implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Usr::class, 'Gitea.User') + ->share('Gitea.User', [$this, 'getUser'], true); + + $container->alias(Applications::class, 'Gitea.User.Applications') + ->share('Gitea.User.Applications', [$this, 'getApplications'], true); + + $container->alias(Emails::class, 'Gitea.User.Emails') + ->share('Gitea.User.Emails', [$this, 'getEmails'], true); + + $container->alias(Followers::class, 'Gitea.User.Followers') + ->share('Gitea.User.Followers', [$this, 'getFollowers'], true); + + $container->alias(Following::class, 'Gitea.User.Following') + ->share('Gitea.User.Following', [$this, 'getFollowing'], true); + + $container->alias(Gpg::class, 'Gitea.User.Gpg') + ->share('Gitea.User.Gpg', [$this, 'getGpg'], true); + + $container->alias(Keys::class, 'Gitea.User.Keys') + ->share('Gitea.User.Keys', [$this, 'getKeys'], true); + + $container->alias(Repos::class, 'Gitea.User.Repos') + ->share('Gitea.User.Repos', [$this, 'getRepos'], true); + + $container->alias(Settings::class, 'Gitea.User.Settings') + ->share('Gitea.User.Settings', [$this, 'getSettings'], true); + + $container->alias(Starred::class, 'Gitea.User.Starred') + ->share('Gitea.User.Starred', [$this, 'getStarred'], true); + + $container->alias(Subscriptions::class, 'Gitea.User.Subscriptions') + ->share('Gitea.User.Subscriptions', [$this, 'getSubscriptions'], true); + + $container->alias(Teams::class, 'Gitea.User.Teams') + ->share('Gitea.User.Teams', [$this, 'getTeams'], true); + + $container->alias(Times::class, 'Gitea.User.Times') + ->share('Gitea.User.Times', [$this, 'getTimes'], true); + + $container->alias(Tokens::class, 'Gitea.User.Tokens') + ->share('Gitea.User.Tokens', [$this, 'getTokens'], true); + } + + /** + * Get the User class + * + * @param Container $container The DI container. + * + * @return Usr + * @since 3.2.0 + */ + public function getUser(Container $container): Usr + { + return new Usr( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Applications class + * + * @param Container $container The DI container. + * + * @return Applications + * @since 3.2.0 + */ + public function getApplications(Container $container): Applications + { + return new Applications( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Emails class + * + * @param Container $container The DI container. + * + * @return Emails + * @since 3.2.0 + */ + public function getEmails(Container $container): Emails + { + return new Emails( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Followers class + * + * @param Container $container The DI container. + * + * @return Followers + * @since 3.2.0 + */ + public function getFollowers(Container $container): Followers + { + return new Followers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Following class + * + * @param Container $container The DI container. + * + * @return Following + * @since 3.2.0 + */ + public function getFollowing(Container $container): Following + { + return new Following( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Gpg class + * + * @param Container $container The DI container. + * + * @return Gpg + * @since 3.2.0 + */ + public function getGpg(Container $container): Gpg + { + return new Gpg( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Keys class + * + * @param Container $container The DI container. + * + * @return Keys + * @since 3.2.0 + */ + public function getKeys(Container $container): Keys + { + return new Keys( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repos class + * + * @param Container $container The DI container. + * + * @return Repos + * @since 3.2.0 + */ + public function getRepos(Container $container): Repos + { + return new Repos( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Settings class + * + * @param Container $container The DI container. + * + * @return Settings + * @since 3.2.0 + */ + public function getSettings(Container $container): Settings + { + return new Settings( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Starred class + * + * @param Container $container The DI container. + * + * @return Starred + * @since 3.2.0 + */ + public function getStarred(Container $container): Starred + { + return new Starred( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Subscriptions class + * + * @param Container $container The DI container. + * + * @return Subscriptions + * @since 3.2.0 + */ + public function getSubscriptions(Container $container): Subscriptions + { + return new Subscriptions( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams class + * + * @param Container $container The DI container. + * + * @return Teams + * @since 3.2.0 + */ + public function getTeams(Container $container): Teams + { + return new Teams( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Times class + * + * @param Container $container The DI container. + * + * @return Times + * @since 3.2.0 + */ + public function getTimes(Container $container): Times + { + return new Times( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Tokens class + * + * @param Container $container The DI container. + * + * @return Tokens + * @since 3.2.0 + */ + public function getTokens(Container $container): Tokens + { + return new Tokens( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Utilities.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Utilities.php new file mode 100644 index 000000000..06427b691 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Utilities.php @@ -0,0 +1,71 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Response; + + +/** + * The Gitea Utilities Service + * + * @since 3.2.0 + */ +class Utilities implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Gitea.Utilities.Uri') + ->share('Gitea.Utilities.Uri', [$this, 'getUri'], true); + + $container->alias(Response::class, 'Gitea.Utilities.Response') + ->share('Gitea.Utilities.Response', [$this, 'getResponse'], true); + } + + /** + * Get the Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + return new Uri(); + } + + /** + * Get the Response class + * + * @param Container $container The DI container. + * + * @return Response + * @since 3.2.0 + */ + public function getResponse(Container $container): Response + { + return new Response(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Api.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Api.php new file mode 100644 index 000000000..cf2d56f96 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Api.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api as BaseAPI; + + +/** + * The Gitea Settings Api + * + * @since 3.2.0 + */ +class Api extends BaseAPI +{ + /** + * Get instance's global settings for API. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/api"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Attachment.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Attachment.php new file mode 100644 index 000000000..921938821 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Attachment.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Settings Attachment + * + * @since 3.2.0 + */ +class Attachment extends Api +{ + /** + * Get instance's global settings for Attachment. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/attachment"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Repository.php new file mode 100644 index 000000000..adbf90846 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Repository.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Settings Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * Get instance's global settings for repositories. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/repository"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Ui.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Ui.php new file mode 100644 index 000000000..def2668c0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Ui.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Settings Ui + * + * @since 3.2.0 + */ +class Ui extends Api +{ + /** + * Get instance's global settings for UI. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/ui"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User.php new file mode 100644 index 000000000..bb9c82e7a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User.php @@ -0,0 +1,335 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User + * + * @since 3.2.0 + */ +class User extends Api +{ + /** + * Get the authenticated user. + * + * @return object|null + * @since 3.2.0 + **/ + public function authenticate(): ?object + { + // Build the request path. + $path = '/user'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Search for users. + * + * @param string $keyword The search keyword. + * @param int|null $uid Optional. ID of the user to search for. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function search( + string $keyword, + ?int $uid = null, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = '/users/search'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('q', $keyword); + + if ($uid !== null) + { + $uri->setVar('uid', $uid); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a user by their username. + * + * @param string $username The username of the user to retrieve. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $username): o?bject + { + // Build the request path. + $path = "/users/{$username}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * List the given user's followers. + * + * @param string $userName The username of the user to retrieve followers for. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function followers( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/followers"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List the users that the given user is following. + * + * @param string $userName The username of the user to retrieve the following users for. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function following( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/following"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if one user is following another user. + * + * @param string $username The username of the user to check. + * @param string $target The username of the target user. + * + * @return string + * @since 3.2.0 + **/ + public function check(string $username, string $target): string + { + // Build the request path. + $path = "/users/{$username}/following/{$target}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * List the given user's GPG keys. + * + * @param string $userName The username of the user to retrieve GPG keys for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function gpg( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/gpg_keys"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a user's heatmap. + * + * @param string $username The username of the user to retrieve heatmap for. + * + * @return array|null + * @since 3.2.0 + **/ + public function heatmap(string $username): ?array + { + // Build the request path. + $path = "/users/{$username}/heatmap"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * List the given user's public keys. + * + * @param string $userName The username of the user to retrieve public keys for. + * @param string|null $fingerprint Optional. The fingerprint of the key. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function keys( + string $userName, + ?string $fingerprint = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/keys"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + if ($fingerprint !== null) + { + $uri->setVar('fingerprint', $fingerprint); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List the repos that the given user has starred. + * + * @param string $userName The username of the user to retrieve starred repos for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function repos( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/starred"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List the repositories watched by a user. + * + * @param string $userName The username of the user to retrieve watched repositories for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function watched( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/subscriptions"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Applications.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Applications.php new file mode 100644 index 000000000..10d8dc600 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Applications.php @@ -0,0 +1,166 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Applications + * + * @since 3.2.0 + */ +class Applications extends Api +{ + /** + * List the authenticated user's oauth2 applications. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/applications/oauth2'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get an OAuth2 application by ID. + * + * @param int $id The OAuth2 application ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function id(int $id): ?object + { + // Build the request path. + $path = "/user/applications/oauth2/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Creates a new OAuth2 application. + * + * @param string $appName The application name. + * @param array $redirectUris The application redirect URIs. + * @param bool $confidentialClient The confidentiality of the client (default: true). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $appName, + array $redirectUris, + bool $confidentialClient = true + ): ?object + { + // Build the request path. + $path = '/user/applications/oauth2'; + + // Set the application data. + $data = new \stdClass(); + $data->name = $appName; + $data->redirect_uris = $redirectUris; + $data->confidential_client = $confidentialClient; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Delete an OAuth2 application by ID. + * + * @param int $id The OAuth2 application ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(int $id): string + { + // Build the request path. + $path = "/user/applications/oauth2/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update an OAuth2 application by ID, this includes regenerating the client secret. + * + * @param int $appId The OAuth2 application ID. + * @param string $appName The application name. + * @param array $redirectUris The application redirect URIs. + * @param bool $confidentialClient The confidentiality of the client (default: true). + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + int $appId, + string $appName, + array $redirectUris, + bool $confidentialClient = true + ): ?object + { + // Build the request path. + $path = "/user/applications/oauth2/{$appId}"; + + // Set the application data. + $data = new \stdClass(); + $data->name = $appName; + $data->redirect_uris = $redirectUris; + $data->confidential_client = $confidentialClient; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Emails.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Emails.php new file mode 100644 index 000000000..aa63b288a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Emails.php @@ -0,0 +1,94 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Emails + * + * @since 3.2.0 + */ +class Emails extends Api +{ + /** + * List the authenticated user's email addresses. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(): ?array + { + // Build the request path. + $path = '/user/emails'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add email addresses for the authenticated user. + * + * @param array $emails An array of email addresses to add. + * + * @return array|null + * @since 3.2.0 + **/ + public function add(array $emails): ?array + { + // Build the request path. + $path = '/user/emails'; + + // Create the request body. + $body = new \stdClass(); + $body->emails = $emails; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($body) + ), 201 + ); + } + + /** + * Delete email addresses for the authenticated user. + * + * @param array $$emails An array of email addresses to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(array $emails): string + { + // Build the request path. + $path = '/user/emails'; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('emails', json_encode($emails)); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Followers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Followers.php new file mode 100644 index 000000000..71b028a28 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Followers.php @@ -0,0 +1,54 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Followers + * + * @since 3.2.0 + */ +class Followers extends Api +{ + /** + * List the authenticated user's followers. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/followers'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Following.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Following.php new file mode 100644 index 000000000..339244969 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Following.php @@ -0,0 +1,122 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Following + * + * @since 3.2.0 + */ +class Following extends Api +{ + /** + * List the users that the authenticated user is following. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/following'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Check whether a user is followed by the authenticated user. + * + * @param string $username The username to check. + * + * @return bool + * @since 3.2.0 + **/ + public function check(string $username): bool + { + // Build the request path. + $path = "/user/following/{$username}"; + + // Send the get request. + $response = $this->http->get( + $this->uri->get($path) + ); + + // Check if the user is followed by the authenticated user. + if ($response->code === 204) + { + return true; + } + return false; + } + + /** + * Follow a user. + * + * @param string $username The username to follow. + * + * @return string + * @since 3.2.0 + **/ + public function follow(string $username): string + { + // Build the request path. + $path = "/user/following/{$username}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Unfollow a user. + * + * @param string $username The username to unfollow. + * + * @return string + * @since 3.2.0 + **/ + public function unfollow(string $username): string + { + // Build the request path. + $path = "/user/following/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Gpg.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Gpg.php new file mode 100644 index 000000000..bf8f6c671 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Gpg.php @@ -0,0 +1,173 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Gpg + * + * @since 3.2.0 + */ +class Gpg extends Api +{ + /** + * Create a GPG key for the authenticated user. + * + * @param string $armoredPublicKey The armored public GPG key. + * @param string|null $armoredSignature The armored signature (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function createGPGKey( + string $armoredPublicKey, + ?string $armoredSignature = null + ): ?object + { + // Build the request path. + $path = '/user/gpg_keys'; + + // Set the GPG key data. + $data = array_filter([ + 'armored_public_key' => $armoredPublicKey, + 'armored_signature' => $armoredSignature + ]); + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a GPG key for the authenticated user. + * + * @param int $id The GPG key ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/user/gpg_keys/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get a token to verify. + * + * @return string|null + * @since 3.2.0 + **/ + public function token(): ?string + { + // Build the request path. + $path = '/user/gpg_key_token'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Verify a GPG key. + * + * @param string $armoredPublicKey The armored public GPG key. + * + * @return object|null + * @since 3.2.0 + **/ + public function verify(string $armoredPublicKey): ?object + { + // Build the request path. + $path = '/user/gpg_key_verify'; + + // Set the GPG key data. + $data = new \stdClass(); + $data->armoredPublicKey = $armoredPublicKey; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * List the authenticated user's GPG keys. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/gpg_keys'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Remove a GPG key for the authenticated user. + * + * @param int $id The GPG key ID. + * + * @return string + * @since 3.2.0 + **/ + public function remove(int $id): string + { + // Build the request path. + $path = "/user/gpg_keys/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Keys.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Keys.php new file mode 100644 index 000000000..ed22c4033 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Keys.php @@ -0,0 +1,135 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Keys + * + * @since 3.2.0 + */ +class Keys extends Api +{ + /** + * Create a public key for the authenticated user. + * + * @param string $title The title of the public key. + * @param string $key The content of the public key. + * @param bool $readOnly Optional. True if the key has only read access, false for read/write access. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $title, + string $key, + bool $readOnly = false + ): ?object + { + // Build the request path. + $path = '/user/keys'; + + // Set the public key data. + $data = new \stdClass(); + $data->title = $title; + $data->key = $key; + $data->read_only = $readOnly; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * List the authenticated user's public keys. + * + * @param string|null $fingerprint Optional. The fingerprint of the key. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + ?string $fingerprint = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/keys'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + if ($fingerprint !== null) { + $uri->setVar('fingerprint', $fingerprint); + } + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a public key for the authenticated user. + * + * @param int $id The public key ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/user/keys/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a public key for the authenticated user. + * + * @param int $id The public key ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(int $id): string + { + // Build the request path. + $path = "/user/keys/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Repos.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Repos.php new file mode 100644 index 000000000..a7f8021c9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Repos.php @@ -0,0 +1,188 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Repos + * + * @since 3.2.0 + */ +class Repos extends Api +{ + /** + * Create a repository for the authenticated user. + * + * @param string $name The name of the repository. + * @param string|null $description Optional. The description of the repository. + * @param bool $private Optional. Indicates whether the repository should be private or not. + * @param bool $autoInit Optional. Indicates whether the repository should be auto-initialized. + * @param string|null $defaultBranch Optional. The default branch of the repository. + * @param string|null $gitignores Optional. Gitignores to use. + * @param string|null $issueLabels Optional. Label-Set to use. + * @param string|null $license Optional. License to use. + * @param string|null $readme Optional. Readme of the repository to create. + * @param bool|null $template Optional. Whether the repository is a template. + * @param string|null $trustModel Optional. TrustModel of the repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $name, + ?string $description = null, + bool $private = false, + bool $autoInit = false, + ?string $defaultBranch = null, + ?string $gitignores = null, + ?string $issueLabels = null, + ?string $license = null, + ?string $readme = null, + ?bool $template = null, + ?string $trustModel = null + ): ?object { + // Build the request path. + $path = '/user/repos'; + + // Set the repository data. + $data = new \stdClass(); + $data->name = $name; + + if ($description !== null) + { + $data->description = $description; + } + + $data->private = $private; + $data->auto_init = $autoInit; + + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + + if ($gitignores !== null) + { + $data->gitignores = $gitignores; + } + + if ($issueLabels !== null) + { + $data->issue_labels = $issueLabels; + } + + if ($license !== null) + { + $data->license = $license; + } + + if ($readme !== null) + { + $data->readme = $readme; + } + + if ($template !== null) + { + $data->template = $template; + } + + if ($trustModel !== null) + { + $data->trust_model = $trustModel; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * List the repos that the authenticated user owns. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/repos'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Star the given repo for the authenticated user. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function star(string $owner, string $repo): string + { + // Build the request path. + $path = "/user/starred/{$owner}/{$repo}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Unstar the given repo for the authenticated user. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function unstar(string $owner, string $repo): string + { + // Build the request path. + $path = "/user/starred/{$owner}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Settings.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Settings.php new file mode 100644 index 000000000..2118c9e0e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Settings.php @@ -0,0 +1,124 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Settings + * + * @since 3.2.0 + */ +class Settings extends Api +{ + /** + * Get user settings for the authenticated user. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = '/user/settings'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Update user settings for the authenticated user. + * + * @param string|null $description Optional. The description to update. + * @param string|null $diffViewStyle Optional. The diff view style to update. + * @param string|null $fullName Optional. The full name to update. + * @param bool|null $hideActivity Optional. Whether to hide activity or not. + * @param bool|null $hideEmail Optional. Whether to hide email or not. + * @param string|null $language Optional. The language to update. + * @param string|null $location Optional. The location to update. + * @param string|null $theme Optional. The theme to update. + * @param string|null $website Optional. The website to update. + * + * @return array|null + * @since 3.2.0 + **/ + public function update( + ?string $description = null, + ?string $diffViewStyle = null, + ?string $fullName = null, + ?bool $hideActivity = null, + ?bool $hideEmail = null, + ?string $language = null, + ?string $location = null, + ?string $theme = null, + ?string $website = null + ): ?array + { + // Prepare settings data + $settings = []; + if ($description !== null) + { + $settings['description'] = $description; + } + if ($diffViewStyle !== null) + { + $settings['diff_view_style'] = $diffViewStyle; + } + if ($fullName !== null) + { + $settings['full_name'] = $fullName; + } + if ($hideActivity !== null) + { + $settings['hide_activity'] = $hideActivity; + } + if ($hideEmail !== null) + { + $settings['hide_email'] = $hideEmail; + } + if ($language !== null) + { + $settings['language'] = $language; + } + if ($location !== null) + { + $settings['location'] = $location; + } + if ($theme !== null) + { + $settings['theme'] = $theme; + } + if ($website !== null) + { + $settings['website'] = $website; + } + + // Build the request path. + $path = '/user/settings'; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($settings) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Starred.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Starred.php new file mode 100644 index 000000000..24140662b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Starred.php @@ -0,0 +1,76 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Starred + * + * @since 3.2.0 + */ +class Starred extends Api +{ + /** + * List the repos that the authenticated user has starred. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/starred'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Check whether the authenticated user is starring the repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function check(string $owner, string $repo): string + { + // Build the request path. + $path = "/user/starred/{$owner}/{$repo}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Subscriptions.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Subscriptions.php new file mode 100644 index 000000000..b62780355 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Subscriptions.php @@ -0,0 +1,54 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Subscriptions + * + * @since 3.2.0 + */ +class Subscriptions extends Api +{ + /** + * List repositories watched by the authenticated user. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/subscriptions'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Teams.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Teams.php new file mode 100644 index 000000000..ce3f32be0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Teams.php @@ -0,0 +1,54 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Teams + * + * @since 3.2.0 + */ +class Teams extends Api +{ + /** + * List all the teams a user belongs to. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/teams'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Times.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Times.php new file mode 100644 index 000000000..027405880 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Times.php @@ -0,0 +1,96 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Times + * + * @since 3.2.0 + */ +class Times extends Api +{ + /** + * List the current user's tracked times. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * @param string|null $since Optional. Only show times updated after the given time (RFC 3339 format). + * @param string|null $before Optional. Only show times updated before the given time (RFC 3339 format). + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10, + ?string $since = null, + ?string $before = null + ): ?array + { + // Build the request path. + $path = '/user/times'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + if ($since !== null) + { + $url->setVar('since', $since); + } + + if ($before !== null) + { + $url->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Get list of all existing stopwatches for the authenticated user. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function stopwatches( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/stopwatches'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Tokens.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Tokens.php new file mode 100644 index 000000000..431ba71a7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Tokens.php @@ -0,0 +1,111 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Tokens + * + * @since 3.2.0 + */ +class Tokens extends Api +{ + /** + * List the authenticated user's access tokens. + * + * @param string $username The username of the authenticated user to retrieve access tokens for. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $username, + ?int $page = null, + ?int $limit = null + ): ?array + { + // Build the request path. + $path = "/users/{$username}/tokens"; + + // Build the URL + $url = $this->uri->get($path); + if ($page !== null) + { + $url->setVar('page', $page); + } + if ($limit !== null) + { + $url->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Create an access token for a user. + * + * @param string $username The username of the user to create the access token for. + * @param string $name The name of the access token. + * + * @return object|null + * @since 3.2.0 + **/ + public function create(string $username, string $name): ?object + { + // Build the request path. + $path = "/users/{$username}/tokens"; + + // Set the token data + $data = new \stdClass(); + $data->name = $name; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Delete an access token for a user. + * + * @param string $username The username of the user to delete the access token for. + * @param string $token The token to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $username, string $token): string + { + // Build the request path. + $path = "/users/{$username}/tokens/{$token}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Http.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Http.php new file mode 100644 index 000000000..6c5b3c6e4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Http.php @@ -0,0 +1,98 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Utilities; + + +use Joomla\CMS\Http\Http as JoomlaHttp; +use Joomla\Registry\Registry; + + +/** + * The Gitea Http + * + * @since 3.2.0 + */ +final class Http extends JoomlaHttp +{ + /** + * The token + * + * @var string + * @since 3.2.0 + */ + protected string $_token_; // to avoid collusions (but allow swapping) + + /** + * Constructor. + * + * @param string|null $token The Gitea API token. + * + * @since 3.2.0 + * @throws \InvalidArgumentException + **/ + public function __construct(?string $token) + { + // setup config + $config = [ + 'userAgent' => 'JoomlaGitea/3.0', + 'headers' => [ + 'Content-Type' => 'application/json' + ] + ]; + + // add the token if given + if (is_string($token)) + { + $config['headers']['Authorization'] = 'token ' . $token; + $this->_token_ = $token; + } + + $options = new Registry($config); + + // run parent constructor + parent::__construct($options); + } + + /** + * Change the Token. + * + * @param string $token The Gitea API token. + * + * @since 3.2.0 + **/ + public function setToken(string $token): void + { + // get the current headers + $headers = (array) $this->getOption('headers', [ + 'Content-Type' => 'application/json' + ] + ); + + // add the token + $headers['Authorization'] = 'token ' . $token; + $this->_token_ = $token; + + $this->setOption('headers', $headers); + } + + /** + * Get the Token. + * + * @return string|null + * @since 3.2.0 + **/ + public function getToken(): ?string + { + return $this->_token_ ?? null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Response.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Response.php new file mode 100644 index 000000000..4b3574efb --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Response.php @@ -0,0 +1,146 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Utilities; + + +use Joomla\CMS\Http\Response as JoomlaResponse; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * The Gitea Response + * + * @since 3.2.0 + */ +final class Response +{ + /** + * Process the response and decode it. + * + * @param JoomlaResponse $response The response. + * @param integer $expectedCode The expected "good" code. + * @param mixed $default The default if body not have length + * + * @return mixed + * + * @since 3.2.0 + * @throws \DomainException + **/ + public function get(JoomlaResponse $response, int $expectedCode = 200, $default = null) + { + // Validate the response code. + if ($response->code != $expectedCode) + { + // Decode the error response and throw an exception. + $message = $this->error($response); + + throw new \DomainException("Invalid response received from API. $message", $response->code); + + } + + return $this->body($response, $default); + } + + /** + * Process the response and decode it. (when we have multiple success codes) + * + * @param JoomlaResponse $response The response. + * @param array [$expectedCode => $default] The expected "good" code. and The default if body not have length + * + * @return mixed + * + * @since 3.2.0 + * @throws \DomainException + **/ + public function get_(JoomlaResponse $response, array $validate = [200 => null]) + { + // Validate the response code. + if (!isset($validate[$response->code])) + { + // Decode the error response and throw an exception. + $message = $this->error($response); + + throw new \DomainException("Invalid response received from API. $message", $response->code); + + } + + return $this->body($response, $validate[$response->code]); + } + + /** + * Return the body from the response + * + * @param JoomlaResponse $response The response. + * @param mixed $default The default if body not have length + * + * @return mixed + * @since 3.2.0 + **/ + protected function body(JoomlaResponse $response, $default = null) + { + // check that we have a body and that its JSON + if (isset($response->body) && StringHelper::check($response->body)) + { + if (JsonHelper::check($response->body)) + { + $body = json_decode((string) $response->body); + + if (isset($body->content_base64)) + { + $body->content = base64_decode((string) $body->content_base64); + } + + return $body; + } + + return $response->body; + } + + return $default; + } + + /** + * Get the error message from the return object + * + * @param JoomlaResponse $response The response. + * + * @return string + * @since 3.2.0 + **/ + protected function error(JoomlaResponse $response): string + { + // do we have a json string + if (isset($response->body) && JsonHelper::check($response->body)) + { + $error = json_decode($response->body); + } + else + { + return ''; + } + + // check + if (isset($error->error)) + { + return $error->error; + } + elseif (isset($error->message)) + { + return $error->message; + } + + return ''; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Uri.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Uri.php new file mode 100644 index 000000000..daa3add1e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Uri.php @@ -0,0 +1,150 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Gitea\Utilities; + + +use Joomla\Uri\Uri as JoomlaUri; + + +/** + * The Gitea Uri + * + * @since 3.2.0 + */ +final class Uri +{ + /** + * The api endpoint + * + * @var string + * @since 3.2.0 + */ + private string $endpoint; + + /** + * The api version + * + * @var string + * @since 3.2.0 + */ + private string $version; + + /** + * The api URL + * + * @var string + * @since 3.2.0 + */ + private string $url; + + /** + * Constructor + * + * @param string $url URL to the gitea system + * example: https://git.vdm.dev + * @param string $endpoint Endpoint to the gitea system + * @param string $version Version to the gitea system + * + * @since 3.2.0 + **/ + public function __construct( + string $url = 'https://git.vdm.dev', + string $endpoint = 'api', + string $version = 'v1') + { + // set the API details + $this->setUrl($url); + $this->setEndpoint($endpoint); + $this->setVersion($version); + } + + /** + * Method to build and return a full request URL for the request. This method will + * add appropriate pagination details if necessary and also prepend the API url + * to have a complete URL for the request. + * + * @param string $path URL to inflect + * + * @return JoomlaUri + * @since 3.2.0 + **/ + public function get(string $path): JoomlaUri + { + // Get a new Uri object focusing the api url and given path. + $uri = new JoomlaUri($this->api() . $path); + + return $uri; + } + + /** + * Get the full API URL + * + * @return string + * @since 3.2.0 + **/ + public function api(): string + { + return $this->url . '/' . $this->endpoint . '/' . $this->version; + } + + /** + * Set the URL of the API + * + * @param string $url URL to your gitea system + * example: https://git.vdm.dev + * + * @return void + * @since 3.2.0 + **/ + public function setUrl(string $url) + { + $this->url = $url; + } + + /** + * Get the URL of the API + * + * @return string|null + * @since 3.2.0 + **/ + public function getUrl(): ?string + { + return $this->url ?? null; + } + + /** + * Set the endpoint of the API + * + * @param string $endpoint endpoint to your gitea API + * + * @return void + * @since 3.2.0 + **/ + private function setEndpoint(string $endpoint) + { + $this->endpoint = $endpoint; + } + + /** + * Set the version of the API + * + * @param string $version version to your gitea API + * + * @return void + * @since 3.2.0 + **/ + private function setVersion($version) + { + $this->version = $version; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/index.html b/libraries/jcb_powers/VDM.Joomla.Openai/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Abstraction/Api.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Abstraction/Api.php new file mode 100644 index 000000000..28247068d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Abstraction/Api.php @@ -0,0 +1,67 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai\Abstraction; + + +use VDM\Joomla\Openai\Utilities\Http; +use VDM\Joomla\Openai\Utilities\Uri; +use VDM\Joomla\Openai\Utilities\Response; + + +/** + * The Openai Api + * + * @since 3.2.0 + */ +abstract class Api +{ + /** + * The Http class + * + * @var Http + * @since 3.2.0 + */ + protected Http $http; + + /** + * The Uri class + * + * @var Uri + * @since 3.2.0 + */ + protected Uri $uri; + + /** + * The Response class + * + * @var Response + * @since 3.2.0 + */ + protected Response $response; + + /** + * Constructor. + * + * @param Http $http The http class. + * @param Uri $uri The uri class. + * @param Response $response The response class. + * + * @since 3.2.0 + **/ + public function __construct(Http $http, Uri $uri, Response $response) + { + $this->http = $http; + $this->uri = $uri; + $this->response = $response; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Abstraction/index.html b/libraries/jcb_powers/VDM.Joomla.Openai/src/Abstraction/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Abstraction/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Audio.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Audio.php new file mode 100644 index 000000000..caa17a488 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Audio.php @@ -0,0 +1,138 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Audio + * + * @since 3.2.0 + */ +class Audio extends Api +{ + /** + * Transcribes audio into the input language. + * API Ref: https://platform.openai.com/docs/api-reference/audio/create + * + * @param string $file The audio file to transcribe. Formats: mp3, mp4, mpeg, mpga, m4a, wav, or webm (required). + * @param string|null $prompt An optional text to guide the model's style (optional). + * @param string|null $responseFormat The format of the transcript output. Options: json, text, srt, verbose_json, or vtt (optional). + * @param float|null $temperature The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic (optional). + * @param string|null $language The language of the input audio (optional). + * @param string $model ID of the model to use. Only "whisper-1" is currently available. + * + * @return object|null + * @since 3.2.0 + **/ + public function transcribe( + string $file, + ?string $prompt = null, + ?string $responseFormat = null, + ?float $temperature = null, + ?string $language = null, + string $model = 'whisper-1' + ): ?object + { + // Build the request path. + $path = "/audio/transcriptions"; + + // Set the request data. + $data = new \stdClass(); + $data->file = $file; + + if ($prompt !== null) + { + $data->prompt = $prompt; + } + + if ($responseFormat !== null) + { + $data->response_format = $responseFormat; + } + + if ($temperature !== null) + { + $data->temperature = $temperature; + } + + if ($language !== null) + { + $data->language = $language; + } + + $data->model = $model; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data), ['Content-Type' => 'multipart/form-data'] + ) + ); + } + + /** + * Translate an audio file into English. + * API Ref: https://platform.openai.com/docs/api-reference/audio/create + * + * @param string $file The the audio file. Formats: mp3, mp4, mpeg, mpga, m4a, wav, or webm (required). + * @param string|null $prompt An optional text to guide the model's style or continue a previous audio segment. The prompt should be in English (optional). + * @param string|null $responseFormat The format of the transcript output. Options: json, text, srt, verbose_json, or vtt (optional). + * @param float|null $temperature The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic (optional). + * @param string $model ID of the model to use. Only "whisper-1" is currently available. + * + * @return object|null + * @since 3.2.0 + **/ + public function translation( + string $file, + ?string $prompt = null, + ?string $responseFormat = null, + ?float $temperature = null, + string $model = 'whisper-1' + ): ?object + { + // Build the request path. + $path = "/audio/translations"; + + // Set the data. + $data = new \stdClass(); + $data->file = $file; + + if ($prompt !== null) + { + $data->prompt = $prompt; + } + + if ($responseFormat !== null) + { + $data->response_format = $responseFormat; + } + + if ($temperature !== null) + { + $data->temperature = $temperature; + } + + $data->model = $model; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data), ['Content-Type' => 'multipart/form-data'] + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Chat.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Chat.php new file mode 100644 index 000000000..deb9097a3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Chat.php @@ -0,0 +1,142 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Chat + * + * @since 3.2.0 + */ +class Chat extends Api +{ + /** + * Create a chat completion with the OpenAI API. + * API Ref: https://platform.openai.com/docs/api-reference/chat/create + * + * @param string $model The model to use for completion. + * @param array $messages A list of messages describing the conversation so far. + * + * Each item in the array is an object with the following: + * - role (string) Required + * The role of the author of this message. + * One of system, user, or assistant. + * - content (string) Required + * The contents of the message. + * - name (string) Optional + * The name of the author of this message. + * May contain a-z, A-Z, 0-9, and underscores, + * with a maximum length of 64 characters. + * + * @param int|null $maxTokens Maximum number of tokens to generate (optional). + * @param float|null $temperature The sampling temperature to use (optional). + * @param float|null $topP The nucleus sampling parameter (optional). + * @param int|null $n The number of chat completion choices to generate (optional). + * @param bool|null $stream Partial message deltas (optional). + * @param mixed|null $stop Sequences where the API will stop generating tokens (optional). + * @param float|null $presencePenalty Penalty for new tokens based on whether they appear in the text (optional). + * @param float|null $frequencyPenalty Penalty for new tokens based on their frequency in the text (optional). + * @param array|null $logitBias Modify the likelihood of specified tokens appearing (optional). + * @param string|null $user A unique identifier representing the end-user (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $model, + array $messages, + ?int $maxTokens = null, + ?float $temperature = null, + ?float $topP = null, + ?int $n = null, + ?bool $stream = null, + $stop = null, + ?float $presencePenalty = null, + ?float $frequencyPenalty = null, + ?array $logitBias = null, + ?string $user = null + ): ?object + { + // Build the request path. + $path = "/chat/completions"; + + // Set the request data. + $data = new \stdClass(); + $data->model = $model; + $data->messages = $messages; + + if ($maxTokens !== null) + { + $data->max_tokens = $maxTokens; + } + + if ($temperature !== null) + { + $data->temperature = $temperature; + } + + if ($topP !== null) + { + $data->top_p = $topP; + } + + if ($n !== null) + { + $data->n = $n; + } + + if ($stream !== null) + { + $data->stream = $stream; + } + + if ($stop !== null) + { + $data->stop = $stop; + } + + if ($presencePenalty !== null) + { + $data->presence_penalty = $presencePenalty; + } + + if ($frequencyPenalty !== null) + { + $data->frequency_penalty = $frequencyPenalty; + } + + if ($logitBias !== null) + { + $data->logit_bias = new \stdClass(); + foreach ($logitBias as $key => $val) + { + $data->logit_bias->$key = $val; + } + } + + if ($user !== null) + { + $data->user = $user; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Completions.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Completions.php new file mode 100644 index 000000000..65769df5c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Completions.php @@ -0,0 +1,158 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Completions + * + * @since 3.2.0 + */ +class Completions extends Api +{ + /** + * Create a completion using the OpenAI API. + * API Ref: https://platform.openai.com/docs/api-reference/completions + * + * @param string $model The ID of the model to use. + * @param string|array $prompt The prompt(s) to generate completions for. + * @param int|null $maxTokens The maximum number of tokens to generate (optional). + * @param float|null $temperature The sampling temperature to use (optional). + * @param string $suffix The suffix that comes after a completion of inserted text. (optional). + * @param float|null $topP The top_p value for nucleus sampling (optional). + * @param int|null $n How many completions to generate (optional). + * @param bool|null $stream Whether to stream back partial progress (optional). + * @param int|null $logprobs Include the log probabilities on the most likely tokens (optional). + * @param bool|null $echo Echo back the prompt in addition to the completion (optional). + * @param string|null $stop Up to 4 sequences where the API will stop generating (optional). + * @param float|null $presencePenalty The presence penalty to use (optional). + * @param float|null $frequencyPenalty The frequency penalty to use (optional). + * @param int|null $bestOf Generates best_of completions server-side (optional). + * @param array|null $logitBias Modify the likelihood of specified tokens (optional). + * @param string|null $user A unique identifier representing your end-user (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $model, + $prompt, + ?int $maxTokens = null, + ?string $suffix = null, + ?float $temperature = null, + ?float $topP = null, + ?int $n = null, + ?bool $stream = null, + ?int $logprobs = null, + ?bool $echo = null, + $stop = null, + ?float $presencePenalty = null, + ?float $frequencyPenalty = null, + ?int $bestOf = null, + ?array $logitBias = null, + ?string $user = null + ): ?object + { + // Build the request path. + $path = "/completions"; + + // Set the completion data. + $data = new \stdClass(); + $data->model = $model; + $data->prompt = $prompt; + + if ($maxTokens !== null) + { + $data->max_tokens = $maxTokens; + } + + if ($temperature !== null) + { + $data->temperature = $temperature; + } + + if ($suffix !== null) + { + $data->suffix = $suffix; + } + + if ($topP !== null) + { + $data->top_p = $topP; + } + + if ($n !== null) + { + $data->n = $n; + } + + if ($stream !== null) + { + $data->stream = $stream; + } + + if ($logprobs !== null) + { + $data->logprobs = $logprobs; + } + + if ($echo !== null) + { + $data->echo = $echo; + } + + if ($stop !== null) + { + $data->stop = $stop; + } + + if ($presencePenalty !== null) + { + $data->presence_penalty = $presencePenalty; + } + + if ($frequencyPenalty !== null) + { + $data->frequency_penalty = $frequencyPenalty; + } + + if ($bestOf !== null) + { + $data->best_of = $bestOf; + } + + if ($logitBias !== null) + { + $data->logit_bias = new \stdClass(); + foreach ($logitBias as $key => $val) + { + $data->logit_bias->$key = $val; + } + } + + if ($user !== null) + { + $data->user = $user; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Edits.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Edits.php new file mode 100644 index 000000000..46731fe43 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Edits.php @@ -0,0 +1,84 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Edits + * + * @since 3.2.0 + */ +class Edits extends Api +{ + /** + * Create a new edit using OpenAI Edit API. + * API Ref: https://platform.openai.com/docs/api-reference/edits + * + * @param string $model The model to use. + * @param string $instruction The instruction for the edit. + * @param string|null $input The input text (optional). + * @param int|null $n How many edits to generate (optional). + * @param float|null $temperature The sampling temperature (optional). + * @param float|null $topP Nucleus sampling parameter (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $model, + string $instruction, + ?string $input = null, + ?int $n = null, + ?float $temperature = null, + ?float $topP = null + ): ?object + { + // Build the request path. + $path = "/edits"; + + // Set the data. + $data = new \stdClass(); + $data->model = $model; + $data->instruction = $instruction; + + if ($input !== null) + { + $data->input = $input; + } + + if ($n !== null) + { + $data->n = $n; + } + + if ($temperature !== null) + { + $data->temperature = $temperature; + } + + if ($topP !== null) + { + $data->top_p = $topP; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Embeddings.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Embeddings.php new file mode 100644 index 000000000..fb0e10304 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Embeddings.php @@ -0,0 +1,63 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Embeddings + * + * @since 3.2.0 + */ +class Embeddings extends Api +{ + /** + * Create an embedding of a given input. + * API Ref: https://platform.openai.com/docs/api-reference/embeddings + * + * @param string $model The ID of the model to use. + * @param mixed $input The input text to get embeddings for, encoded as a string or array of tokens. + * @param string|null $user A unique identifier representing your end-user (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $model, + $input, + ?string $user = null + ): ?object + { + // Build the request path. + $path = "/embeddings"; + + // Set the request data. + $data = new \stdClass(); + $data->model = $model; + $data->input = $input; + + if ($user !== null) + { + $data->user = $user; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Factory.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Factory.php new file mode 100644 index 000000000..246a934e2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Factory.php @@ -0,0 +1,78 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use Joomla\DI\Container; +use VDM\Joomla\Openai\Service\Api; +use VDM\Joomla\Openai\Service\Utilities; +use VDM\Joomla\Interfaces\FactoryInterface; + + +/** + * Openai Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Package Container + * + * @var Container + * @since 3.2.0 + **/ + protected static $container = null; + + /** + * Get any class from the package container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _($key) + { + return self::getContainer()->get($key); + } + + /** + * Get the global package container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Utilities()) + ->registerServiceProvider(new Api()); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Files.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Files.php new file mode 100644 index 000000000..1d0f8a2b3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Files.php @@ -0,0 +1,140 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Files + * + * @since 3.2.0 + */ +class Files extends Api +{ + /** + * Fetches a list of files belonging to the user's organization. + * API Ref: https://platform.openai.com/docs/api-reference/files/list + * + * @return object|null The response from the OpenAI API, or null if an error occurred. + * @since 3.2.0 + */ + public function list(): ?object + { + // Build the request path. + $path = "/files"; + + // Prepare the URI. + $uri = $this->uri->get($path); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Upload a file that contains document(s) to be used across various endpoints/features. + * API Ref: https://platform.openai.com/docs/api-reference/files/upload + * + * @param string $file The file to upload. + * @param string $purpose The intended purpose of the uploaded documents. + * + * @return object|null + * @since 3.2.0 + **/ + public function upload(string $file, string $purpose): ?object + { + // Build the request path. + $path = "/files"; + + // Set the request data. + $data = new \stdClass(); + $data->file = $file; + $data->purpose = $purpose; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Returns information about a specific file. + * API Ref: https://platform.openai.com/docs/api-reference/files/retrieve + * + * @param string $fileID The file id to retrieve info + * + * @return object|null + * @since 3.2.0 + **/ + public function info(string $fileID): ?object + { + // Build the request path. + $path = "/files/{$fileID}"; + + // Send the post request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Retrieve a specific file content. + * API Ref: https://platform.openai.com/docs/api-reference/files/retrieve-content + * + * @param string $fileID The file id to retrieve content + * + * @return mixed + * @since 3.2.0 + **/ + public function content(string $fileID) + { + // Build the request path. + $path = "/files/{$fileID}/content"; + + // Send the post request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a file. + * API Ref: https://platform.openai.com/docs/api-reference/files/delete + * + * @param string $fileID The file id to delete + * + * @return object|null + * @since 3.2.0 + **/ + public function delete(string $fileID): ?object + { + // Build the request path. + $path = "/files/{$fileID}"; + + // Send the post request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/FineTunes.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/FineTunes.php new file mode 100644 index 000000000..af160ee26 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/FineTunes.php @@ -0,0 +1,50 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Fine Tunes + * + * @since 3.2.0 + */ +class FineTunes extends Api +{ + /** + * List your organization's fine-tuning jobs + * API Ref: https://platform.openai.com/docs/api-reference/fine-tunes/list + * + * @return object|null The response from the OpenAI API, or null if an error occurred. + * @since 3.2.0 + */ + public function list(): ?object + { + // Build the request path. + $path = "/fine-tunes"; + + // Prepare the URI. + $uri = $this->uri->get($path); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * More to follow: https://platform.openai.com/docs/api-reference/fine-tunes + **/ +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Images.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Images.php new file mode 100644 index 000000000..455ba1e97 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Images.php @@ -0,0 +1,203 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Images + * + * @since 3.2.0 + */ +class Images extends Api +{ + /** + * Generate an image given a text prompt. + * API Ref: https://platform.openai.com/docs/api-reference/images/create + * + * @param string $prompt The text description of the desired image(s). + * @param string|null $size The size of the generated images (optional). + * @param string|null $responseFormat The format in which the images are returned (optional). + * @param int|null $n The number of images to generate (optional). + * @param string|null $user A unique identifier representing the end-user (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function generate( + string $prompt, + ?string $size = null, + ?string $responseFormat = null, + ?int $n = null, + ?string $user = null + ): ?object + { + // Build the request path. + $path = "/images/generations"; + + // Set the request data. + $data = new \stdClass(); + $data->prompt = $prompt; + + if ($size !== null) + { + $data->size = $size; + } + + if ($responseFormat !== null) + { + $data->response_format = $responseFormat; + } + + if ($n !== null) + { + $data->n = $n; + } + + if ($user !== null) + { + $data->user = $user; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Create an image edit with extended options. + * API Ref: https://platform.openai.com/docs/api-reference/images/create-edit + * + * @param string $image The original image to edit. Must be a valid PNG file, less than 4MB, and square. + * @param string|null $mask An additional image for editing (optional). + * @param string $prompt A text description of the desired image(s). + * @param string|null $size The size of the generated images (optional). + * @param string|null $responseFormat The format in which the images are returned (optional). + * @param int|null $n The number of images to generate (optional). + * @param string|null $user A unique identifier representing your end-user (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $image, + string $prompt, + ?string $mask = null, + ?string $size = null, + ?string $responseFormat = null, + ?int $n = null, + ?string $user = null + ): ?object + { + // Build the request path. + $path = "/images/edits"; + + // Set the image edit data. + $data = new \stdClass(); + $data->image = $image; + $data->prompt = $prompt; + + if ($mask !== null) + { + $data->mask = $mask; + } + + if ($size !== null) + { + $data->size = $size; + } + + if ($responseFormat !== null) + { + $data->response_format = $responseFormat; + } + + if ($n !== null) + { + $data->n = $n; + } + + if ($user !== null) + { + $data->user = $user; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Create a variation of a given image. + * API Ref: https://platform.openai.com/docs/api-reference/images/create-variation + * + * @param string $image The image to use as the basis for the variation(s). + * @param string|null $size The size of the generated images (optional). + * @param string|null $responseFormat The format in which the generated images are returned (optional). + * @param int|null $n The number of images to generate (optional). + * @param string|null $user A unique identifier representing your end-user (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function variation( + string $image, + ?string $size = null, + ?string $responseFormat = null, + ?int $n = null, + ?string $user = null + ): ?object + { + // Build the request path. + $path = "/images/variations"; + + // Set the image variation data. + $data = new \stdClass(); + $data->image = $image; + + if ($size !== null) + { + $data->size = $size; + } + + if ($responseFormat !== null) + { + $data->response_format = $responseFormat; + } + + if ($n !== null) + { + $data->n = $n; + } + + if ($user !== null) + { + $data->user = $user; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Models.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Models.php new file mode 100644 index 000000000..034cdd326 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Models.php @@ -0,0 +1,44 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Models + * + * @since 3.2.0 + */ +class Models extends Api +{ + /** + * List the available models from OpenAI API. + * + * @return object|null + * @since 3.2.0 + **/ + public function list(): ?object + { + // Build the request path. + $path = "/models"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Moderate.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Moderate.php new file mode 100644 index 000000000..5f0289640 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Moderate.php @@ -0,0 +1,60 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai; + + +use VDM\Joomla\Openai\Abstraction\Api; + + +/** + * The Openai Moderate + * + * @since 3.2.0 + */ +class Moderate extends Api +{ + /** + * Classify if text violates OpenAI's Content Policy. + * API Ref: https://platform.openai.com/docs/api-reference/moderations/create + * + * @param string|array $input The input text to classify. + * @param string|null $model The moderation model (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function text( + $input, + ?string $model = null + ): ?object + { + // Build the request path. + $path = "/moderations"; + + // Set the moderation data. + $data = new \stdClass(); + $data->input = $input; + + if ($model !== null) + { + $data->model = $model; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/Api.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/Api.php new file mode 100644 index 000000000..ef386f890 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/Api.php @@ -0,0 +1,247 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Openai\Audio; +use VDM\Joomla\Openai\Chat; +use VDM\Joomla\Openai\Completions; +use VDM\Joomla\Openai\Edits; +use VDM\Joomla\Openai\Embeddings; +use VDM\Joomla\Openai\Files; +use VDM\Joomla\Openai\FineTunes; +use VDM\Joomla\Openai\Images; +use VDM\Joomla\Openai\Models; +use VDM\Joomla\Openai\Moderate; + + +/** + * The Openai Api Service + * + * @since 3.2.0 + */ +class Api implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Audio::class, 'Openai.Audio') + ->share('Openai.Audio', [$this, 'getAudio'], true); + + $container->alias(Chat::class, 'Openai.Chat') + ->share('Openai.Chat', [$this, 'getChat'], true); + + $container->alias(Completions::class, 'Openai.Completions') + ->share('Openai.Completions', [$this, 'getCompletions'], true); + + $container->alias(Edits::class, 'Openai.Edits') + ->share('Openai.Edits', [$this, 'getEdits'], true); + + $container->alias(Embeddings::class, 'Openai.Embeddings') + ->share('Openai.Embeddings', [$this, 'getEmbeddings'], true); + + $container->alias(Files::class, 'Openai.Files') + ->share('Openai.Files', [$this, 'getFiles'], true); + + $container->alias(FineTunes::class, 'Openai.FineTunes') + ->share('Openai.FineTunes', [$this, 'getFineTunes'], true); + + $container->alias(Images::class, 'Openai.Images') + ->share('Openai.Images', [$this, 'getImages'], true); + + $container->alias(Models::class, 'Openai.Models') + ->share('Openai.Models', [$this, 'getModels'], true); + + $container->alias(Moderate::class, 'Openai.Moderate') + ->share('Openai.Moderate', [$this, 'getModerate'], true); + } + + /** + * Get the Audio class + * + * @param Container $container The DI container. + * + * @return Audio + * @since 3.2.0 + */ + public function getAudio(Container $container): Audio + { + return new Audio( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Chat class + * + * @param Container $container The DI container. + * + * @return Chat + * @since 3.2.0 + */ + public function getChat(Container $container): Chat + { + return new Chat( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Completions class + * + * @param Container $container The DI container. + * + * @return Completions + * @since 3.2.0 + */ + public function getCompletions(Container $container): Completions + { + return new Completions( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Edits class + * + * @param Container $container The DI container. + * + * @return Edits + * @since 3.2.0 + */ + public function getEdits(Container $container): Edits + { + return new Edits( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Embeddings class + * + * @param Container $container The DI container. + * + * @return Embeddings + * @since 3.2.0 + */ + public function getEmbeddings(Container $container): Embeddings + { + return new Embeddings( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Files class + * + * @param Container $container The DI container. + * + * @return Files + * @since 3.2.0 + */ + public function getFiles(Container $container): Files + { + return new Files( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the FineTunes class + * + * @param Container $container The DI container. + * + * @return FineTunes + * @since 3.2.0 + */ + public function getFineTunes(Container $container): FineTunes + { + return new FineTunes( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Images class + * + * @param Container $container The DI container. + * + * @return Images + * @since 3.2.0 + */ + public function getImages(Container $container): Images + { + return new Images( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Models class + * + * @param Container $container The DI container. + * + * @return Models + * @since 3.2.0 + */ + public function getModels(Container $container): Models + { + return new Models( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } + + /** + * Get the Moderate class + * + * @param Container $container The DI container. + * + * @return Moderate + * @since 3.2.0 + */ + public function getModerate(Container $container): Moderate + { + return new Moderate( + $container->get('Openai.Utilities.Http'), + $container->get('Openai.Utilities.Uri'), + $container->get('Openai.Utilities.Response') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/Utilities.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/Utilities.php new file mode 100644 index 000000000..b7f6a4c51 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/Utilities.php @@ -0,0 +1,113 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Openai\Utilities\Uri; +use VDM\Joomla\Openai\Utilities\Response; +use VDM\Joomla\Openai\Utilities\Http; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * The Openai Utilities Service + * + * @since 3.2.0 + */ +class Utilities implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Openai.Utilities.Uri') + ->share('Openai.Utilities.Uri', [$this, 'getUri'], true); + + $container->alias(Response::class, 'Openai.Utilities.Response') + ->share('Openai.Utilities.Response', [$this, 'getResponse'], true); + + $container->alias(Http::class, 'Openai.Utilities.Http') + ->share('Openai.Utilities.Http', [$this, 'getHttp'], true); + } + + /** + * Get the Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + return new Uri(); + } + + /** + * Get the Response class + * + * @param Container $container The DI container. + * + * @return Response + * @since 3.2.0 + */ + public function getResponse(Container $container): Response + { + return new Response(); + } + + /** + * Get the Http class + * + * @param Container $container The DI container. + * + * @return Http + * @since 3.2.0 + */ + public function getHttp(Container $container): Http + { + $openai_token = null; + $openai_org_token = null; + if (Helper::getParams()->get('enable_open_ai') == 1) + { + $openai_token = Helper::getParams()->get('openai_token'); + if (Helper::getParams()->get('enable_open_ai_org') == 1) + { + $openai_org_token = Helper::getParams()->get('openai_org_token'); + } + + if ($openai_token === 'secret') + { + $openai_token = null; + } + + if ($openai_org_token === 'secret') + { + $openai_org_token = null; + } + } + + return new Http( + $openai_token, + $openai_org_token + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/index.html b/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Http.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Http.php new file mode 100644 index 000000000..6d0b705c6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Http.php @@ -0,0 +1,139 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai\Utilities; + + +use Joomla\CMS\Http\Http as JoomlaHttp; +use Joomla\Registry\Registry; + + +/** + * The Openai Http + * + * @since 3.2.0 + */ +final class Http extends JoomlaHttp +{ + /** + * The default Header + * + * @var array + * @since 3.2.0 + */ + protected array $defaultHeaders = ['Content-Type' => 'application/json']; + + /** + * Constructor. + * + * @param string|null $token The Openai API token. + * @param string|null $orgToken The Openai API Organization token. + * + * @since 3.2.0 + * @throws \InvalidArgumentException + **/ + public function __construct(?string $token, ?string $orgToken = null) + { + // add the token if given + if (is_string($token)) + { + $this->defaultHeaders['Authorization'] = 'Bearer ' . $token; + } + + // add the organization token if given + if (is_string($orgToken)) + { + $this->defaultHeaders['OpenAI-Organization'] = $orgToken; + } + + // setup config + $config = [ + 'userAgent' => 'JoomlaOpenai/3.0', + 'headers' => $this->defaultHeaders + ]; + + $options = new Registry($config); + + // run parent constructor + parent::__construct($options); + } + + /** + * Change the Tokens. + * + * @param string|null $token The Openai API token. + * @param string|null $orgToken The Openai API Organization token. + * + * @since 3.2.0 + **/ + public function setTokens(?string $token = null, ?string $orgToken = null) + { + // get the current headers + $this->defaultHeaders = (array) $this->getOption('headers', + $this->defaultHeaders + ); + + // add the token if given + if (is_string($token)) + { + $this->defaultHeaders['Authorization'] = 'Bearer ' . $token; + } + + // add the organization token if given + if (is_string($orgToken)) + { + $this->defaultHeaders['OpenAI-Organization'] = $orgToken; + } + + $this->setOption('headers', $this->defaultHeaders); + } + + /** + * Change the User Token. + * + * @param string $token The API token. + * + * @since 3.2.0 + **/ + public function setToken(string $token) + { + // get the current headers + $this->defaultHeaders = (array) $this->getOption('headers', + $this->defaultHeaders + ); + + // add the token + $this->defaultHeaders['Authorization'] = 'Bearer ' . $token; + + $this->setOption('headers', $this->defaultHeaders); + } + + /** + * Change the Organization Token. + * + * @param string $token The Organization API token. + * + * @since 3.2.0 + **/ + public function setOrgToken(string $token) + { + // get the current headers + $this->defaultHeaders = (array) $this->getOption('headers', + $this->defaultHeader + ); + + // add the token + $this->defaultHeaders['OpenAI-Organization'] = $token; + + $this->setOption('headers', $this->defaultHeaders); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Response.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Response.php new file mode 100644 index 000000000..b07d31d96 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Response.php @@ -0,0 +1,140 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai\Utilities; + + +use Joomla\CMS\Http\Response as JoomlaResponse; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * The Openai Response + * + * @since 3.2.0 + */ +final class Response +{ + /** + * Process the response and decode it. + * + * @param JoomlaResponse $response The response. + * @param integer $expectedCode The expected "good" code. + * @param mixed $default The default if body not have length + * + * @return mixed + * + * @since 3.2.0 + * @throws \DomainException + **/ + public function get(JoomlaResponse $response, int $expectedCode = 200, $default = null) + { + // Validate the response code. + if ($response->code != $expectedCode) + { + // Decode the error response and throw an exception. + $message = $this->error($response); + + // Throw an exception with the OpenAI error message and code. + throw new \DomainException($message, $response->code); + } + + return $this->body($response, $default); + } + + /** + * Process the response and decode it. (when we have multiple success codes) + * + * @param JoomlaResponse $response The response. + * @param array [$expectedCode => $default] The expected "good" code. and The default if body not have length + * + * @return mixed + * + * @since 3.2.0 + * @throws \DomainException + **/ + public function get_(JoomlaResponse $response, array $validate = [200 => null]) + { + // Validate the response code. + if (!isset($validate[$response->code])) + { + // Decode the error response and throw an exception. + $message = $this->error($response); + + // Throw an exception with the OpenAI error message and code. + throw new \DomainException($message, $response->code); + + } + + return $this->body($response, $validate[$response->code]); + } + + /** + * Return the body from the response + * + * @param JoomlaResponse $response The response. + * @param mixed $default The default if body not have length + * + * @return mixed + * @since 3.2.0 + **/ + protected function body(JoomlaResponse $response, $default = null) + { + // check that we have a body and that its JSON + if (isset($response->body) && StringHelper::check($response->body)) + { + if (JsonHelper::check($response->body)) + { + return json_decode((string) $response->body); + } + + return $response->body; + } + + return $default; + } + + /** + * Get the error message from the OpenAI API response + * + * @param JoomlaResponse $response The response. + * + * @return string + * @since 3.2.0 + **/ + protected function error(JoomlaResponse $response): string + { + // do we have a json string + if (isset($response->body) && JsonHelper::check($response->body)) + { + $error = json_decode($response->body); + } + else + { + return 'Invalid or empty response body.'; + } + + // check if OpenAI returned an error object + if (isset($error->error)) + { + // error object found, extract message and code + $errorMessage = isset($error->error->message) ? $error->error->message : 'Unknown error.'; + $errorCode = isset($error->error->code) ? $error->error->code : 'Unknown error code.'; + + // return formatted error message + return 'OpenAI Error: ' . $errorMessage . ' Code: ' . $errorCode; + } + + return 'No error information found in response.'; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Uri.php b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Uri.php new file mode 100644 index 000000000..ceeb5cd96 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/Uri.php @@ -0,0 +1,115 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Openai\Utilities; + + +use Joomla\Uri\Uri as JoomlaUri; + + +/** + * The Openai Uri + * + * @since 3.2.0 + */ +final class Uri +{ + /** + * The api version + * + * @var string + * @since 3.2.0 + */ + private string $version; + + /** + * The api URL + * + * @var string + * @since 3.2.0 + */ + private string $url; + + /** + * Constructor + * + * @param string $url URL to the openai system + * example: https://api.openai.com + * @param string $version Version to the openai system + * + * @since 3.2.0 + **/ + public function __construct( + string $url = 'https://api.openai.com', + string $version = 'v1') + { + // set the API details + $this->setUrl($url); + $this->setVersion($version); + } + + /** + * Method to build and return a full request URL for the request. This method will + * add appropriate pagination details if necessary and also prepend the API url + * to have a complete URL for the request. + * + * @param string $path URL to inflect + * + * @return JoomlaUri + * @since 3.2.0 + **/ + public function get(string $path): JoomlaUri + { + // Get a new Uri object focusing the api url and given path. + $uri = new JoomlaUri($this->api() . $path); + + return $uri; + } + + /** + * Get the full API URL + * + * @return string + * @since 3.2.0 + **/ + public function api(): string + { + return $this->url . '/' . $this->version; + } + + /** + * Set the URL of the API + * + * @param string $url URL to your openai system + * example: https://api.openai.com + * + * @return void + * @since 3.2.0 + **/ + private function setUrl(string $url) + { + return $this->url = $url; + } + + /** + * Set the version of the API + * + * @param string $version version to your openai API + * + * @return void + * @since 3.2.0 + **/ + private function setVersion($version) + { + return $this->version = $version; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/index.html b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/Utilities/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Openai/src/index.html b/libraries/jcb_powers/VDM.Joomla.Openai/src/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Openai/src/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/ActiveRegistry.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/ActiveRegistry.php new file mode 100644 index 000000000..0eeb531d3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/ActiveRegistry.php @@ -0,0 +1,272 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction; + + +use VDM\Joomla\Interfaces\Activeregistryinterface; + + +/** + * Active Storage Registry. + * + * Don't use this beyond 10 dimensional depth for best performance. + * + * @since 3.2.0 + */ +abstract class ActiveRegistry implements Activeregistryinterface +{ + /** + * The registry array. + * + * @var array + * @since 3.2.0 + **/ + protected array $active = []; + + /** + * Check if the registry has any content. + * + * @return bool Returns true if the active array is not empty, false otherwise. + * @since 3.2.0 + */ + public function isActive(): bool + { + return !empty($this->active); + } + + /** + * Get all value from the active registry. + * + * @return array The values or empty array. + * @since 3.2.0 + */ + public function allActive(): array + { + return $this->active; + } + + /** + * Sets a value into the registry using multiple keys. + * + * @param mixed $value The value to set. + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return void + * @since 3.2.0 + */ + public function setActive($value, string ...$keys): void + { + if (!$this->validActiveKeys($keys)) + { + throw new \InvalidArgumentException("Keys must only be strings or numbers to set any value."); + } + + $array = &$this->active; + + foreach ($keys as $key) + { + if (!isset($array[$key])) + { + if (!is_array($array)) + { + $path = '[' . implode('][', $keys) . ']'; + throw new \InvalidArgumentException("Attempted to use key '{$key}' on a non-array value: {$array}. Path: {$path} Value: {$value}"); + } + + $array[$key] = []; + } + $array = &$array[$key]; + } + + $array = $value; + } + + /** + * Adds content into the registry. If a key exists, + * it either appends or concatenates based on the value's type. + * + * @param mixed $value The value to set. + * @param bool $asArray Determines if the new value should be treated as an array. + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return void + * @since 3.2.0 + */ + public function addActive($value, bool $asArray, string ...$keys): void + { + if (!$this->validActiveKeys($keys)) + { + throw new \InvalidArgumentException("Keys must only be strings or numbers to add any value."); + } + + $array = &$this->active; + + foreach ($keys as $key) + { + if (!isset($array[$key])) + { + if (!is_array($array)) + { + $path = '[' . implode('][', $keys) . ']'; + throw new \InvalidArgumentException("Attempted to use key '{$key}' on a non-array value: {$array}. Path: {$path} Value: {$value}"); + } + + $array[$key] = []; + } + $array = &$array[$key]; + } + + // add string + if (!$asArray && $array === []) + { + $array = ''; + } + + // Handle the adding logic at the tip of the array + if (is_array($array) || $asArray) + { + if (!is_array($array)) + { + // Convert to array if it's not already an array + $array = [$array]; + } + $array[] = $value; + } + else + { + if (is_string($value) || is_numeric($value)) + { + $array .= (string) $value; + } + else + { + $array = $value; + } + } + } + + /** + * Retrieves a value (or sub-array) from the registry using multiple keys. + * + * @param mixed $default The default value if not set. + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return mixed The value or sub-array from the storage. Null if the location doesn't exist. + * @since 3.2.0 + */ + public function getActive($default, string ...$keys) + { + if (!$this->validActiveKeys($keys)) + { + throw new \InvalidArgumentException("Keys must only be strings or numbers to get any value."); + } + + $array = $this->active; + + foreach ($keys as $key) + { + if (!isset($array[$key])) + { + return $default; + } + $array = $array[$key]; + } + + return $array; + } + + /** + * Removes a value (or sub-array) from the registry using multiple keys. + * + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return void + * @since 3.2.0 + */ + public function removeActive(string ...$keys): void + { + if (!$this->validActiveKeys($keys)) + { + throw new \InvalidArgumentException("Keys must only be strings or numbers to remove any value."); + } + + $array = &$this->active; + $lastKey = array_pop($keys); + + foreach ($keys as $key) + { + if (!isset($array[$key])) + { + return; // Exit early if the key doesn't exist + } + $array = &$array[$key]; + } + + unset($array[$lastKey]); + } + + /** + * Checks the existence of a particular location in the registry using multiple keys. + * + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return bool True if the location exists, false otherwise. + * @since 3.2.0 + */ + public function existsActive(string ...$keys): bool + { + if (!$this->validActiveKeys($keys)) + { + throw new \InvalidArgumentException("Keys must only be strings or numbers to check if any value exist."); + } + + $array = $this->active; + + foreach ($keys as $key) + { + if (!isset($array[$key])) + { + return false; + } + $array = $array[$key]; + } + + return true; + } + + /** + * Checks that the keys are valid + * + * @param array $keys The keys to determine the location. + * + * @return bool False if any of the keys are not a number or string. + * @since 3.2.0 + */ + protected function validActiveKeys(array $keys): bool + { + foreach ($keys as $key) + { + if ($key === '' || (!is_string($key) && !is_numeric($key))) + { + return false; + } + } + + return true; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/BaseConfig.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/BaseConfig.php new file mode 100644 index 000000000..fbd3c09ab --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/BaseConfig.php @@ -0,0 +1,122 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction; + + +use Joomla\Registry\Registry as JoomlaRegistry; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; + + +/** + * Config + * + * @since 3.2.0 + */ +abstract class BaseConfig extends JoomlaRegistry +{ + /** + * Constructor + * + * @since 3.2.0 + */ + public function __construct() + { + // Instantiate the internal data object. + $this->data = new \stdClass(); + } + + /** + * setting any config value + * + * @param string $key The value's key/path name + * @param mixed $value Optional default value, returned if the internal value is null. + * + * @since 3.2.0 + */ + public function __set(string $key, $value) + { + $this->set($key, $value); + } + + /** + * getting any valid value + * + * @param string $key The value's key/path name + * + * @since 3.2.0 + * @throws \InvalidArgumentException If $key is not a valid function name. + */ + public function __get(string $key) + { + // check if it has been set + if (($value = $this->get($key, '__N0T_S3T_Y3T_')) !== '__N0T_S3T_Y3T_') + { + return $value; + } + + throw new \InvalidArgumentException(sprintf('Argument %s could not be found as function or path.', $key)); + } + + /** + * Get a config value. + * + * @param string $path Registry path (e.g. joomla_content_showauthor) + * @param mixed $default Optional default value, returned if the internal value is null. + * + * @return mixed Value of entry or null + * + * @since 3.2.0 + */ + public function get($path, $default = null) + { + // function name with no underscores + $method = 'get' . ucfirst((string) ClassfunctionHelper::safe(str_replace('_', '', $path))); + + // check if it has been set + if (($value = parent::get($path, '__N0T_S3T_Y3T_')) !== '__N0T_S3T_Y3T_') + { + return $value; + } + elseif (method_exists($this, $method)) + { + $value = $this->{$method}($default); + + $this->set($path, $value); + + return $value; + } + + return $default; + } + + /** + * Append value to a path in registry of an array + * + * @param string $path Parent registry Path (e.g. joomla.content.showauthor) + * @param mixed $value Value of entry + * + * @return mixed The value of the that has been set. + * + * @since 3.2.0 + */ + public function appendArray(string $path, $value) + { + // check if it does not exist + if (!$this->exists($path)) + { + $this->set($path, []); + } + + return $this->append($path, $value); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/BaseTable.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/BaseTable.php new file mode 100644 index 000000000..468645b1f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/BaseTable.php @@ -0,0 +1,364 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction; + + +use VDM\Joomla\Interfaces\Tableinterface; + + +/** + * Base Table + * + * @since 3.2.0 + */ +abstract class BaseTable implements Tableinterface +{ + /** + * All areas/views/tables with their field details + * + * @var array + * @since 3.2.0 + **/ + protected array $tables; + + /** + * All default fields + * + * @var array + * @since 3.2.0 + **/ + protected array $defaults = [ + 'id' => [ + 'order' => -1, + 'name' => 'id', + 'label' => 'ID', + 'type' => 'text', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'ordering' => [ + 'name' => 'ordering', + 'label' => 'Ordering', + 'type' => 'number', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'published' => [ + 'name' => 'published', + 'label' => 'Status', + 'type' => 'list', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'modified_by' => [ + 'name' => 'modified_by', + 'label' => 'Modified by', + 'type' => 'user', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'modified' => [ + 'name' => 'modified', + 'label' => 'Modified', + 'type' => 'calendar', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'created_by' => [ + 'name' => 'created_by', + 'label' => 'Created by', + 'type' => 'user', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'created' => [ + 'name' => 'created', + 'label' => 'Created', + 'type' => 'calendar', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'hits' => [ + 'name' => 'hits', + 'label' => 'Hits', + 'type' => 'number', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ], + 'version' => [ + 'name' => 'version', + 'label' => 'Version', + 'type' => 'text', + 'title' => false, + 'list' => NULL, + 'store' => NULL, + 'tab_name' => NULL + ] + ]; + + /** + * Get any value from a item/field/column of an area/view/table + * Example: $this->get('table_name', 'field_name', 'value_key'); + * Get an item/field/column of an area/view/table + * Example: $this->get('table_name', 'field_name'); + * Get all items/fields/columns of an area/view/table + * Example: $this->get('table_name'); + * Get all areas/views/tables with all their item/field/column details + * Example: $this->get('All'); + * + * @param string $table The table + * @param string|null $field The field + * @param string|null $key The value key + * + * @return mixed + * @since 3.2.0 + */ + public function get(string $table, ?string $field = null, ?string $key = null) + { + // return the item/field/column of an area/view/table + if (is_string($field) && is_string($key)) + { + // return the value of a item/field/column of an area/view/table + if (isset($this->tables[$table][$field][$key])) + { + return $this->tables[$table][$field][$key]; + } + + return $this->getDefaultKey($field, $key); + } + // return the item/field/column of an area/view/table + elseif (is_string($field)) + { + if (isset($this->tables[$table][$field])) + { + return $this->tables[$table][$field]; + } + + return $this->getDefault($field); + } + // return an area/view/table + elseif ($table !== 'All') + { + if (isset($this->tables[$table])) + { + return $this->tables[$table]; + } + return null; + } + + // return all + return $this->tables; + } + + /** + * Get title field from an area/view/table + * + * @param string $table The area + * + * @return ?array + * @since 3.2.0 + */ + public function title(string $table): ?array + { + // return the title item/field/column of an area/view/table + if (($table = $this->get($table)) !== null) + { + foreach ($table as $item) + { + if ($item['title']) + { + return $item; + } + } + } + + // none found + return null; + } + + /** + * Get title field name + * + * @param string $table The area + * + * @return string + * @since 3.2.0 + */ + public function titleName(string $table): string + { + // return the title name of an area/view/table + if (($field = $this->title($table)) !== null) + { + return $field['name']; + } + + // none found default to ID + return 'id'; + } + + /** + * Get all tables + * + * @return array + * @since 3.2.0 + */ + public function tables(): array + { + // return all areas/views/tables + return array_keys($this->tables); + } + + /** + * Check if a table (and field) exist + * + * @param string $table The area + * @param string|null $field The area + * + * @return bool + * @since 3.2.0 + */ + public function exist(string $table, ?string $field = null): bool + { + if (isset($this->tables[$table])) + { + // if we have a field + if (is_string($field)) + { + if (isset($this->tables[$table][$field])) + { + return true; + } + } + else + { + return true; + } + } + + return $this->isDefault($field); + } + + /** + * Get all fields of an area/view/table + * + * @param string $table The area + * @param bool $default Add the default fields + * + * @return array|null On success an array of fields + * @since 3.2.0 + */ + public function fields(string $table, bool $default = false): ?array + { + // return all fields of an area/view/table + if (($table = $this->get($table)) !== null) + { + if ($default) + { + return $this->addDefault(array_keys($table)); + } + else + { + return array_keys($table); + } + } + + // none found + return null; + } + + /** + * Add the default fields + * + * @param array $fields The table dynamic fields + * + * @return array Fields (with defaults added) + * @since 3.2.0 + */ + protected function addDefault(array $fields): array + { + // add default fields + foreach ($this->defaults as $default) + { + // used just for loading the fields + $order = $default['order'] ?? 1; + unset($default['order']); + + if ($order < 0) + { + array_unshift($fields, $default['name']); + } + else + { + $fields[] = $default['name']; + } + } + + return $fields; + } + + /** + * Check if the field is a default field + * + * @param string $field The field to check + * + * @return bool True if a default field + * @since 3.2.0 + */ + protected function isDefault(string $field): bool + { + return isset($this->defaults[$field]); + } + + /** + * Get a default field + * + * @param string $field The field to check + * + * @return array|null True if a default field + * @since 3.2.0 + */ + protected function getDefault(string $field): ?array + { + return $this->defaults[$field] ?? null; + } + + /** + * Get a default field property + * + * @param string $field The field to check + * @param string $key The field key/property to check + * + * @return string|null String value if a default field property exist + * @since 3.2.0 + */ + protected function getDefaultKey(string $field, string $key): ?string + { + return $this->defaults[$field][$key] ?? null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Database.php new file mode 100644 index 000000000..f615e709e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Database.php @@ -0,0 +1,118 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction; + + +use Joomla\CMS\Factory as JoomlaFactory; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * Database + * + * @since 3.2.0 + */ +abstract class Database +{ + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + */ + protected \JDatabaseDriver $db; + + /** + * Core Component Table Name + * + * @var string + * @since 3.2.0 + */ + protected string $table; + + /** + * Constructor + * + * @param \JDatabaseDriver|null $db The database driver + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?\JDatabaseDriver $db = null) + { + $this->db = $db ?: JoomlaFactory::getDbo(); + + // set the component table + $this->table = '#__' . Helper::getCode(); + } + + /** + * Set a value based on data type + * + * @param mixed $value The value to set + * + * @return mixed + * @since 3.2.0 + **/ + protected function quote($value) + { + if ($value === null) // hmm the null does pose an issue (will keep an eye on this) + { + return 'NULL'; + } + + if (is_numeric($value)) + { + if (filter_var($value, FILTER_VALIDATE_INT)) + { + return (int) $value; + } + elseif (filter_var($value, FILTER_VALIDATE_FLOAT)) + { + return (float) $value; + } + } + elseif (is_bool($value)) // not sure if this will work well (but its correct) + { + return $value ? 'TRUE' : 'FALSE'; + } + + // For date and datetime values + if ($value instanceof \DateTime) + { + return $this->db->quote($value->format('Y-m-d H:i:s')); + } + + // For other data types, just escape it + return $this->db->quote($value); + } + + /** + * Set a table name, adding the + * core component as needed + * + * @param string $table The table string + * + * @return string + * @since 3.2.0 + **/ + protected function getTable(string $table): string + { + if (strpos($table, '#__') === false) + { + return $this->table . '_' . $table; + } + + return $table; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Model.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Model.php new file mode 100644 index 000000000..9321eef87 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Model.php @@ -0,0 +1,358 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction; + + +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Interfaces\Tableinterface as Table; + + +/** + * Base Model + * + * @since 3.2.0 + */ +abstract class Model +{ + /** + * Last ID + * + * @var array + * @since 3.2.0 + */ + protected array $last; + + /** + * Search Table + * + * @var Table + * @since 3.2.0 + */ + protected Table $table; + + /** + * Constructor + * + * @param Table $table The search table object. + * + * @since 3.2.0 + */ + public function __construct(Table $table) + { + $this->table = $table; + } + + /** + * Model the value + * Example: $this->value(value, 'value_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + abstract public function value($value, string $field, ?string $table = null); + + /** + * Model the values of an item + * Example: $this->item(Object, 'table_name'); + * + * @param object|null $item The item object + * @param string|null $table The table + * + * @return object|null + * @since 3.2.0 + */ + public function item(?object $item, ?string $table = null): ?object + { + // we must have an object + if (empty($item)) + { + return null; + } + + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + if (($fields = $this->getTableFields($table, true)) !== null) + { + // field counter + $field_number = 0; + + // check if this is a valid table + $item_bucket = new \stdClass(); + + foreach ($fields as $field) + { + // model a value if it exists + if(isset($item->{$field})) + { + if (!$this->validateBefore($item->{$field}, $field, $table)) + { + continue; + } + + $item->{$field} = $this->value($item->{$field}, $field, $table); + + if (!$this->validateAfter($item->{$field}, $field, $table)) + { + continue; + } + + $item_bucket->{$field} = $item->{$field}; + + $field_number++; + } + } + + // all items must have more than one field or its empty (1 = key) + if ($field_number > 1) + { + return $item_bucket; + } + } + + return null; + } + + /** + * Model the values of multiple items + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The array of item objects + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function items(?array $items = null, ?string $table = null): ?array + { + // check if this is a valid table + if (ArrayHelper::check($items)) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + foreach ($items as $id => &$item) + { + // model the item + if (($item = $this->item($item, $table)) !== null) + { + // add the last ID + $this->last[$table] = $item->id ?? $this->last[$table] ?? null; + } + else + { + unset($items[$id]); + } + } + + if (ArrayHelper::check($items)) + { + return $items; + } + } + + return null; + } + + /** + * Model the values of an row + * Example: $this->item(Array, 'table_name'); + * + * @param array|null $item The item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function row(?array $item, ?string $table = null): ?array + { + // we must have an array + if (empty($item)) + { + return null; + } + + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + if (($fields = $this->getTableFields($table, true)) !== null) + { + // field counter + $field_number = 0; + + // check if this is a valid table + $item_bucket = []; + + foreach ($fields as $field) + { + // model a value if it exists + if(isset($item[$field])) + { + if (!$this->validateBefore($item[$field], $field, $table)) + { + continue; + } + + $item[$field] = $this->value($item[$field], $field, $table); + + if (!$this->validateAfter($item[$field], $field, $table)) + { + continue; + } + + $item_bucket[$field] = $item[$field]; + + $field_number++; + } + } + + // all items must have more than one field or its empty (1 = id or guid) + if ($field_number > 1) + { + return $item_bucket; + } + } + + return null; + } + + /** + * Model the values of multiple rows + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The array of item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function rows(?array $items = null, ?string $table = null): ?array + { + // check if this is a valid table + if (ArrayHelper::check($items)) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + foreach ($items as $id => &$item) + { + // model the item + if (($item = $this->row($item, $table)) !== null) + { + // add the last ID + $this->last[$table] = $item['id'] ?? $this->last[$table] ?? null; + } + else + { + unset($items[$id]); + } + } + + if (ArrayHelper::check($items)) + { + return $items; + } + } + + return null; + } + + /** + * Get last modeled ID + * Example: $this->last('table_name'); + * + * @param string|null $table The table + * + * @return int|null + * @since 3.2.0 + */ + public function last(?string $table = null): ?int + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if ($table && isset($this->last[$table])) + { + return $this->last[$table]; + } + + return null; + } + + /** + * Get the current active table's fields (including defaults) + * + * @param string $table The area + * @param bool $default Add the default fields + * + * @return array + * @since 3.2.0 + */ + protected function getTableFields(string $table, bool $default = false): ?array + { + return $this->table->fields($table, $default); + } + + /** + * Validate before the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + abstract protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool; + + /** + * Validate after the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + abstract protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool; + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + abstract protected function getTable(): string; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry.php new file mode 100644 index 000000000..bbe1daba9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry.php @@ -0,0 +1,182 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction; + + +use VDM\Joomla\Interfaces\Activeregistryinterface; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\ActiveRegistry; + + +/** + * VDM Basic Registry. + * + * Don't use this beyond 10 dimensional depth for best performance. + * + * @since 3.2.0 + */ +abstract class Registry extends ActiveRegistry implements Activeregistryinterface, Registryinterface +{ + /** + * Path separator + * + * @var string|null + * @since 3.2.0 + */ + protected ?string $separator = '.'; + + /** + * Sets a value into the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * @param mixed $value Value of entry + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return void + * @since 3.2.0 + */ + public function set(string $path, $value): void + { + if (($keys = $this->getActiveKeys($path)) === null) + { + throw new \InvalidArgumentException("Path must only be strings or numbers to set any value."); + } + + $this->setActive($value, ...$keys); + } + + /** + * Adds content into the registry. If a key exists, + * it either appends or concatenates based on $asArray switch. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * @param mixed $value Value of entry + * @param bool $asArray Determines if the new value should be treated as an array. Default is false. + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return void + * @since 3.2.0 + */ + public function add(string $path, $value, bool $asArray = false): void + { + if (($keys = $this->getActiveKeys($path)) === null) + { + throw new \InvalidArgumentException("Path must only be strings or numbers to add any value."); + } + + $this->addActive($value, $asArray, ...$keys); + } + + /** + * Retrieves a value (or sub-array) from the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * @param mixed $default Optional default value, returned if the internal doesn't exist. + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return mixed The value or sub-array from the storage. Null if the location doesn't exist. + * @since 3.2.0 + */ + public function get(string $path, $default = null) + { + if (($keys = $this->getActiveKeys($path)) === null) + { + throw new \InvalidArgumentException("Path must only be strings or numbers to get any value."); + } + + return $this->getActive($default, ...$keys); + } + + /** + * Removes a value (or sub-array) from the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return void + * @since 3.2.0 + */ + public function remove(string $path): void + { + if (($keys = $this->getActiveKeys($path)) === null) + { + throw new \InvalidArgumentException("Path must only be strings or numbers to remove any value."); + } + + $this->removeActive(...$keys); + } + + /** + * Checks the existence of a particular location in the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return bool True if the location exists, false otherwise. + * @since 3.2.0 + */ + public function exists(string $path): bool + { + if (($keys = $this->getActiveKeys($path)) === null) + { + throw new \InvalidArgumentException("Path must only be strings or numbers to check if any value exist."); + } + + return $this->existsActive(...$keys); + } + + /** + * Sets a separator value + * + * @param string|null $value The value to set. + * + * @return void + * @since 3.2.0 + */ + public function setSeparator(?string $value): void + { + $this->separator = $value; + } + + /** + * Get that the active keys from a path + * + * @param string $path The path to determine the location registry. + * + * @return array|null The valid array of keys + * @since 3.2.0 + */ + protected function getActiveKeys(string $path): ?array + { + // empty path no allowed + if ($path === '') + { + return null; + } + + // Flatten the path + if ($this->separator === null || $this->separator === '') + { + return [$path]; + } + + $keys = array_values(array_filter(explode($this->separator, $path), 'strlen')); + + if (empty($keys)) + { + return null; + } + + return $keys; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/Count.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/Count.php new file mode 100644 index 000000000..5584a9ffe --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/Count.php @@ -0,0 +1,51 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +/** + * Count Values + * + * @since 3.2.0 + */ +trait Count +{ + /** + * Retrieves number of values (or sub-array) from the storage using multiple keys. + * + * @param string $path Storage path (e.g. vdm.content.builder) + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return int The number of values + * @since 3.2.0 + */ + public function count(string $path): int + { + if (($values = $this->get($path)) === null) + { + return 0; + } + + if (is_array($values)) + { + return count($values); + } + + if (is_object($values)) + { + return count((array) $values); + } + + return 1; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/GetString.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/GetString.php new file mode 100644 index 000000000..56f128d79 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/GetString.php @@ -0,0 +1,50 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +/** + * Get String Values + * + * @since 3.2.0 + */ +trait GetString +{ + /** + * Get a registry path if the return value is a string + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * @param string|null $default A default value + * + * @return string|null + * @since 3.2.0 + */ + public function getString(string $path, ?string $default = null): ?string + { + // Return default value if path is empty + if (empty($path)) + { + return $default; + } + + // get the value + if (($node = $this->get($path)) !== null + && is_string($node) + && strlen((string) $node) > 0) + { + return $node; + } + + return $default; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/InArray.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/InArray.php new file mode 100644 index 000000000..9bcd7082d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/InArray.php @@ -0,0 +1,50 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +/** + * Check if a value is in an array + * + * @since 3.2.0 + */ +trait InArray +{ + /** + * Check if a value is found in an array + * + * @param mixed $value The value to check for + * @param string|null $path Registry path (e.g. joomla.content.showauthor) + * + * @return bool + * @since 3.2.0 + */ + public function inArray($value, ?string $path = null): bool + { + // Check base array if no path is given + if (empty($path)) + { + return in_array($value, $this->active); + } + + // get the value + if (($node = $this->get($path)) !== null + && is_array($node) + && in_array($value, $node)) + { + return true; + } + + return false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/IsArray.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/IsArray.php new file mode 100644 index 000000000..cdf224b18 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/IsArray.php @@ -0,0 +1,48 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +/** + * Check if a value is in an array + * + * @since 3.2.0 + */ +trait IsArray +{ + /** + * Check if a path is an array + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * + * @return bool + * @since 3.2.0 + */ + public function isArray(string $path): bool + { + // Check base array if no path is given + if (empty($path)) + { + return false; + } + + // get the value + if (($node = $this->get($path)) !== null + && is_array($node)) + { + return true; + } + + return false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/IsString.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/IsString.php new file mode 100644 index 000000000..e0b69ca33 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/IsString.php @@ -0,0 +1,48 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +/** + * Is String Values + * + * @since 3.2.0 + */ +trait IsString +{ + /** + * Check if a registry path exists and is a string + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * + * @return boolean + * @since 3.2.0 + */ + public function isString(string $path): bool + { + // Return default value if path is empty + if (empty($path)) { + return false; + } + + // get the value + if (($node = $this->get($path)) !== null + && is_string($node) + && strlen((string) $node) > 0) + { + return true; + } + + return false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/ToString.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/ToString.php new file mode 100644 index 000000000..285f7099d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/ToString.php @@ -0,0 +1,55 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +/** + * To String Values + * + * @since 3.2.0 + */ +trait ToString +{ + /** + * Convert an array of values to a string (or return string) + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * @param string $seperator Return string separator + * + * @return string + * @since 3.2.0 + */ + public function toString(string $path, string $separator = ''): string + { + // Return default value if path is empty + if (empty($path)) + { + return ''; + } + + // get the value + if (($node = $this->get($path)) !== null) + { + if (is_array($node) && $node !== []) + { + return implode($separator, $node); + } + elseif (is_string($node) && strlen((string) $node) > 0) + { + return $node; + } + } + + return ''; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/VarExport.php b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/VarExport.php new file mode 100644 index 000000000..56af57e7c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/VarExport.php @@ -0,0 +1,105 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Abstraction\Registry\Traits; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Var Export Values + * + * @since 3.2.0 + */ +trait VarExport +{ + /** + * Default indentation value + * + * @var int + * @since 3.4.0 + */ + protected int $indent = 2; + + /** + * Method to export a set of values to a PHP array + * + * @param string|null $path Registry path (e.g. joomla.content.showauthor) + * @param int $indentation The default indentation + * + * @return ?string The var set being exported as a PHP array + * @since 3.4.0 + */ + public function varExport(?string $path = null, int $indentation = 2): ?string + { + // Load the data array + if ($path === null && $this->isActive()) + { + $data = $this->allActive(); + } + else + { + $data = $this->get($path); + } + + // check if we have data + if ($data === null) + { + return null; + } + + // set the default indentation value + $this->indent = $indentation; + + // convert to string + $data = var_export($data, true); + + // replace all space with system indentation + $data = preg_replace_callback("/^(\s{2})(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(\s{2})?(.*)/m", [$this, 'convertIndent'], $data); + + // convert all array to [] + $array = preg_split("/\r\n|\n|\r/", $data); + $array = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [NULL, ']$1', ' => ['], $array); + $data = implode(PHP_EOL, array_filter(["["] + $array)); + + // add needed indentation to the last ] + $data = preg_replace("/^(\])/m", Indent::_($indentation) . '$1', $data); + + return $data; + } + + /** + * Method to convert found of grouped spaces to system indentation + * + * @param array $matches The regex array of matching values + * + * @return string The resulting string. + * @since 3.4.0 + */ + protected function convertIndent(array $matches): string + { + // set number to indent by default + $indent = Indent::_($this->indent); + + // update each found space (group) with one indentation + foreach (range(1, 11) as $space) + { + if (strlen((string) $matches[$space]) > 0) + { + $indent .= Indent::_(1); + } + } + + return $indent . $matches[12]; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/index.html b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/Registry/Traits/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Abstraction/index.html b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Abstraction/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/BaseConfig.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/BaseConfig.php new file mode 100644 index 000000000..1319d2c5d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/BaseConfig.php @@ -0,0 +1,64 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Abstraction; + + +use Joomla\Registry\Registry as JoomlaRegistry; +use Joomla\CMS\Factory; +use Joomla\Input\Input; +use VDM\Joomla\Abstraction\BaseConfig as Config; +use VDM\Joomla\Utilities\Component\Helper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; + + +/** + * Config + * + * @since 3.2.0 + */ +abstract class BaseConfig extends Config +{ + /** + * Hold a JInput object for easier access to the input variables. + * + * @var Input + * @since 3.2.0 + */ + protected Input $input; + + /** + * The Params + * + * @var JoomlaRegistry + * @since 3.2.0 + */ + protected JoomlaRegistry $params; + + /** + * Constructor + * + * @param Input|null $input Input + * @param Registry|null $params The component parameters + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Input $input = null, ?JoomlaRegistry $params = null) + { + $this->input = $input ?: Factory::getApplication()->input; + $this->params = $params ?: Helper::getParams('com_componentbuilder'); + + // run parent constructor + parent::__construct(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/BaseRegistry.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/BaseRegistry.php new file mode 100644 index 000000000..bfec40984 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/BaseRegistry.php @@ -0,0 +1,150 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Abstraction; + + +use Joomla\Registry\Registry as JoomlaRegistry; + + +/** + * Registry + * + * So we have full control over this class + * + * @since 3.2.0 + */ +abstract class BaseRegistry extends JoomlaRegistry implements \JsonSerializable, \ArrayAccess, \IteratorAggregate, \Countable +{ + /** + * Method to iterate over any part of the registry + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * + * @return \ArrayIterator|null This object represented as an ArrayIterator. + * + * @since 3.4.0 + */ + public function _(string $path): ?\ArrayIterator + { + $data = $this->extract($path); + + if ($data === null) + { + return null; + } + + return $data->getIterator(); + } + + /** + * Append value to a path in registry of an array + * + * @param string $path Parent registry Path (e.g. joomla.content.showauthor) + * @param mixed $value Value of entry + * + * @return mixed The value of the that has been set. + * + * @since 3.2.0 + */ + public function appendArray(string $path, $value) + { + // check if it does not exist + if (!$this->exists($path)) + { + $this->set($path, []); + } + + return $this->append($path, $value); + } + + /** + * Check if a registry path exists and is an array + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * + * @return boolean + * + * @since 3.2.0 + */ + public function isArray(string $path): bool + { + // Return default value if path is empty + if (empty($path)) { + return false; + } + + // get the value + if (($node = $this->get($path)) !== null + && is_array($node) + && $node !== []) + { + return true; + } + + return false; + } + + /** + * Check if a registry path exists and is a string + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * + * @return boolean + * + * @since 3.2.0 + */ + public function isString(string $path): bool + { + // Return default value if path is empty + if (empty($path)) { + return false; + } + + // get the value + if (($node = $this->get($path)) !== null + && is_string($node) + && strlen((string) $node) > 0) + { + return true; + } + + return false; + } + + /** + * Check if a registry path exists and is numeric + * + * @param string $path Registry path (e.g. joomla.content.showauthor) + * + * @return boolean + * + * @since 3.2.0 + */ + public function isNumeric(string $path): bool + { + // Return default value if path is empty + if (empty($path)) { + return false; + } + + // get the value + if (($node = $this->get($path)) !== null + && is_numeric($node)) + { + return true; + } + + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php new file mode 100644 index 000000000..bda82d831 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Data.php @@ -0,0 +1,530 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Adminview; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customtabs; +use VDM\Joomla\Componentbuilder\Compiler\Model\Tabs; +use VDM\Joomla\Componentbuilder\Compiler\Model\Fields; +use VDM\Joomla\Componentbuilder\Compiler\Model\Historyadminview as History; +use VDM\Joomla\Componentbuilder\Compiler\Model\Permissions; +use VDM\Joomla\Componentbuilder\Compiler\Model\Conditions; +use VDM\Joomla\Componentbuilder\Compiler\Model\Relations; +use VDM\Joomla\Componentbuilder\Compiler\Model\Linkedviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Javascriptadminview as Javascript; +use VDM\Joomla\Componentbuilder\Compiler\Model\Cssadminview as Css; +use VDM\Joomla\Componentbuilder\Compiler\Model\Phpadminview as Php; +use VDM\Joomla\Componentbuilder\Compiler\Model\Custombuttons; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customimportscripts; +use VDM\Joomla\Componentbuilder\Compiler\Model\Ajaxadmin as Ajax; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customalias; +use VDM\Joomla\Componentbuilder\Compiler\Model\Sql; +use VDM\Joomla\Componentbuilder\Compiler\Model\Mysqlsettings; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteEditView; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Admin View Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Dispenser Class. + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * The Customtabs Class. + * + * @var Customtabs + * @since 3.2.0 + */ + protected Customtabs $customtabs; + + /** + * The Tabs Class. + * + * @var Tabs + * @since 3.2.0 + */ + protected Tabs $tabs; + + /** + * The Fields Class. + * + * @var Fields + * @since 3.2.0 + */ + protected Fields $fields; + + /** + * The Historyadminview Class. + * + * @var History + * @since 3.2.0 + */ + protected History $history; + + /** + * The Permissions Class. + * + * @var Permissions + * @since 3.2.0 + */ + protected Permissions $permissions; + + /** + * The Conditions Class. + * + * @var Conditions + * @since 3.2.0 + */ + protected Conditions $conditions; + + /** + * The Relations Class. + * + * @var Relations + * @since 3.2.0 + */ + protected Relations $relations; + + /** + * The Linkedviews Class. + * + * @var Linkedviews + * @since 3.2.0 + */ + protected Linkedviews $linkedviews; + + /** + * The Javascriptadminview Class. + * + * @var Javascript + * @since 3.2.0 + */ + protected Javascript $javascript; + + /** + * The Cssadminview Class. + * + * @var Css + * @since 3.2.0 + */ + protected Css $css; + + /** + * The Phpadminview Class. + * + * @var Php + * @since 3.2.0 + */ + protected Php $php; + + /** + * The Custombuttons Class. + * + * @var Custombuttons + * @since 3.2.0 + */ + protected Custombuttons $custombuttons; + + /** + * The Customimportscripts Class. + * + * @var Customimportscripts + * @since 3.2.0 + */ + protected Customimportscripts $customimportscripts; + + /** + * The Ajaxadmin Class. + * + * @var Ajax + * @since 3.2.0 + */ + protected Ajax $ajax; + + /** + * The Customalias Class. + * + * @var Customalias + * @since 3.2.0 + */ + protected Customalias $customalias; + + /** + * The Sql Class. + * + * @var Sql + * @since 3.2.0 + */ + protected Sql $sql; + + /** + * The Mysqlsettings Class. + * + * @var Mysqlsettings + * @since 3.2.0 + */ + protected Mysqlsettings $mysqlsettings; + + /** + * The SiteEditView Class. + * + * @var SiteEditView + * @since 3.2.0 + */ + protected SiteEditView $siteeditview; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Event $event The EventInterface Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Dispenser $dispenser The Dispenser Class. + * @param Customtabs $customtabs The Customtabs Class. + * @param Tabs $tabs The Tabs Class. + * @param Fields $fields The Fields Class. + * @param History $history The Historyadminview Class. + * @param Permissions $permissions The Permissions Class. + * @param Conditions $conditions The Conditions Class. + * @param Relations $relations The Relations Class. + * @param Linkedviews $linkedviews The Linkedviews Class. + * @param Javascript $javascript The Javascriptadminview Class. + * @param Css $css The Cssadminview Class. + * @param Php $php The Phpadminview Class. + * @param Custombuttons $custombuttons The Custombuttons Class. + * @param Customimportscripts $customimportscripts The Customimportscripts Class. + * @param Ajax $ajax The Ajaxadmin Class. + * @param Customalias $customalias The Customalias Class. + * @param Sql $sql The Sql Class. + * @param Mysqlsettings $mysqlsettings The Mysqlsettings Class. + * @param SiteEditView $siteeditview The SiteEditView Class. + * @param \JDatabaseDriver|null $db The Database Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Event $event, Placeholder $placeholder, Dispenser $dispenser, Customtabs $customtabs, Tabs $tabs, Fields $fields, + History $history, Permissions $permissions, Conditions $conditions, Relations $relations, Linkedviews $linkedviews, Javascript $javascript, + Css $css, Php $php, Custombuttons $custombuttons, Customimportscripts $customimportscripts, Ajax $ajax, Customalias $customalias, Sql $sql, + Mysqlsettings $mysqlsettings, SiteEditView $siteeditview, ?\JDatabaseDriver $db = null) + { + $this->config = $config; + $this->event = $event; + $this->placeholder = $placeholder; + $this->dispenser = $dispenser; + $this->customtabs = $customtabs; + $this->tabs = $tabs; + $this->fields = $fields; + $this->history = $history; + $this->permissions = $permissions; + $this->conditions = $conditions; + $this->relations = $relations; + $this->linkedviews = $linkedviews; + $this->javascript = $javascript; + $this->css = $css; + $this->php = $php; + $this->custombuttons = $custombuttons; + $this->customimportscripts = $customimportscripts; + $this->ajax = $ajax; + $this->customalias = $customalias; + $this->sql = $sql; + $this->mysqlsettings = $mysqlsettings; + $this->siteeditview = $siteeditview; + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Admin View Data + * + * @param int $id The view ID + * + * @return object|null The view data + * @since 3.2.0 + */ + public function get(int $id): ?object + { + if (!isset($this->data[$id])) + { + // Create a new query object. + $query = $this->db->getQuery(true); + + $query->select('a.*'); + $query->select( + $this->db->quoteName( + array( + 'b.addfields', + 'b.id', + 'c.addconditions', + 'c.id', + 'r.addrelations', + 't.tabs' + ), array( + 'addfields', + 'addfields_id', + 'addconditions', + 'addconditions_id', + 'addrelations', + 'customtabs' + ) + ) + ); + + $query->from('#__componentbuilder_admin_view AS a'); + $query->join( + 'LEFT', + $this->db->quoteName('#__componentbuilder_admin_fields', 'b') + . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('b.admin_view') . ')' + ); + + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_admin_fields_conditions', 'c' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('c.admin_view') . ')' + ); + + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_admin_fields_relations', 'r' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('r.admin_view') . ')' + ); + + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_admin_custom_tabs', 't' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('t.admin_view') . ')' + ); + + $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); + + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + // Trigger Event: jcb_ce_onBeforeQueryViewData + $this->event->trigger( + 'jcb_ce_onBeforeQueryViewData', + array(&$component_context, &$id, &$query, &$this->db) + ); + + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + + // Load the results as a list of stdClass objects (see later for more options on retrieving data). + $view = $this->db->loadObject(); + + // setup single view code names to use in storing the data + $view->name_single_code = 'oops_hmm_' . $id; + if (isset($view->name_single) && $view->name_single != 'null') + { + $view->name_single_code = StringHelper::safe( + $view->name_single + ); + } + + // setup list view code name to use in storing the data + $view->name_list_code = 'oops_hmmm_' . $id; + if (isset($view->name_list) && $view->name_list != 'null') + { + $view->name_list_code = StringHelper::safe( + $view->name_list + ); + } + + // check the length of the view name (+5 for com_ and _) + $name_length = $this->config->component_code_name_length + strlen( + (string) $view->name_single_code + ) + 5; + // when the name is larger than 49 we need to add the assets' table name fix + if ($name_length > 49) + { + $this->config->set('add_assets_table_name_fix', true); + } + + // setup token check + if (!isset($this->dispenser->hub['token'])) + { + $this->dispenser->hub['token'] = []; + } + $this->dispenser->hub['token'][$view->name_single_code] = false; + $this->dispenser->hub['token'][$view->name_list_code] = false; + + // set some placeholders + $this->placeholder->set('view', $view->name_single_code); + $this->placeholder->set('views', $view->name_list_code); + $this->placeholder->set('View', StringHelper::safe( + $view->name_single, 'F' + )); + $this->placeholder->set('Views', StringHelper::safe( + $view->name_list, 'F' + )); + $this->placeholder->set('VIEW', StringHelper::safe( + $view->name_single, 'U' + )); + $this->placeholder->set('VIEWS', StringHelper::safe( + $view->name_list, 'U' + )); + + // for plugin event TODO change event api signatures + $placeholders = $this->placeholder->active; + $component_context = $this->config->component_context; + + // Trigger Event: jcb_ce_onBeforeModelViewData + $this->event->trigger( + 'jcb_ce_onBeforeModelViewData', + array(&$component_context, &$view, &$placeholders) + ); + unset($placeholders); + + // add the tables + $view->addtables = (isset($view->addtables) + && JsonHelper::check($view->addtables)) + ? json_decode((string) $view->addtables, true) : null; + if (ArrayHelper::check($view->addtables)) + { + $view->tables = array_values($view->addtables); + } + unset($view->addtables); + + // set custom tabs + $this->customtabs->set($view); + + // set the local tabs + $this->tabs->set($view); + + // set permissions + $this->permissions->set($view); + + // set fields + $this->fields->set($view); + + // build update SQL + $this->history->set($view); + + // set the conditions + $this->conditions->set($view); + + // set the relations + $this->relations->set($view); + + // set linked views + $this->linkedviews->set($view); + + // set the lang target + $this->config->lang_target = 'admin'; + if ($this->siteeditview->exists($id)) + { + $this->config->lang_target = 'both'; + } + + // set javascript + $this->javascript->set($view); + + // set css + $this->css->set($view); + + // set php + $this->php->set($view); + + // set custom buttons + $this->custombuttons->set($view); + + // set custom import scripts + $this->customimportscripts->set($view); + + // set Ajax for this view + $this->ajax->set($view); + + // activate alias builder + $this->customalias->set($view); + + // set sql + $this->sql->set($view); + + // set mySql Table Settings + $this->mysqlsettings->set($view); + + // for plugin event TODO change event api signatures + $placeholders = $this->placeholder->active; + + // Trigger Event: jcb_ce_onAfterModelViewData + $this->event->trigger( + 'jcb_ce_onAfterModelViewData', + array(&$component_context, &$view, &$placeholders) + ); + + // clear placeholders + $this->placeholder->remove('view'); + $this->placeholder->remove('views'); + $this->placeholder->remove('View'); + $this->placeholder->remove('Views'); + $this->placeholder->remove('VIEW'); + $this->placeholder->remove('VIEWS'); + + // store this view to class object + $this->data[$id] = $view; + } + + // return the found view data + return $this->data[$id]; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Permission.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Permission.php new file mode 100644 index 000000000..75b15e091 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/Permission.php @@ -0,0 +1,123 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Adminview; + + +use VDM\Joomla\Componentbuilder\Compiler\Builder\HasPermissions; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Admin View Permission Class + * + * @since 3.2.0 + */ +final class Permission +{ + /** + * The HasPermissions Class. + * + * @var HasPermissions + * @since 3.2.0 + */ + protected HasPermissions $haspermissions; + + /** + * Constructor. + * + * @param HasPermissions $haspermissions The HasPermissions Class. + * + * @since 3.2.0 + */ + public function __construct(HasPermissions $haspermissions) + { + $this->haspermissions = $haspermissions; + } + + /** + * Check to see if a view has permissions + * + * @param array $view View details + * @param string $nameSingleCode View Single Code Name + * + * @return bool true if it has permissions + * @since 3.2.0 + */ + public function check(array &$view, string &$nameSingleCode): bool + { + // first check if we have checked this already + if (!$this->haspermissions->exists($nameSingleCode)) + { + // when a view has history, it has permissions + // since it tracks the version access + if (isset($view['history']) && $view['history'] == 1) + { + // set the permission for later + $this->haspermissions->set($nameSingleCode, true); + + // break out here + return true; + } + // check if the view has permissions + if (isset($view['settings']) + && ArrayHelper::check( + $view['settings']->permissions, true + )) + { + foreach ($view['settings']->permissions as $per) + { + // check if the permission targets the view + // 1 = view + // 3 = both view & component + if (isset($per['implementation']) + && ( + $per['implementation'] == 1 + || $per['implementation'] == 3 + )) + { + // set the permission for later + $this->haspermissions->set($nameSingleCode, true); + + // break out here + return true; + } + } + } + // check if the fields has permissions + if (isset($view['settings']) + && ArrayHelper::check( + $view['settings']->fields, true + )) + { + foreach ($view['settings']->fields as $field) + { + // if a field has any permissions + // the a view has permissions + if (isset($field['permission']) + && ArrayHelper::check( + $field['permission'], true + )) + { + // set the permission for later + $this->haspermissions->set($nameSingleCode, true); + + // break out here + return true; + } + } + } + } + + return $this->haspermissions->exists($nameSingleCode); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Adminview/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Alias/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Alias/Data.php new file mode 100644 index 000000000..42bf0d31a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Alias/Data.php @@ -0,0 +1,265 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Alias; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Model\Loader; +use VDM\Joomla\Componentbuilder\Compiler\Model\Libraries; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Alias Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Auto Loader + * + * @var Loader + * @since 3.2.0 + */ + protected Loader $loader; + + /** + * Compiler Libraries Model + * + * @var Libraries + * @since 3.2.0 + */ + protected Libraries $libraries; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param Loader|null $load The compiler loader object. + * @param Libraries|null $libraries The compiler libraries model object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Registry $registry = null, + ?Customcode $customcode = null, ?Gui $gui = null, + ?Loader $loader = null, ?Libraries $libraries = null, + ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->loader = $loader ?: Compiler::_('Model.Loader'); + $this->libraries = $libraries ?: Compiler::_('Model.Libraries'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Data by Alias + * + * @param string $alias The alias name + * @param string $table The table where to find the alias + * @param string $view The view code name + * + * @return array|null The data found with the alias + * @since 3.2.0 + */ + public function get(string $alias, string $table, string $view): ?array + { + // if not set, get all keys in table and set by ID + $this->set($table); + + // now check if key is found + $name = preg_replace("/[^A-Za-z]/", '', $alias); + + if (($id = $this->registry->get('builder.data_with_alias_keys.' . $table . '.' . $name, null)) === null && + ($id = $this->registry->get('builder.data_with_alias_keys.' . $table . '.' . $alias, null)) === null) + { + return null; + } + + // Create a new query object. + $query = $this->db->getQuery(true); + $query->select('a.*'); + $query->from('#__componentbuilder_' . $table . ' AS a'); + $query->where( + $this->db->quoteName('a.id') . ' = ' . (int) $id + ); + + // get the row + $this->db->setQuery($query); + $item = $this->db->loadObject(); + + // get the other target if both + $targets = [$this->config->build_target]; + + if ($this->config->lang_target === 'both') + { + $targets = ['site', 'admin']; + } + + // we load this layout + $php_view = ''; + if ($item->add_php_view == 1 + && StringHelper::check($item->php_view)) + { + $php_view = $this->gui->set( + $this->customcode->update(base64_decode((string) $item->php_view)), + array( + 'table' => $table, + 'field' => 'php_view', + 'id' => (int) $item->id, + 'type' => 'php') + ); + } + + $content = $this->gui->set( + $this->customcode->update(base64_decode((string) $item->{$table})), + array( + 'table' => $table, + 'field' => $table, + 'id' => (int) $item->id, + 'type' => 'html') + ); + + // load all targets + foreach ($targets as $target) + { + // set libraries + $this->libraries->set($view, $item, $target); + + // auto loaders + $this->loader->set($view, $content, $target); + $this->loader->set($view, $php_view, $target); + } + + // load uikit version 2 if required + $this->loader->uikit($view, $content); + $this->loader->uikit($view, $php_view); + + return [ + 'id' => $item->id, + 'html' => $this->gui->set( + $content, + [ + 'table' => $table, + 'field' => $table, + 'id' => $item->id, + 'type' => 'html' + ] + ), + 'php_view' => $this->gui->set( + $php_view, + [ + 'table' => $table, + 'field' => 'php_view', + 'id' => $item->id, + 'type' => 'php' + ] + ) + ]; + } + + /** + * Load all alias and ID's of a table + * + * @param string $table The table where to find the alias + * + * @return void + * @since 3.2.0 + */ + protected function set(string $table) + { + // now check if key is found + if (!$this->registry->get('builder.data_with_alias_keys.' . $table, null)) + { + // Create a new query object. + $query = $this->db->getQuery(true); + $query->select(array('a.id', 'a.alias')); + $query->from('#__componentbuilder_' . $table . ' AS a'); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + // check if we have an array + if (ArrayHelper::check($items)) + { + foreach ($items as $item) + { + // build the key + $k_ey = StringHelper::safe($item->alias); + $key = preg_replace("/[^A-Za-z]/", '', (string) $k_ey); + + // set the keys + $this->registry-> + set('builder.data_with_alias_keys.' . $table . '.' . $item->alias, $item->id); + $this->registry-> + set('builder.data_with_alias_keys.' . $table . '.' . $k_ey, $item->id); + $this->registry-> + set('builder.data_with_alias_keys.' . $table . '.' . $key, $item->id); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Alias/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Alias/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Alias/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AccessSwitch.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AccessSwitch.php new file mode 100644 index 000000000..00dbac54d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AccessSwitch.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Access Switch Builder Class + * + * @since 3.2.0 + */ +final class AccessSwitch extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AccessSwitchList.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AccessSwitchList.php new file mode 100644 index 000000000..deed56b65 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AccessSwitchList.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Access Switch List Builder Class + * + * @since 3.2.0 + */ +final class AccessSwitchList extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AdminFilterType.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AdminFilterType.php new file mode 100644 index 000000000..c8fb86b63 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/AdminFilterType.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Admin Filter Type Builder Class + * + * @since 3.2.0 + */ +final class AdminFilterType extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Alias.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Alias.php new file mode 100644 index 000000000..5fe1a5950 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Alias.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Alias Builder Class + * + * @since 3.2.0 + */ +final class Alias extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/BaseSixFour.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/BaseSixFour.php new file mode 100644 index 000000000..5504dccb7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/BaseSixFour.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Base64 Builder Class + * + * @since 3.2.0 + */ +final class BaseSixFour extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Category.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Category.php new file mode 100644 index 000000000..f88360eb6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Category.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Category Builder Class + * + * @since 3.2.0 + */ +final class Category extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CategoryCode.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CategoryCode.php new file mode 100644 index 000000000..8d3cb87bd --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CategoryCode.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\GetString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Category Code Builder Class + * + * @since 3.2.0 + */ +final class CategoryCode extends Registry implements Registryinterface +{ + /** + * Get String Values + * + * @since 3.2.0 + */ + use GetString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CategoryOtherName.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CategoryOtherName.php new file mode 100644 index 000000000..833141e92 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CategoryOtherName.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Category Other Name Builder Class + * + * @since 3.2.0 + */ +final class CategoryOtherName extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CheckBox.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CheckBox.php new file mode 100644 index 000000000..c1dc199b9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CheckBox.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Check Box Builder Class + * + * @since 3.2.0 + */ +final class CheckBox extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ComponentFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ComponentFields.php new file mode 100644 index 000000000..725346f6a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ComponentFields.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\VarExport; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Component Fields Builder Class + * + * @since 3.2.0 + */ +final class ComponentFields extends Registry implements Registryinterface +{ + /** + * Var Export Values + * + * @since 3.2.0 + */ + use VarExport; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ContentMulti.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ContentMulti.php new file mode 100644 index 000000000..5fd4829fa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ContentMulti.php @@ -0,0 +1,89 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Abstraction\Registry\Traits\IsArray; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Compiler Content Multi + * + * @since 3.2.0 + */ +class ContentMulti extends Registry implements Registryinterface +{ + /** + * Is an Array + * + * @since 3.2.0 + */ + use IsArray; + + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } + + /** + * Get that the active keys from a path + * + * @param string $path The path to determine the location mapper. + * + * @return array|null The valid array of keys + * @since 3.2.0 + */ + protected function getActiveKeys(string $path): ?array + { + // Call the parent class's version of this method + $keys = parent::getActiveKeys($path); + + if ($keys === null) + { + return null; + } + + return $this->modelActiveKeys($keys); + } + + /** + * Model that the active key + * + * @param array $keys The keys to the location mapper. + * + * @return array|null The valid array of key + * @since 3.2.0 + */ + protected function modelActiveKeys(array $keys): ?array + { + if (isset($keys[1])) + { + return [$keys[0], Placefix::_h($keys[1])]; + } + + if (isset($keys[0])) + { + return [$keys[0]]; + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ContentOne.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ContentOne.php new file mode 100644 index 000000000..53854277f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ContentOne.php @@ -0,0 +1,71 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Compiler Content One + * + * @since 3.2.0 + */ +class ContentOne extends Registry implements Registryinterface +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator(null); + } + + /** + * Get that the active keys from a path + * + * @param string $path The path to determine the location mapper. + * + * @return array|null The valid array of keys + * @since 3.2.0 + */ + protected function getActiveKeys(string $path): ?array + { + // Call the parent class's version of this method + $keys = parent::getActiveKeys($path); + + if ($keys === null) + { + return null; + } + + return $this->modelActiveKeys($keys); + } + + /** + * Model that the active key + * + * @param array $keys The keys to the location mapper. + * + * @return array The valid array of key + * @since 3.2.0 + */ + protected function modelActiveKeys(array $keys): array + { + return [Placefix::_h($keys[0])]; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomAlias.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomAlias.php new file mode 100644 index 000000000..f71dd6ca5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomAlias.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Custom Alias Builder Class + * + * @since 3.2.0 + */ +final class CustomAlias extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomField.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomField.php new file mode 100644 index 000000000..533a05766 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomField.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Custom Field Builder Class + * + * @since 3.2.0 + */ +final class CustomField extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomFieldLinks.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomFieldLinks.php new file mode 100644 index 000000000..df81be489 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomFieldLinks.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\ToString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Custom Field Links Builder Class + * + * @since 3.2.0 + */ +final class CustomFieldLinks extends Registry implements Registryinterface +{ + /** + * To String Values + * + * @since 3.2.0 + */ + use ToString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomList.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomList.php new file mode 100644 index 000000000..d2eb0ffd8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomList.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Custom List Builder Class + * + * @since 3.2.0 + */ +final class CustomList extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomTabs.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomTabs.php new file mode 100644 index 000000000..42f5c1d77 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/CustomTabs.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Custom Tabs Builder Class + * + * @since 3.2.0 + */ +final class CustomTabs extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseKeys.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseKeys.php new file mode 100644 index 000000000..e9496c54c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseKeys.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Database Keys Builder Class + * + * @since 3.2.0 + */ +final class DatabaseKeys extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseTables.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseTables.php new file mode 100644 index 000000000..20cdb52d2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseTables.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Database Tables Builder Class + * + * @since 3.2.0 + */ +final class DatabaseTables extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseUniqueGuid.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseUniqueGuid.php new file mode 100644 index 000000000..5e73779e8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseUniqueGuid.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Database Unique Guid Builder Class + * + * @since 3.2.0 + */ +final class DatabaseUniqueGuid extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseUniqueKeys.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseUniqueKeys.php new file mode 100644 index 000000000..4763c4d77 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DatabaseUniqueKeys.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Database Unique Keys Builder Class + * + * @since 3.2.0 + */ +final class DatabaseUniqueKeys extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DoNotEscape.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DoNotEscape.php new file mode 100644 index 000000000..020475d60 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DoNotEscape.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Do Not Escape Builder Class + * + * @since 3.2.0 + */ +final class DoNotEscape extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DynamicFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DynamicFields.php new file mode 100644 index 000000000..df3982eb7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/DynamicFields.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\ToString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Dynamic Fields Builder Class + * + * @since 3.2.0 + */ +final class DynamicFields extends Registry implements Registryinterface +{ + /** + * To String Values + * + * @since 3.2.0 + */ + use ToString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ExtensionCustomFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ExtensionCustomFields.php new file mode 100644 index 000000000..1b6fd5992 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ExtensionCustomFields.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Extension Custom Fields Builder Class + * + * @since 3.2.0 + */ +final class ExtensionCustomFields extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldGroupControl.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldGroupControl.php new file mode 100644 index 000000000..62b5ac51c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldGroupControl.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Field Group Control Builder Class + * + * @since 3.2.0 + */ +final class FieldGroupControl extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldNames.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldNames.php new file mode 100644 index 000000000..e6032ef21 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldNames.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\IsString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Field Names Builder Class + * + * @since 3.2.0 + */ +final class FieldNames extends Registry implements Registryinterface +{ + /** + * Is String Values + * + * @since 3.2.0 + */ + use IsString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldRelations.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldRelations.php new file mode 100644 index 000000000..89dd20a73 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FieldRelations.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Field Relations Builder Class + * + * @since 3.2.0 + */ +final class FieldRelations extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Filter.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Filter.php new file mode 100644 index 000000000..17eac8a38 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Filter.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Filter Builder Class + * + * @since 3.2.0 + */ +final class Filter extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FootableScripts.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FootableScripts.php new file mode 100644 index 000000000..30413a325 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/FootableScripts.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Footable Scripts Builder Class + * + * @since 3.2.0 + */ +final class FootableScripts extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GetAsLookup.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GetAsLookup.php new file mode 100644 index 000000000..e2bc98570 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GetAsLookup.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Get As Lookup Builder Class + * + * @since 3.2.0 + */ +final class GetAsLookup extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GetModule.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GetModule.php new file mode 100644 index 000000000..c8042b007 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GetModule.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Get Module Builder Class + * + * @since 3.2.0 + */ +final class GetModule extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GoogleChart.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GoogleChart.php new file mode 100644 index 000000000..848cf7cf5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/GoogleChart.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Google Chart Builder Class + * + * @since 3.2.0 + */ +final class GoogleChart extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/HasPermissions.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/HasPermissions.php new file mode 100644 index 000000000..ce321c661 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/HasPermissions.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Has Permissions Builder Class + * + * @since 3.2.0 + */ +final class HasPermissions extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/HiddenFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/HiddenFields.php new file mode 100644 index 000000000..bfef415f6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/HiddenFields.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\ToString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Hidden Fields Builder Class + * + * @since 3.2.0 + */ +final class HiddenFields extends Registry implements Registryinterface +{ + /** + * To String Values + * + * @since 3.2.0 + */ + use ToString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/History.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/History.php new file mode 100644 index 000000000..a9a4d8de8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/History.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * History Builder Class + * + * @since 3.2.0 + */ +final class History extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/IntegerFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/IntegerFields.php new file mode 100644 index 000000000..37135aca4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/IntegerFields.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\ToString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Integer Fields Builder Class + * + * @since 3.2.0 + */ +final class IntegerFields extends Registry implements Registryinterface +{ + /** + * To String Values + * + * @since 3.2.0 + */ + use ToString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ItemsMethodEximportString.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ItemsMethodEximportString.php new file mode 100644 index 000000000..ac0e17168 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ItemsMethodEximportString.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Items Method Eximport String Builder Class + * + * @since 3.2.0 + */ +final class ItemsMethodEximportString extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ItemsMethodListString.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ItemsMethodListString.php new file mode 100644 index 000000000..b8a0ede93 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ItemsMethodListString.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Items Method List String Builder Class + * + * @since 3.2.0 + */ +final class ItemsMethodListString extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonItem.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonItem.php new file mode 100644 index 000000000..7f1886a19 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonItem.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Json Item Builder Class + * + * @since 3.2.0 + */ +final class JsonItem extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonItemArray.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonItemArray.php new file mode 100644 index 000000000..97203c5b3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonItemArray.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\InArray; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Json Item Array Builder Class + * + * @since 3.2.0 + */ +final class JsonItemArray extends Registry implements Registryinterface +{ + /** + * In Array + * + * @since 3.2.0 + */ + use InArray; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonString.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonString.php new file mode 100644 index 000000000..6cb68ea82 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/JsonString.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Json String Builder Class + * + * @since 3.2.0 + */ +final class JsonString extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Layout.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Layout.php new file mode 100644 index 000000000..cd5074bfe --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Layout.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\Count; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Layout Builder Class + * + * @since 3.2.0 + */ +final class Layout extends Registry implements Registryinterface +{ + /** + * Count Values + * + * @since 3.2.0 + */ + use Count; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/LayoutData.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/LayoutData.php new file mode 100644 index 000000000..b6bf1984e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/LayoutData.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Layout Data Builder Class + * + * @since 3.2.0 + */ +final class LayoutData extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/LibraryManager.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/LibraryManager.php new file mode 100644 index 000000000..8675c2952 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/LibraryManager.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Library Manager Builder Class + * + * @since 3.2.0 + */ +final class LibraryManager extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListFieldClass.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListFieldClass.php new file mode 100644 index 000000000..4ec7b1f20 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListFieldClass.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * List Field Class Builder Class + * + * @since 3.2.0 + */ +final class ListFieldClass extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListHeadOverride.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListHeadOverride.php new file mode 100644 index 000000000..bbe5cf943 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListHeadOverride.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * List Head Override Builder Class + * + * @since 3.2.0 + */ +final class ListHeadOverride extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListJoin.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListJoin.php new file mode 100644 index 000000000..fa6864a61 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ListJoin.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * List Join Builder Class + * + * @since 3.2.0 + */ +final class ListJoin extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Lists.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Lists.php new file mode 100644 index 000000000..99a2c2590 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Lists.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Lists Builder Class + * + * @since 3.2.0 + */ +final class Lists extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MainTextField.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MainTextField.php new file mode 100644 index 000000000..24535ca2a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MainTextField.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Main Text Field Builder Class + * + * @since 3.2.0 + */ +final class MainTextField extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MetaData.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MetaData.php new file mode 100644 index 000000000..ea297d40a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MetaData.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\IsString; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Meta Data Builder Class + * + * @since 3.2.0 + */ +final class MetaData extends Registry implements Registryinterface +{ + /** + * Is String Values + * + * @since 3.2.0 + */ + use IsString; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelBasicField.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelBasicField.php new file mode 100644 index 000000000..73598ef43 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelBasicField.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Basic Field Model Builder Class + * + * @since 3.2.0 + */ +final class ModelBasicField extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelExpertField.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelExpertField.php new file mode 100644 index 000000000..7f31e18ac --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelExpertField.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Expert Field Model Builder Class + * + * @since 3.2.0 + */ +final class ModelExpertField extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelExpertFieldInitiator.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelExpertFieldInitiator.php new file mode 100644 index 000000000..236164e4b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelExpertFieldInitiator.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Expert Field Initiator Model Builder Class + * + * @since 3.2.0 + */ +final class ModelExpertFieldInitiator extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelMediumField.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelMediumField.php new file mode 100644 index 000000000..fdb03f39f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelMediumField.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Medium Field Model Builder Class + * + * @since 3.2.0 + */ +final class ModelMediumField extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelWhmcsField.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelWhmcsField.php new file mode 100644 index 000000000..099422028 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ModelWhmcsField.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Whmcs Field Model Builder Class + * + * @since 3.2.0 + */ +final class ModelWhmcsField extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MovedPublishingFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MovedPublishingFields.php new file mode 100644 index 000000000..0476f8365 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MovedPublishingFields.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Moved Publishing Fields Builder Class + * + * @since 3.2.0 + */ +final class MovedPublishingFields extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MysqlTableSetting.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MysqlTableSetting.php new file mode 100644 index 000000000..482c36ca2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/MysqlTableSetting.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Mysql Table Setting Builder Class + * + * @since 3.2.0 + */ +final class MysqlTableSetting extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/NewPublishingFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/NewPublishingFields.php new file mode 100644 index 000000000..c32d4dbd7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/NewPublishingFields.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\Count; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * New Publishing Fields Builder Class + * + * @since 3.2.0 + */ +final class NewPublishingFields extends Registry implements Registryinterface +{ + /** + * Count Values + * + * @since 3.2.0 + */ + use Count; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OrderZero.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OrderZero.php new file mode 100644 index 000000000..8408d2b7e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OrderZero.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Order Zero Builder Class + * + * @since 3.2.0 + */ +final class OrderZero extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherFilter.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherFilter.php new file mode 100644 index 000000000..103b5a15d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherFilter.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Other Filter Builder Class + * + * @since 3.2.0 + */ +final class OtherFilter extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherGroup.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherGroup.php new file mode 100644 index 000000000..685320c7c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherGroup.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Other Group Builder Class + * + * @since 3.2.0 + */ +final class OtherGroup extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherJoin.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherJoin.php new file mode 100644 index 000000000..e07fba026 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherJoin.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Other Join Builder Class + * + * @since 3.2.0 + */ +final class OtherJoin extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherOrder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherOrder.php new file mode 100644 index 000000000..fdb9fdcb0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherOrder.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Other Order Builder Class + * + * @since 3.2.0 + */ +final class OtherOrder extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherQuery.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherQuery.php new file mode 100644 index 000000000..0eda01640 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherQuery.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Other Query Builder Class + * + * @since 3.2.0 + */ +final class OtherQuery extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherWhere.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherWhere.php new file mode 100644 index 000000000..85050ed5d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/OtherWhere.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Other Where Builder Class + * + * @since 3.2.0 + */ +final class OtherWhere extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionAction.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionAction.php new file mode 100644 index 000000000..401795b8a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionAction.php @@ -0,0 +1,36 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Permission Actions Builder Class + * + * @since 3.2.0 + */ +final class PermissionAction extends Registry implements Registryinterface +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionComponent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionComponent.php new file mode 100644 index 000000000..af8c8373e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionComponent.php @@ -0,0 +1,88 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Permission Component Builder Class + * + * @since 3.2.0 + */ +final class PermissionComponent extends Registry implements Registryinterface +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } + + /** + * Get the build component content + * + * @return string + * @since 3.2.0 + */ + public function build(): string + { + if ($this->isActive()) + { + $bucket = ['
']; + + // get the header + if ($this->exists('->HEAD<-')) + { + $headers = $this->get('->HEAD<-'); + + // remove from active values + $this->remove('->HEAD<-'); + + foreach ($headers as $action) + { + $bucket[] = Indent::_(2) . ''; + } + } + + if ($this->isActive()) + { + ksort($this->active, SORT_STRING); + + foreach ($this->active as $active) + { + $bucket[] = Indent::_(2) . ''; + } + } + + // reset memory + $this->active = []; + + return implode(PHP_EOL, $bucket) . PHP_EOL . Indent::_(1) . "
"; + } + + return ''; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionCore.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionCore.php new file mode 100644 index 000000000..3c6e08465 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionCore.php @@ -0,0 +1,36 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Permission Core Builder Class + * + * @since 3.2.0 + */ +final class PermissionCore extends Registry implements Registryinterface +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php new file mode 100644 index 000000000..ac3c8c43d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionDashboard.php @@ -0,0 +1,64 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\VarExport; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Permission Dashboard Builder Class + * + * @since 3.2.0 + */ +final class PermissionDashboard extends Registry implements Registryinterface +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } + + /** + * Var Export Values + * + * @since 3.2.0 + */ + use VarExport; + + /** + * Get the build permission dashboard code + * + * @return string + * @since 3.2.0 + */ + public function build(): string + { + if ($this->isActive()) + { + return PHP_EOL . Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " view access array" . PHP_EOL . Indent::_(2) + . "\$viewAccess = " . $this->varExport() . ';'; + } + + return ''; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionGlobalAction.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionGlobalAction.php new file mode 100644 index 000000000..04d6db3bd --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionGlobalAction.php @@ -0,0 +1,36 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Permission Global Action Builder Class + * + * @since 3.2.0 + */ +final class PermissionGlobalAction extends Registry implements Registryinterface +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionViews.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionViews.php new file mode 100644 index 000000000..f4197e137 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/PermissionViews.php @@ -0,0 +1,71 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Permission Views Builder Class + * + * @since 3.2.0 + */ +final class PermissionViews extends Registry +{ + /** + * Constructor. + * + * @since 3.2.0 + */ + public function __construct() + { + $this->setSeparator('|'); + } + + /** + * Get the build view content + * + * @return string + * @since 3.2.0 + */ + public function build(): string + { + if ($this->isActive()) + { + $bucket = []; + foreach ($this->active as $views_code_name => $actions) + { + $bucket[] = Indent::_(1) . '
'; + + foreach ($actions as $action) + { + $bucket[] = Indent::_(2) . ''; + } + + $bucket[] = Indent::_(1) . "
"; + } + + // reset memory + $this->active = []; + + return PHP_EOL . implode(PHP_EOL, $bucket); + } + + return ''; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ScriptMediaSwitch.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ScriptMediaSwitch.php new file mode 100644 index 000000000..338aa80fa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ScriptMediaSwitch.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\InArray; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Script Media Switch Builder Class + * + * @since 3.2.0 + */ +final class ScriptMediaSwitch extends Registry implements Registryinterface +{ + /** + * In Array + * + * @since 3.2.0 + */ + use InArray; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ScriptUserSwitch.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ScriptUserSwitch.php new file mode 100644 index 000000000..40de3c551 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/ScriptUserSwitch.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\InArray; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Script User Switch Builder Class + * + * @since 3.2.0 + */ +final class ScriptUserSwitch extends Registry implements Registryinterface +{ + /** + * In Array + * + * @since 3.2.0 + */ + use InArray; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Search.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Search.php new file mode 100644 index 000000000..8fffb1f38 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Search.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Search Builder Class + * + * @since 3.2.0 + */ +final class Search extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SelectionTranslation.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SelectionTranslation.php new file mode 100644 index 000000000..c1bf2256c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SelectionTranslation.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Selection Translation Builder Class + * + * @since 3.2.0 + */ +final class SelectionTranslation extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteDecrypt.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteDecrypt.php new file mode 100644 index 000000000..b9e25eaf0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteDecrypt.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Decrypt Builder Class + * + * @since 3.2.0 + */ +final class SiteDecrypt extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteDynamicGet.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteDynamicGet.php new file mode 100644 index 000000000..c9540624d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteDynamicGet.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Dynamic Get Builder Class + * + * @since 3.2.0 + */ +final class SiteDynamicGet extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteEditView.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteEditView.php new file mode 100644 index 000000000..84fbf97d0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteEditView.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Edit View Builder Class + * + * @since 3.2.0 + */ +final class SiteEditView extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFieldData.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFieldData.php new file mode 100644 index 000000000..0e4c01cde --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFieldData.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry\Traits\InArray; +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Field Data Builder Class + * + * @since 3.2.0 + */ +final class SiteFieldData extends Registry implements Registryinterface +{ + /** + * In Array + * + * @since 3.2.0 + */ + use InArray; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFieldDecodeFilter.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFieldDecodeFilter.php new file mode 100644 index 000000000..8ebd6c9f2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFieldDecodeFilter.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Field Decode Filter Builder Class + * + * @since 3.2.0 + */ +final class SiteFieldDecodeFilter extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFields.php new file mode 100644 index 000000000..368ea1be3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteFields.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Fields Builder Class + * + * @since 3.2.0 + */ +final class SiteFields extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteMainGet.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteMainGet.php new file mode 100644 index 000000000..0f5329d4a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/SiteMainGet.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Site Main Get Builder Class + * + * @since 3.2.0 + */ +final class SiteMainGet extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Sort.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Sort.php new file mode 100644 index 000000000..c13dbc1e7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Sort.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Sort Builder Class + * + * @since 3.2.0 + */ +final class Sort extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/TabCounter.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/TabCounter.php new file mode 100644 index 000000000..00c6c9c1b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/TabCounter.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Tab Counter Builder Class + * + * @since 3.2.0 + */ +final class TabCounter extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Tags.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Tags.php new file mode 100644 index 000000000..c18a00b8e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Tags.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Tags Builder Class + * + * @since 3.2.0 + */ +final class Tags extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/TemplateData.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/TemplateData.php new file mode 100644 index 000000000..fbdcafe4a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/TemplateData.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Template Data Builder Class + * + * @since 3.2.0 + */ +final class TemplateData extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Title.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Title.php new file mode 100644 index 000000000..f569b53cf --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Title.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Title Builder Class + * + * @since 3.2.0 + */ +final class Title extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/UikitComp.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/UikitComp.php new file mode 100644 index 000000000..32adf0c47 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/UikitComp.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Uikit Comp Builder Class + * + * @since 3.2.0 + */ +final class UikitComp extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/UpdateMysql.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/UpdateMysql.php new file mode 100644 index 000000000..431383d47 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/UpdateMysql.php @@ -0,0 +1,43 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder; + + +use VDM\Joomla\Abstraction\Registry; + + +/** + * Compiler Builder Update Mysql + * + * @since 3.2.0 + */ +class UpdateMysql extends Registry +{ + /** + * Get that the active keys from a path + * + * @param string $path The path to determine the location. + * + * @return array|null The valid array of keys + * @since 3.2.0 + */ + protected function getActiveKeys(string $path): ?array + { + if (!empty($path)) + { + return [preg_replace('/\s+/', '', $path)]; + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component.php new file mode 100644 index 000000000..211abf268 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component.php @@ -0,0 +1,60 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Component\Data; +use VDM\Joomla\Componentbuilder\Abstraction\BaseRegistry; + + +/** + * Compiler Component + * + * @since 3.2.0 + */ +final class Component extends BaseRegistry +{ + /** + * Constructor + * + * @param Data|null $component The component data class. + * + * @since 3.2.0 + */ + public function __construct(?Data $component = null) + { + $component = $component ?: Compiler::_('Component.Data'); + + parent::__construct($component->get()); + } + + /** + * getting any valid value + * + * @param string $path The value's key/path name + * + * @since 3.2.0 + */ + public function __get(string $path) + { + // check if it has been set + if (($value = $this->get($path, '__N0T_S3T_Y3T_')) !== '__N0T_S3T_Y3T_') + { + return $value; + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Dashboard.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Dashboard.php new file mode 100644 index 000000000..12a0ba240 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Dashboard.php @@ -0,0 +1,212 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Application\CMSApplication; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Compiler Component Dynamic Dashboard + * + * @since 3.2.0 + */ +final class Dashboard +{ + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Component + * + * @var Component + * @since 3.2.0 + **/ + protected Component $component; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * @param Component|null $component The component class. + * @param CMSApplication|null $app The app object. + * + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null, ?Component $component = null, + ?CMSApplication $app = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + $this->component = $component ?: Compiler::_('Component'); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * Set the Dynamic Dashboard + * + * @return void + * @since 3.2.0 + */ + public function set() + { + // only add the dynamic dashboard if all checks out + if ($this->component->get('dashboard_type', 0) == 2 + && ($dashboard_ = $this->component->get('dashboard')) !== null + && StringHelper::check($dashboard_) + && strpos((string) $dashboard_, '_') !== false) + { + // set the default view + $getter = explode('_', (string) $dashboard_); + if (count((array) $getter) == 2 && is_numeric($getter[1])) + { + // the pointers + $t = StringHelper::safe($getter[0], 'U'); + $id = (int) $getter[1]; + + // the dynamic stuff + $targets = array('A' => 'admin_views', + 'C' => 'custom_admin_views'); + $names = array('A' => 'admin view', + 'C' => 'custom admin view'); + $types = array('A' => 'adminview', 'C' => 'customadminview'); + $keys = array('A' => 'name_list', 'C' => 'code'); + + // check the target values + if (isset($targets[$t]) && $id > 0) + { + // set the type name + $type_names = StringHelper::safe( + $targets[$t], 'w' + ); + // set the dynamic dash + if (($target_ = $this->component->get($targets[$t])) !== null + && ArrayHelper::check($target_)) + { + // search the target views + $dashboard = (array) array_filter( + $target_, + function ($view) use ($id, $t, $types) { + if (isset($view[$types[$t]]) + && $id == $view[$types[$t]]) + { + return true; + } + + return false; + } + ); + + // set dashboard + if (ArrayHelper::check($dashboard)) + { + $dashboard = array_values($dashboard)[0]; + } + + // check if view was found (this should be true) + if (isset($dashboard['settings']) + && isset($dashboard['settings']->{$keys[$t]})) + { + $this->registry->set('build.dashboard', + StringHelper::safe( + $dashboard['settings']->{$keys[$t]} + ) + ); + $this->registry->set('build.dashboard.type', + $targets[$t] + ); + } + else + { + // set massage that something is wrong + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), + 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_BSB_IS_NOT_AVAILABLE_IN_YOUR_COMPONENT_PLEASE_INSURE_TO_ONLY_USED_S_FOR_A_DYNAMIC_DASHBOARD_THAT_ARE_STILL_LINKED_TO_YOUR_COMPONENT', + $names[$t], $dashboard_, + $type_names + ), 'Error' + ); + } + } + else + { + // set massage that something is wrong + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_BSB_IS_NOT_AVAILABLE_IN_YOUR_COMPONENT_PLEASE_INSURE_TO_ONLY_USED_S_FOR_A_DYNAMIC_DASHBOARD_THAT_ARE_STILL_LINKED_TO_YOUR_COMPONENT', + $names[$t], $dashboard_, + $type_names + ), 'Error' + ); + } + } + else + { + // the target value is wrong + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_VALUE_FOR_THE_DYNAMIC_DASHBOARD_IS_INVALID', + $dashboard_ + ), 'Error' + ); + } + } + else + { + // the target value is wrong + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_VALUE_FOR_THE_DYNAMIC_DASHBOARD_IS_INVALID', + $dashboard_ + ), 'Error' + ); + } + + // if default was changed to dynamic dashboard the remove default tab and methods + if ($this->registry->get('build.dashboard')) + { + // dynamic dashboard is used + $this->component->remove('dashboard_tab'); + $this->component->remove('php_dashboard_methods'); + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php new file mode 100644 index 000000000..e4d2927ca --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php @@ -0,0 +1,877 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder as ComponentPlaceholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Field as Field; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName; +use VDM\Joomla\Componentbuilder\Compiler\Field\UniqueName; +use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders; +use VDM\Joomla\Componentbuilder\Compiler\Model\Historycomponent; +use VDM\Joomla\Componentbuilder\Compiler\Model\Whmcs; +use VDM\Joomla\Componentbuilder\Compiler\Model\Sqltweaking; +use VDM\Joomla\Componentbuilder\Compiler\Model\Adminviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Siteviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customadminviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Updateserver; +use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlamodules; +use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlaplugins; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Compiler Component Data + * + * @since 3.2.0 + */ +final class Data +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Compiler Event + * + * @var EventInterface + * @since 3.2.0 + */ + protected EventInterface $event; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Compiler Component Placeholder + * + * @var ComponentPlaceholder + * @since 3.2.0 + **/ + protected ComponentPlaceholder $componentPlaceholder; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Field + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * Compiler field name + * + * @var FieldName + * @since 3.2.0 + */ + protected FieldName $fieldName; + + /** + * Compiler Field Unique Name + * + * @var UniqueName + * @since 3.2.0 + **/ + protected UniqueName $uniqueName; + + /** + * Compiler Files Folders + * + * @var Filesfolders + * @since 3.2.0 + */ + protected Filesfolders $filesFolders; + + /** + * The modelling component history + * + * @var Historycomponent + * @since 3.2.0 + */ + protected Historycomponent $history; + + /** + * The modelling whmcs + * + * @var Whmcs + * @since 3.2.0 + */ + protected Whmcs $whmcs; + + /** + * The modelling Sql Tweaking + * + * @var Sqltweaking + * @since 3.2.0 + */ + protected Sqltweaking $sqltweaking; + + /** + * The modelling Admin Views + * + * @var Adminviews + * @since 3.2.0 + */ + protected Adminviews $adminviews; + + /** + * The modelling Site Views + * + * @var Siteviews + * @since 3.2.0 + */ + protected Siteviews $siteviews; + + /** + * The modelling Custom Admin Views + * + * @var Customadminviews + * @since 3.2.0 + */ + protected Customadminviews $customadminviews; + + /** + * The modelling Update Server + * + * @var Updateserver + * @since 3.2.0 + */ + protected Updateserver $updateserver; + + /** + * The modelling Joomla Modules + * + * @var Joomlamodules + * @since 3.2.0 + */ + protected Joomlamodules $modules; + + /** + * The modelling Joomla Plugins + * + * @var Joomlaplugins + * @since 3.2.0 + */ + protected Joomlaplugins $plugins; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param EventInterface|null $event The compiler event api object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param ComponentPlaceholder|null $componentPlaceholder The compiler component placeholder object. + * @param Dispenser|null $dispenser The compiler customcode dispenser object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param Field|null $field The compiler field object. + * @param FieldName|null $fieldName The compiler field name object. + * @param UniqueName|null $uniqueName The compiler field unique name object. + * @param Filesfolders|null $filesFolders The compiler files folders object. + * @param Historycomponent|null $history The modelling component history object. + * @param Whmcs|null $whmcs The modelling whmcs object. + * @param Sqltweaking|null $sqltweaking The modelling sql tweaking object. + * @param Adminviews|null $adminviews The modelling adminviews object. + * @param Siteviews|null $siteviews The modelling siteviews object. + * @param Customadminviews|null $customadminviews The modelling customadminviews object. + * @param Updateserver|null $updateserver The modelling update server object. + * @param Joomlamodules|null $modules The modelling modules object. + * @param Joomlaplugins|null $plugins The modelling plugins object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?EventInterface $event = null, + ?Placeholder $placeholder = null, ?ComponentPlaceholder $componentPlaceholder = null, + ?Dispenser $dispenser = null, ?Customcode $customcode = null, ?Gui $gui = null, + ?Field $field = null, ?FieldName $fieldName = null, ?UniqueName $uniqueName = null, + ?Filesfolders $filesFolders = null, ?Historycomponent $history = null, ?Whmcs $whmcs = null, + ?Sqltweaking $sqltweaking = null, ?Adminviews $adminviews = null, ?Siteviews $siteviews = null, + ?Customadminviews $customadminviews = null, ?Updateserver $updateserver = null, + ?Joomlamodules $modules = null, ?Joomlaplugins $plugins = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->event = $event ?: Compiler::_('Event'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->componentPlaceholder = $componentPlaceholder ?: Compiler::_('Component.Placeholder'); + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->field = $field ?: Compiler::_('Field'); + $this->fieldName = $fieldName ?: Compiler::_('Field.Name'); + $this->uniqueName = $uniqueName ?: Compiler::_('Field.Unique.Name'); + $this->filesFolders = $filesFolders ?: Compiler::_('Model.Filesfolders'); + $this->history = $history ?: Compiler::_('Model.Historycomponent'); + $this->whmcs = $whmcs ?: Compiler::_('Model.Whmcs'); + $this->sqltweaking = $sqltweaking ?: Compiler::_('Model.Sqltweaking'); + $this->adminviews = $adminviews ?: Compiler::_('Model.Adminviews'); + $this->siteviews = $siteviews ?: Compiler::_('Model.Siteviews'); + $this->customadminviews = $customadminviews ?: Compiler::_('Model.Customadminviews'); + $this->updateserver = $updateserver ?: Compiler::_('Model.Updateserver'); + $this->modules = $modules ?: Compiler::_('Model.Joomlamodules'); + $this->plugins = $plugins ?: Compiler::_('Model.Joomlaplugins'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * get current component data + * + * @return object|null The component data + * @since 3.2.0 + */ + public function get(): ?object + { + // Create a new query object. + $query = $this->db->getQuery(true); + + // selection + $selection = array( + 'b.addadmin_views' => 'addadmin_views', + 'b.id' => 'addadmin_views_id', + 'h.addconfig' => 'addconfig', + 'd.addcustom_admin_views' => 'addcustom_admin_views', + 'g.addcustommenus' => 'addcustommenus', + 'j.addfiles' => 'addfiles', + 'j.addfolders' => 'addfolders', + 'j.addfilesfullpath' => 'addfilesfullpath', + 'j.addfoldersfullpath' => 'addfoldersfullpath', + 'c.addsite_views' => 'addsite_views', + 'l.addjoomla_plugins' => 'addjoomla_plugins', + 'k.addjoomla_modules' => 'addjoomla_modules', + 'i.dashboard_tab' => 'dashboard_tab', + 'i.php_dashboard_methods' => 'php_dashboard_methods', + 'i.params' => 'dashboard_params', + 'i.id' => 'component_dashboard_id', + 'f.sql_tweak' => 'sql_tweak', + 'e.version_update' => 'version_update', + 'e.id' => 'version_update_id' + ); + $query->select('a.*'); + $query->select( + $this->db->quoteName( + array_keys($selection), array_values($selection) + ) + ); + + // from this table + $query->from('#__componentbuilder_joomla_component AS a'); + + // jointer-map + $joiners = array( + 'b' => 'component_admin_views', + 'c' => 'component_site_views', + 'd' => 'component_custom_admin_views', + 'e' => 'component_updates', + 'f' => 'component_mysql_tweaks', + 'g' => 'component_custom_admin_menus', + 'h' => 'component_config', + 'i' => 'component_dashboard', + 'j' => 'component_files_folders', + 'l' => 'component_plugins', + 'k' => 'component_modules' + ); + + // load the joins + foreach ($joiners as $as => $join) + { + $query->join( + 'LEFT', + $this->db->quoteName('#__componentbuilder_' . $join, $as) + . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName($as . '.joomla_component') . ')' + ); + } + $query->where( + $this->db->quoteName('a.id') . ' = ' . (int) $this->config->component_id + ); + + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + $component_id = $this->config->component_id; + + // Trigger Event: jcb_ce_onBeforeQueryComponentData + $this->event->trigger( + 'jcb_ce_onBeforeQueryComponentData', + array(&$component_context, &$component_id, &$query, + &$this->db) + ); + + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + + // Load the results as a list of stdClass objects + $component = $this->db->loadObject(); + + // make sure we got a component loaded + if (!is_object($component) || !isset($component->system_name)) + { + return null; + } + + // Trigger Event: jcb_ce_onBeforeModelComponentData + $this->event->trigger( + 'jcb_ce_onBeforeModelComponentData', + array(&$component_context, &$component) + ); + + // load the global placeholders + $this->placeholder->active = $this->componentPlaceholder->get(); + + // set component sales name + $component->sales_name = StringHelper::safe( + $component->system_name + ); + + // set the component name_code + $component->name_code = StringHelper::safe( + $component->name_code + ); + + // ensure version naming is correct + $this->config->set('component_version', preg_replace( + '/[^0-9.]+/', '', (string) $component->component_version + ) + ); + + // set the website and autor for global use (default to VDM if not found) + $this->config->set('project_website', $component->website ?? 'https://dev.vdm.io'); + $this->config->set('project_author', $component->author ?? 'VDM'); + + // set the files and folders + $this->filesFolders->set($component); + + // set the uikit switch + $this->config->set('uikit', $component->adduikit); + + // set whmcs links if needed + $this->whmcs->set($component); + + // set the footable switch + if ($component->addfootable > 0) + { + // force add footable + $this->config->set('footable', true); + // add the version + $this->config->set('footable_version', (3 == $component->addfootable) ? 3 : 2); + } + + // set the addcustommenus data + $component->addcustommenus = (isset($component->addcustommenus) + && JsonHelper::check($component->addcustommenus)) + ? json_decode((string) $component->addcustommenus, true) : null; + if (ArrayHelper::check($component->addcustommenus)) + { + $component->custommenus = array_values($component->addcustommenus); + } + unset($component->addcustommenus); + + // set the sql tweak data + $this->sqltweaking->set($component); + + // set the admin view data + $this->adminviews->set($component); + + // set the site view data + $this->siteviews->set($component); + + // set the custom_admin_views data + $this->customadminviews->set($component); + + // set the config data + $component->addconfig = (isset($component->addconfig) + && JsonHelper::check($component->addconfig)) + ? json_decode((string) $component->addconfig, true) : null; + if (ArrayHelper::check($component->addconfig)) + { + $component->config = array_map( + function ($field) { + // make sure the alias and title is 0 + $field['alias'] = 0; + $field['title'] = 0; + // set the field details + $this->field->set($field); + // set unique name counter + $this->uniqueName->set($field['base_name'], 'configs'); + + // return field + return $field; + }, array_values($component->addconfig) + ); + + // do some house cleaning (for fields) + foreach ($component->config as $field) + { + // so first we lock the field name in + $this->fieldName->get($field, 'configs'); + } + // unset original value + unset($component->addconfig); + } + + // set the add contributors + $component->addcontributors = (isset($component->addcontributors) + && JsonHelper::check($component->addcontributors)) + ? json_decode((string) $component->addcontributors, true) : null; + if (ArrayHelper::check($component->addcontributors)) + { + $this->config->set('add_contributors', true); + $component->contributors = array_values( + $component->addcontributors + ); + } + unset($component->addcontributors); + + // set the version updates + $this->updateserver->set($component); + + // build the build date + if ($this->config->get('add_build_date', 1) == 3) + { + if (empty($this->component->modified) || + $this->component->modified == '0000-00-00' || + $this->component->modified == '0000-00-00 00:00:00') + { + $this->config->set('build_date', $this->component->created); + } + else + { + $this->config->set('build_date', $this->component->modified); + } + } + + // build update SQL + $this->history->set($component); + + // set GUI mapper + $guiMapper = [ + 'table' => 'joomla_component', + 'id' => (int) $this->config->component_id, + 'field' => 'javascript', + 'type' => 'js' + ]; + + // add_javascript + if ($component->add_javascript == 1) + { + $this->dispenser->set( + $component->javascript, + 'component_js', + null, + null, + $guiMapper + ); + } + else + { + $this->dispenser->hub['component_js'] = ''; + } + unset($component->javascript); + + // add global CSS + $addGlobalCss = ['admin', 'site']; + foreach ($addGlobalCss as $area) + { + // add_css if found + if (isset($component->{'add_css_' . $area}) + && $component->{'add_css_' . $area} == 1 + && isset($component->{'css_' . $area}) + && StringHelper::check( + $component->{'css_' . $area} + )) + { + $this->dispenser->set( + $component->{'css_' . $area}, + 'component_css_' . $area + ); + } + else + { + $this->dispenser->hub['component_css_' . $area] = ''; + } + unset($component->{'css_' . $area}); + } + + // set the lang target + $this->config->lang_target = 'admin'; + + // add PHP in ADMIN + $addScriptMethods = [ + 'php_preflight', + 'php_postflight', + 'php_method' + ]; + $addScriptTypes = [ + 'install', + 'update', + 'uninstall' + ]; + // update GUI mapper + $guiMapper['type'] = 'php'; + foreach ($addScriptMethods as $scriptMethod) + { + foreach ($addScriptTypes as $scriptType) + { + if (isset($component->{'add_' . $scriptMethod . '_' . $scriptType}) + && $component->{'add_' . $scriptMethod . '_' . $scriptType} == 1 + && StringHelper::check( + $component->{$scriptMethod . '_' . $scriptType} + )) + { + // set GUI mapper field + $guiMapper['field'] = $scriptMethod . '_' . $scriptType; + $this->dispenser->set( + $component->{$scriptMethod . '_' . $scriptType}, + $scriptMethod, + $scriptType, + null, + $guiMapper + ); + } + else + { + $this->dispenser->hub[$scriptMethod][$scriptType] = ''; + } + unset($component->{$scriptMethod . '_' . $scriptType}); + } + } + + // add_php_helper + if ($component->add_php_helper_admin == 1 + && StringHelper::check( + $component->php_helper_admin + )) + { + $this->config->lang_target = 'admin'; + // update GUI mapper + $guiMapper['field'] = 'php_helper_admin'; + $guiMapper['prefix'] = PHP_EOL . PHP_EOL; + $this->dispenser->set( + $component->php_helper_admin, + 'component_php_helper_admin', + null, + null, + $guiMapper + ); + unset($guiMapper['prefix']); + } + else + { + $this->dispenser->hub['component_php_helper_admin'] = ''; + } + unset($component->php_helper); + + // add_admin_event + if ($component->add_admin_event == 1 + && StringHelper::check($component->php_admin_event)) + { + $this->config->lang_target = 'admin'; + // update GUI mapper field + $guiMapper['field'] = 'php_admin_event'; + $this->dispenser->set( + $component->php_admin_event, + 'component_php_admin_event', + null, + null, + $guiMapper + ); + } + else + { + $this->dispenser->hub['component_php_admin_event'] = ''; + } + unset($component->php_admin_event); + + // add_php_helper_both + if ($component->add_php_helper_both == 1 + && StringHelper::check($component->php_helper_both)) + { + $this->config->lang_target = 'both'; + // update GUI mapper field + $guiMapper['field'] = 'php_helper_both'; + $guiMapper['prefix'] = PHP_EOL . PHP_EOL; + $this->dispenser->set( + $component->php_helper_both, + 'component_php_helper_both', + null, + null, + $guiMapper + ); + unset($guiMapper['prefix']); + } + else + { + $this->dispenser->hub['component_php_helper_both'] = ''; + } + + // add_php_helper_site + if ($component->add_php_helper_site == 1 + && StringHelper::check($component->php_helper_site)) + { + $this->config->lang_target = 'site'; + // update GUI mapper field + $guiMapper['field'] = 'php_helper_site'; + $guiMapper['prefix'] = PHP_EOL . PHP_EOL; + $this->dispenser->set( + $component->php_helper_site, + 'component_php_helper_site', + null, + null, + $guiMapper + ); + unset($guiMapper['prefix']); + } + else + { + $this->dispenser->hub['component_php_helper_site'] = ''; + } + unset($component->php_helper); + + // add_site_event + if ($component->add_site_event == 1 + && StringHelper::check($component->php_site_event)) + { + $this->config->lang_target = 'site'; + // update GUI mapper field + $guiMapper['field'] = 'php_site_event'; + $this->dispenser->set( + $component->php_site_event, + 'component_php_site_event', + null, + null, + $guiMapper + ); + } + else + { + $this->dispenser->hub['component_php_site_event'] = ''; + } + unset($component->php_site_event); + + // add_sql + if ($component->add_sql == 1) + { + $this->dispenser->set( + $component->sql, + 'sql', + 'component_sql' + ); + } + unset($component->sql); + + // add_sql_uninstall + if ($component->add_sql_uninstall == 1) + { + $this->dispenser->set( + $component->sql_uninstall, + 'sql_uninstall' + ); + } + unset($component->sql_uninstall); + + // bom + if (StringHelper::check($component->bom)) + { + $this->config->set('bom_path', + $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/' . $component->bom + ); + } + unset($component->bom); + + // README + $component->readme = + $component->addreadme ? + $this->customcode->update( + base64_decode((string) $component->readme) + ) : ''; + + // set lang now + $nowLang = $this->config->lang_target; + $this->config->lang_target = 'admin'; + + // dashboard methods + $component->dashboard_tab = (isset($component->dashboard_tab) + && JsonHelper::check($component->dashboard_tab)) + ? json_decode((string) $component->dashboard_tab, true) : null; + if (ArrayHelper::check($component->dashboard_tab)) + { + $component->dashboard_tab = array_map( + function ($array) { + $array['html'] = $this->customcode->update($array['html']); + + return $array; + }, array_values($component->dashboard_tab) + ); + } + else + { + $component->dashboard_tab = ''; + } + + // add the php of the dashboard if set + if (isset($component->php_dashboard_methods) + && StringHelper::check( + $component->php_dashboard_methods + )) + { + // load the php for the dashboard model + $component->php_dashboard_methods = $this->gui->set( + $this->customcode->update( + base64_decode((string) $component->php_dashboard_methods) + ), + [ + 'table' => 'component_dashboard', + 'field' => 'php_dashboard_methods', + 'id' => (int) $component->component_dashboard_id, + 'type' => 'php' + ] + ); + } + else + { + $component->php_dashboard_methods = ''; + } + + // reset back to now lang + $this->config->lang_target = $nowLang; + + // catch empty URL to update server TODO: we need to fix this in better way later + if (empty($component->add_update_server) || ($component->add_update_server == 1 && $component->update_server_target != 3 + && ( + !StringHelper::check($component->update_server_url) + || strpos($component->update_server_url, 'http') === false + ))) + { + // we fall back to other, since we can't work with an empty update server URL + $component->add_update_server = 0; + $component->update_server_target = 3; + $component->update_server_url = ''; + } + + // add the update/sales server FTP details if that is the expected protocol + $serverArray = array('update_server', 'sales_server'); + foreach ($serverArray as $server) + { + if ($component->{'add_' . $server} == 1 + && is_numeric($component->{$server}) + && $component->{$server} > 0) + { + // get the server protocol + $component->{$server . '_protocol'} + = GetHelper::var( + 'server', (int) $component->{$server}, 'id', 'protocol' + ); + } + else + { + $component->{$server} = 0; + // only change this for sales server (update server can be added loacaly to the zip file) + if ('sales_server' === $server) + { + $component->{'add_' . $server} = 0; + } + $component->{$server . '_protocol'} = 0; + } + } + + // set the ignore folders for repo if found + if (isset($component->toignore) + && StringHelper::check( + $component->toignore + )) + { + if (strpos((string) $component->toignore, ',') !== false) + { + $component->toignore = array_map( + 'trim', (array) explode(',', (string) $component->toignore) + ); + } + else + { + $component->toignore = array(trim((string) $component->toignore)); + } + } + else + { + // the default is to ignore the repo folder + $component->toignore = array('.git'); + } + + // set all modules + $this->modules->set($component); + + // set all plugins + $this->plugins->set($component); + + // Trigger Event: jcb_ce_onAfterModelComponentData + $this->event->trigger( + 'jcb_ce_onAfterModelComponentData', + array(&$component_context, &$component) + ); + + // return found component data + return $component; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Placeholder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Placeholder.php new file mode 100644 index 000000000..39cc7e5ff --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Placeholder.php @@ -0,0 +1,144 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\PlaceholderInterface; + + +/** + * Get a Components Global Placeholders + * + * @since 3.2.0 + */ +final class Placeholder implements PlaceholderInterface +{ + /** + * Placeholders + * + * @var array + * @since 3.2.0 + **/ + protected $placeholders = null; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected $config; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected $db; + + /** + * Constructor. + * + * @param Config $config The compiler config object. + * @param \JDatabaseDriver $db The Database Driver object. + * + * @since 3.2.0 + **/ + public function __construct(?Config $config = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * get all System Placeholders + * + * @return array The global placeholders + * + * @since 3.2.0 + */ + public function get(): array + { + // set only once + if (is_array($this->placeholders)) + { + return $this->placeholders; + } + + // load the config + $config = $this->config; + // load the db + $db = $this->db; + // reset bucket + $bucket = []; + // Create a new query object. + $query = $db->getQuery(true); + $query->select($db->quoteName(array('a.target', 'a.value'))); + // from these tables + $query->from('#__componentbuilder_placeholder AS a'); + // Reset the query using our newly populated query object. + $db->setQuery($query); + + // Load the items + $db->execute(); + if ($db->getNumRows()) + { + $bucket = $db->loadAssocList('target', 'value'); + // open all the code + foreach ($bucket as $key => &$code) + { + $code = base64_decode((string) $code); + } + } + + // set component place holders + $bucket[Placefix::_h('component')] = $config->component_code_name; + $bucket[Placefix::_h('Component')] = StringHelper::safe($config->component_code_name, 'F'); + $bucket[Placefix::_h('COMPONENT')] = StringHelper::safe($config->component_code_name, 'U'); + $bucket[Placefix::_('component')] = $bucket[Placefix::_h('component')]; + $bucket[Placefix::_('Component')] = $bucket[Placefix::_h('Component')]; + $bucket[Placefix::_('COMPONENT')] = $bucket[Placefix::_h('COMPONENT')]; + $bucket[Placefix::_h('LANG_PREFIX')] = $config->lang_prefix; + $bucket[Placefix::_('LANG_PREFIX')] = $bucket[Placefix::_h('LANG_PREFIX')]; + + // get the current components overrides + if (($_placeholders = GetHelper::var( + 'component_placeholders', $config->component_id, + 'joomla_component', 'addplaceholders' + )) !== false + && JsonHelper::check($_placeholders)) + { + $_placeholders = json_decode((string) $_placeholders, true); + if (ArrayHelper::check($_placeholders)) + { + foreach ($_placeholders as $row) + { + $bucket[$row['target']] = $row['value']; + } + } + } + + $this->placeholders = $bucket; + + return $bucket; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Settings.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Settings.php new file mode 100644 index 000000000..63b53483e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Settings.php @@ -0,0 +1,756 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Dynamicpath; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Pathfix; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Compiler Component (Joomla Version) Settings + * + * @since 3.2.0 + */ +final class Settings +{ + /** + * The standard folders + * + * @var array + * @since 3.2.0 + */ + protected array $standardFolders = [ + 'site', + 'admin', + 'media' + ]; + + /** + * The standard root files + * + * @var array + * @since 3.2.0 + */ + protected array $standardRootFiles = [ + 'access.xml', + 'config.xml', + 'controller.php', + 'index.html', + 'README.txt' + ]; + + /** + * Compiler Joomla Version Data + * + * @var object|null + * @since 3.2.0 + */ + protected ?object $data = null; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Event + * + * @var EventInterface + * @since 3.2.0 + */ + protected EventInterface $event; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Compiler Component + * + * @var Component + * @since 3.2.0 + **/ + protected Component $component; + + /** + * Compiler Utilities Paths + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * Compiler Component Dynamic Path + * + * @var Dynamicpath + * @since 3.2.0 + **/ + protected Dynamicpath $dynamicpath; + + /** + * Compiler Component Pathfix + * + * @var Pathfix + * @since 3.2.0 + **/ + protected Pathfix $pathfix; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param EventInterface|null $event The compiler event api object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Component|null $component The component class. + * @param Paths|null $paths The compiler paths object. + * @param Dynamicpath|null $dynamicpath The compiler dynamic path object. + * @param Pathfix|null $pathfix The compiler path fixing object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Registry $registry = null, + ?EventInterface $event = null, ?Placeholder $placeholder = null, + ?Component $component = null, ?Paths $paths = null, + ?Dynamicpath $dynamicpath = null, ?Pathfix $pathfix = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->event = $event ?: Compiler::_('Event'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->component = $component ?: Compiler::_('Component'); + $this->paths = $paths ?: Compiler::_('Utilities.Paths'); + $this->dynamicpath = $dynamicpath ?: Compiler::_('Utilities.Dynamicpath'); + $this->pathfix = $pathfix ?: Compiler::_('Utilities.Pathfix'); + + // add component endpoint file to stander list of root files + $this->standardRootFiles[] = $this->component->get('name_code') . '.php'; + } + + /** + * Check if data set is loaded + * + * @return bool + * @since 3.2.0 + */ + public function exists(): bool + { + if (!$this->isSet()) + { + // load the data + $this->data = $this->get(); + + if (!$this->isSet()) + { + return false; + } + } + + return true; + } + + /** + * Get Joomla - Folder Structure to Create + * + * @return object The version related structure + * @since 3.2.0 + */ + public function structure(): object + { + return $this->data->create; + } + + /** + * Get Joomla - Move Multiple Structure + * + * @return object The version related multiple structure + * @since 3.2.0 + */ + public function multiple(): object + { + return $this->data->move->dynamic; + } + + /** + * Get Joomla - Move Single Structure + * + * @return object The version related single structure + * @since 3.2.0 + */ + public function single(): object + { + return $this->data->move->static; + } + + /** + * Check if Folder is a Standard Folder + * + * @param string $folder The folder name + * + * @return bool true if the folder exists + * @since 3.2.0 + */ + public function standardFolder(string $folder): bool + { + return in_array($folder, $this->standardFolders); + } + + /** + * Check if File is a Standard Root File + * + * @param string $file The file name + * + * @return bool true if the file exists + * @since 3.2.0 + */ + public function standardRootFile(string $file): bool + { + return in_array($file, $this->standardRootFiles); + } + + /** + * Check if Data is Set + * + * @return bool + * @since 3.2.0 + */ + private function isSet(): bool + { + return is_object($this->data) && + isset($this->data->create) && + isset($this->data->move) && + isset($this->data->move->static) && + isset($this->data->move->dynamic); + } + + /** + * get the Joomla Version Data + * + * @return object|null The version data + * @since 3.2.0 + */ + private function get(): ?object + { + // override option + $customSettings = $this->paths->template_path . '/settings_' . + $this->config->component_code_name . '.json'; + + // get the data + $version_data = $this->readJsonFile($customSettings); + + if (is_null($version_data) || !$this->isValidData($version_data)) + { + return null; + } + + $this->loadExtraFolders(); + $this->loadExtraFiles(); + + $this->addFolders($version_data); + $this->addFiles($version_data); + + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + + // Trigger Event: jcb_ce_onAfterSetJoomlaVersionData + $this->event->trigger( + 'jcb_ce_onAfterSetJoomlaVersionData', + array(&$component_context, &$version_data) + ); + + return $version_data; + } + + /** + * Read the Json file data + * + * @param string $filePath + * + * @return object|null The version data + * @since 3.2.0 + */ + private function readJsonFile(string $filePath): ?object + { + if (FileHelper::exists($filePath)) + { + $jsonContent = FileHelper::getContent($filePath); + } + else + { + $jsonContent = FileHelper::getContent($this->paths->template_path . '/settings.json'); + } + + if (JsonHelper::check($jsonContent)) + { + return json_decode((string) $jsonContent); + } + + return null; + } + + /** + * Check if this is valid data + * + * @param object $versionData + * + * @return bool + * @since 3.2.0 + */ + private function isValidData(object $versionData): bool + { + return isset($versionData->create) && + isset($versionData->move) && + isset($versionData->move->static) && + isset($versionData->move->dynamic); + } + + /** + * Add Extra/Dynamic folders + * + * @return void + * @since 3.2.0 + */ + private function loadExtraFolders() + { + if ($this->component->isArray('folders') || + $this->config->get('add_eximport', false) || + $this->config->get('uikit', 0) || + $this->config->get('footable', false)) + { + $this->addImportViewFolder(); + $this->addPhpSpreadsheetFolder(); + $this->addUikitFolder(); + $this->addFooTableFolder(); + } + } + + /** + * Add Import and Export Folder + * + * @return void + * @since 3.2.0 + */ + private function addImportViewFolder() + { + if ($this->config->get('add_eximport', false)) + { + $this->component->appendArray('folders', [ + 'folder' => 'importViews', + 'path' => 'admin/views/import', + 'rename' => 1 + ]); + } + } + + /** + * Add Php Spreadsheet Folder + * + * @return void + * @since 3.2.0 + */ + private function addPhpSpreadsheetFolder() + { + // move the phpspreadsheet Folder (TODO we must move this to a library package) + if ($this->config->get('add_eximport', false)) + { + $this->component->appendArray('folders', [ + 'folderpath' => 'JPATH_LIBRARIES/phpspreadsheet/vendor', + 'path' => '/libraries/phpspreadsheet/', + 'rename' => 0 + ]); + } + } + + /** + * Add Uikit Folders + * + * @return void + * @since 3.2.0 + */ + private function addUikitFolder() + { + $uikit = $this->config->get('uikit', 0); + if (2 == $uikit || 1 == $uikit) + { + // move the UIKIT Folder into place + $this->component->appendArray('folders', [ + 'folder' => 'uikit-v2', + 'path' => 'media', + 'rename' => 0 + ]); + } + if (2 == $uikit || 3 == $uikit) + { + // move the UIKIT-3 Folder into place + $this->component->appendArray('folders', [ + 'folder' => 'uikit-v3', + 'path' => 'media', + 'rename' => 0 + ]); + } + } + + /** + * Add Foo Table Folder + * + * @return void + * @since 3.2.0 + */ + private function addFooTableFolder() + { + if (!$this->config->get('footable', false)) + { + return; + } + + $footable_version = $this->config->get('footable_version', 2); + + if (2 == $footable_version) + { + // move the footable folder into place + $this->component->appendArray('folders', [ + 'folder' => 'footable-v2', + 'path' => 'media', + 'rename' => 0 + ]); + } + elseif (3 == $footable_version) + { + // move the footable folder into place + $this->component->appendArray('folders', [ + 'folder' => 'footable-v3', + 'path' => 'media', + 'rename' => 0 + ]); + } + } + + /** + * Add Extra/Dynamic files + * + * @return void + * @since 3.2.0 + */ + private function loadExtraFiles() + { + if ($this->component->isArray('files') || + $this->config->get('google_chart', false)) + { + $this->addGoogleChartFiles(); + } + } + + /** + * Add Google Chart Files + * + * @return void + * @since 3.2.0 + */ + private function addGoogleChartFiles() + { + if ($this->config->get('google_chart', false)) + { + // move the google chart files + $this->component->appendArray('files', [ + 'file' => 'google.jsapi.js', + 'path' => 'media/js', + 'rename' => 0 + ]); + $this->component->appendArray('files', [ + 'file' => 'chartbuilder.php', + 'path' => 'admin/helpers', + 'rename' => 0 + ]); + } + } + + /** + * Add Folders + * + * @param object $versionData + * + * @return void + * @since 3.2.0 + */ + private function addFolders(object &$versionData) + { + if (!$this->component->isArray('folders')) + { + return; + } + + // pointer tracker + $pointer_tracker = 'h'; + foreach ($this->component->get('folders') as $custom) + { + // check type of target type + $_target_type = 'c0mp0n3nt'; + if (isset($custom['target_type'])) + { + $_target_type = $custom['target_type']; + } + + // for good practice + $this->pathfix->set( + $custom, ['path', 'folder', 'folderpath'] + ); + + // fix custom path + if (isset($custom['path']) + && StringHelper::check($custom['path'])) + { + $custom['path'] = trim((string) $custom['path'], '/'); + } + + // by default custom path is true + $customPath = 'custom'; + + // set full path if this is a full path folder + if (!isset($custom['folder']) && isset($custom['folderpath'])) + { + // update the dynamic path + $custom['folderpath'] = $this->dynamicpath->update( + $custom['folderpath'] + ); + + // set the folder path with / if does not have a drive/windows full path + $custom['folder'] = (preg_match( + '/^[a-z]:/i', $custom['folderpath'] + )) ? trim($custom['folderpath'], '/') + : '/' . trim($custom['folderpath'], '/'); + + // remove the file path + unset($custom['folderpath']); + + // triget fullpath + $customPath = 'full'; + } + + // make sure we use the correct name + $pathArray = (array) explode('/', (string) $custom['path']); + $lastFolder = end($pathArray); + + // only rename folder if last has folder name + if (isset($custom['rename']) && $custom['rename'] == 1) + { + $custom['path'] = str_replace( + '/' . $lastFolder, '', (string) $custom['path'] + ); + $rename = 'new'; + $newname = $lastFolder; + } + elseif ('full' === $customPath) + { + // make sure we use the correct name + $folderArray = (array) explode('/', (string) $custom['folder']); + $lastFolder = end($folderArray); + $rename = 'new'; + $newname = $lastFolder; + } + else + { + $rename = false; + $newname = ''; + } + + // insure we have no duplicates + $key_pointer = StringHelper::safe( + $custom['folder'] + ) . '_f' . $pointer_tracker; + + $pointer_tracker++; + + // fix custom path + $custom['path'] = ltrim((string) $custom['path'], '/'); + + // set new folder to object + $versionData->move->static->{$key_pointer} = new \stdClass(); + $versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['folder']); + $versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path']; + $versionData->move->static->{$key_pointer}->rename = $rename; + $versionData->move->static->{$key_pointer}->newName = $newname; + $versionData->move->static->{$key_pointer}->type = 'folder'; + $versionData->move->static->{$key_pointer}->custom = $customPath; + + // set the target if type and id is found + if (isset($custom['target_id']) && isset($custom['target_type'])) + { + $versionData->move->static->{$key_pointer}->_target = [ + 'key' => $custom['target_id'] . '_' . $custom['target_type'], + 'type' => $custom['target_type'] + ]; + } + } + + $this->component->remove('folders'); + } + + /** + * Add Files + * + * @param object $versionData + * + * @return void + * @since 3.2.0 + */ + private function addFiles(object &$versionData) + { + if (!$this->component->isArray('files')) { + return; + } + + // pointer tracker + $pointer_tracker = 'h'; + foreach ($this->component->get('files') as $custom) + { + // check type of target type + $_target_type = 'c0mp0n3nt'; + if (isset($custom['target_type'])) + { + $_target_type = $custom['target_type']; + } + + // for good practice + $this->pathfix->set( + $custom, ['path', 'file', 'filepath'] + ); + + // by default custom path is true + $customPath = 'custom'; + + // set full path if this is a full path file + if (!isset($custom['file']) && isset($custom['filepath'])) + { + // update the dynamic path + $custom['filepath'] = $this->dynamicpath->update( + $custom['filepath'] + ); + + // set the file path with / if does not have a drive/windows full path + $custom['file'] = (preg_match('/^[a-z]:/i', $custom['filepath'])) + ? trim($custom['filepath'], '/') : '/' . trim($custom['filepath'], '/'); + + // remove the file path + unset($custom['filepath']); + + // triget fullpath + $customPath = 'full'; + } + + // make sure we have not duplicates + $key_pointer = StringHelper::safe( + $custom['file'] + ) . '_g' . $pointer_tracker; + + $pointer_tracker++; + + // set new file to object + $versionData->move->static->{$key_pointer} = new \stdClass(); + $versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['file']); + + // update the dynamic component name placholders in file names + $custom['path'] = $this->placeholder->update_( + $custom['path'] + ); + + // get the path info + $pathInfo = pathinfo((string) $custom['path']); + if (isset($pathInfo['extension']) && $pathInfo['extension']) + { + $pathInfo['dirname'] = trim($pathInfo['dirname'], '/'); + + // set the info + $versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $pathInfo['dirname']; + $versionData->move->static->{$key_pointer}->rename = 'new'; + $versionData->move->static->{$key_pointer}->newName = $pathInfo['basename']; + } + elseif ('full' === $customPath) + { + // fix custom path + $custom['path'] = ltrim((string) $custom['path'], '/'); + + // get file array + $fileArray = (array) explode('/', (string) $custom['file']); + + // set the info + $versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path']; + $versionData->move->static->{$key_pointer}->rename = 'new'; + $versionData->move->static->{$key_pointer}->newName = end($fileArray); + } + else + { + // fix custom path + $custom['path'] = ltrim((string) $custom['path'], '/'); + + // set the info + $versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path']; + $versionData->move->static->{$key_pointer}->rename = false; + } + + $versionData->move->static->{$key_pointer}->type = 'file'; + $versionData->move->static->{$key_pointer}->custom = $customPath; + + // set the target if type and id is found + if (isset($custom['target_id']) + && isset($custom['target_type'])) + { + $versionData->move->static->{$key_pointer}->_target = [ + 'key' => $custom['target_id'] . '_' . $custom['target_type'], + 'type' => $custom['target_type'] + ]; + } + + // check if file should be updated + if (!isset($custom['notnew']) || $custom['notnew'] == 0 + || $custom['notnew'] != 1) + { + $this->registry->appendArray('files.not.new', $key_pointer); + } + else + { + // update the file content + $this->registry->set('update.file.content.' . $key_pointer, true); + } + } + + $this->component->remove('files'); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structure.php new file mode 100644 index 000000000..dee9d57c4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structure.php @@ -0,0 +1,117 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Component\Settings; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Build/Create Component Structure + * + * @since 3.2.0 + */ +final class Structure +{ + /** + * Compiler Component Joomla Version Settings + * + * @var Settings + * @since 3.2.0 + */ + protected Settings $settings; + + /** + * Compiler Paths + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * Compiler Utilities Folder + * + * @var Folder + * @since 3.2.0 + */ + protected Folder $folder; + + /** + * Constructor + * + * @param Settings|null $settings The compiler component joomla version settings object. + * @param Paths|null $paths The compiler paths object. + * @param Folder|null $folder The compiler folder object. + * + * @since 3.2.0 + */ + public function __construct(?Settings $settings = null, ?Paths $paths = null, ?Folder $folder = null) + { + $this->settings = $settings ?: Compiler::_('Component.Settings'); + $this->paths = $paths ?: Compiler::_('Utilities.Paths'); + $this->folder = $folder ?: Compiler::_('Utilities.Folder'); + } + + /** + * Build the Component Structure + * + * @return bool + * @since 3.2.0 + */ + public function build(): bool + { + if ($this->settings->exists()) + { + // setup the main component path + $this->folder->create($this->paths->component_path); + + // build the version structure + $this->folders( + $this->settings->structure(), + $this->paths->component_path + ); + + return true; + } + + return false; + } + + /** + * Create the folder and subfolders + * + * @param object $folders The object[] of folders + * @param string $path The path + * + * @return void + * @since 3.2.0 + */ + protected function folders(object $folders, string $path) + { + foreach ($folders as $folder => $sub_folders) + { + $new_path = $path . '/' . $folder; + $this->folder->create($new_path); + + if (ObjectHelper::check($sub_folders)) + { + $this->folders($sub_folders, $new_path); + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structuremultiple.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structuremultiple.php new file mode 100644 index 000000000..4bd1fc9a8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structuremultiple.php @@ -0,0 +1,354 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Component\Settings; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Componentbuilder\Compiler\Model\Createdate; +use VDM\Joomla\Componentbuilder\Compiler\Model\Modifieddate; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; + + +/** + * Multiple Files and Folders Builder Class + * + * @since 3.2.0 + */ +final class Structuremultiple +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Component Joomla Version Settings + * + * @var Settings + * @since 3.2.0 + */ + protected Settings $settings; + + /** + * Compiler Component + * + * @var Component + * @since 3.2.0 + **/ + protected Component $component; + + /** + * Compiler Model Createdate + * + * @var Createdate + * @since 3.2.0 + **/ + protected Createdate $createdate; + + /** + * Compiler Model Modifieddate + * + * @var Modifieddate + * @since 3.2.0 + **/ + protected Modifieddate $modifieddate; + + /** + * Compiler Utility to Build Structure + * + * @var Structure + * @since 3.2.0 + **/ + protected Structure $structure; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param Settings|null $settings The compiler component Joomla version settings object. + * @param Component|null $component The component class. + * @param Createdate|null $createdate The compiler model to get create date class. + * @param Modifieddate|null $modifieddate The compiler model to get modified date class. + * @param Structure|null $structure The compiler structure to build dynamic folder and files class. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Registry $registry = null, + ?Settings $settings = null, ?Component $component = null, + ?Createdate $createdate = null, ?Modifieddate $modifieddate = null, + ?Structure $structure = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->settings = $settings ?: Compiler::_('Component.Settings'); + $this->component = $component ?: Compiler::_('Component'); + $this->createdate = $createdate ?: Compiler::_('Model.Createdate'); + $this->modifieddate = $modifieddate ?: Compiler::_('Model.Modifieddate'); + $this->structure = $structure ?: Compiler::_('Utilities.Structure'); + } + + /** + * Build the Multiple Files & Folders + * + * @return bool + * @since 3.2.0 + */ + public function build(): bool + { + $success = false; + + if ($this->settings->exists()) + { + $success = $this->admin(); + $success = $this->site() || $success; + $success = $this->custom() || $success; + } + + return $success; + } + + /** + * Build the Dynamic Admin Files & Folders + * + * @return bool + * @since 3.2.0 + */ + protected function admin(): bool + { + if (!$this->component->isArray('admin_views')) + { + return false; + } + + // check if we have a dynamic dashboard + if (!$this->registry->get('build.dashboard')) + { + // setup the default dashboard + $target = ['admin' => $this->component->get('name_code')]; + $this->structure->build($target, 'dashboard'); + } + + $config = []; + $checkin = false; + + foreach ($this->component->get('admin_views') as $view) + { + if (!$this->isValidAdminView($view, $config)) + { + continue; + } + + $this->buildAdminView($view, $config); + + // quick set of checkin once + if (!$checkin && isset($view['checkin']) && $view['checkin'] == 1) + { + // switch to add checking to config + $checkin = true; + $this->config->set('add_checkin', $checkin); + } + } + + return true; + } + + /** + * Build the Dynamic Site Files & Folders + * + * @return bool + * @since 3.2.0 + */ + protected function site(): bool + { + if (!$this->component->isArray('site_views')) + { + return false; + } + + $config = []; + + foreach ($this->component->get('site_views') as $view) + { + if (!$this->isValidView($view, $config)) + { + continue; + } + + $this->buildView($view, $config, 'site'); + } + + return true; + } + + /** + * Build the Dynamic Custom Admin Files & Folders + * + * @return bool + * @since 3.2.0 + */ + protected function custom(): bool + { + if (!$this->component->isArray('custom_admin_views')) + { + return false; + } + + $config = []; + + foreach ($this->component->get('custom_admin_views') as $view) + { + if (!$this->isValidView($view, $config)) + { + continue; + } + + $this->buildView($view, $config, 'custom_admin'); + } + + return true; + } + + /** + * Check if the view is a valid view + * + * @param array $view + * @param array $config + * + * @return bool + * @since 3.2.0 + */ + private function isValidAdminView(array $view, array &$config): bool + { + if (!isset($view['settings']) || !ObjectHelper::check($view['settings']) + || ((!isset($view['settings']->name_list) || $view['settings']->name_list == 'null') + && (!isset($view['settings']->name_single) || $view['settings']->name_single == 'null'))) + { + return false; + } + + $created = $this->createdate->get($view); + $modified = $this->modifieddate->get($view); + + $config = [ + Placefix::_h('CREATIONDATE') => $created, + Placefix::_h('BUILDDATE') => $modified, + Placefix::_h('VERSION') => $view['settings']->version + ]; + + return true; + } + + /** + * Check if the view is a valid view + * + * @param array $view + * @param array $config + * + * @return bool + * @since 3.2.0 + */ + private function isValidView(array $view, array &$config): bool + { + if (!isset($view['settings']) || !ObjectHelper::check($view['settings']) + || !isset($view['settings']->main_get) + || !ObjectHelper::check($view['settings']->main_get) + || !isset($view['settings']->main_get->gettype) + || ($view['settings']->main_get->gettype != 1 && $view['settings']->main_get->gettype != 2)) + { + return false; + } + + $created = $this->createdate->get($view); + $modified = $this->modifieddate->get($view); + + $config = [ + Placefix::_h('CREATIONDATE') => $created, + Placefix::_h('BUILDDATE') => $modified, + Placefix::_h('VERSION') => $view['settings']->version + ]; + + return true; + } + + /** + * Build the admin view + * + * @param array $view + * @param array $config + * + * @return void + * @since 3.2.0 + */ + private function buildAdminView(array $view, array $config) + { + // build the admin edit view + if ($view['settings']->name_single != 'null') + { + $target = ['admin' => $view['settings']->name_single]; + $this->structure->build($target, 'single', false, $config); + + // build the site edit view (of this admin view) + if (isset($view['edit_create_site_view']) + && is_numeric($view['edit_create_site_view']) + && $view['edit_create_site_view'] > 0) + { + // setup the front site edit-view files + $target = ['site' => $view['settings']->name_single]; + $this->structure->build($target, 'edit', false, $config); + } + } + + // build the list view + if ($view['settings']->name_list != 'null') + { + $target = ['admin' => $view['settings']->name_list]; + $this->structure->build($target, 'list', false, $config); + } + } + + /** + * Build the custom view + * + * @param array $view + * @param array $config + * @param string $type + * + * @return void + * @since 3.2.0 + */ + private function buildView(array $view, array $config, string $type) + { + $target = [$type => $view['settings']->code]; + $view_type = ($view['settings']->main_get->gettype == 1) ? 'single' : 'list'; + + $this->structure->build($target, $view_type, false, $config); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structuresingle.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structuresingle.php new file mode 100644 index 000000000..7f9b33d22 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Structuresingle.php @@ -0,0 +1,620 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Component; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Filesystem\File; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Component\Settings; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Single Files and Folders Builder Class + * + * @since 3.2.0 + */ +final class Structuresingle +{ + /** + * The new name + * + * @var string + * @since 3.2.0 + */ + protected string $newName; + + /** + * Current Full Path + * + * @var string + * @since 3.2.0 + */ + protected string $currentFullPath; + + /** + * Package Full Path + * + * @var string + * @since 3.2.0 + */ + protected string $packageFullPath; + + /** + * ZIP Full Path + * + * @var string + * @since 3.2.0 + */ + protected string $zipFullPath; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Registry Class. + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * The Settings Class. + * + * @var Settings + * @since 3.2.0 + */ + protected Settings $settings; + + /** + * The Component Class. + * + * @var Component + * @since 3.2.0 + */ + protected Component $component; + + /** + * The ContentOne Class. + * + * @var Content + * @since 3.2.0 + */ + protected Content $content; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * The Paths Class. + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * The Files Class. + * + * @var Files + * @since 3.2.0 + */ + protected Files $files; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Registry $registry The Registry Class. + * @param Settings $settings The Settings Class. + * @param Component $component The Component Class. + * @param Content $content The ContentOne Class. + * @param Counter $counter The Counter Class. + * @param Paths $paths The Paths Class. + * @param Files $files The Files Class. + * @param CMSApplication|null $app The CMS Application object. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Registry $registry, Settings $settings, + Component $component, Content $content, Counter $counter, + Paths $paths, Files $files, ?CMSApplication $app = null) + { + $this->config = $config; + $this->registry = $registry; + $this->settings = $settings; + $this->component = $component; + $this->content = $content; + $this->counter = $counter; + $this->paths = $paths; + $this->files = $files; + $this->app = $app ?: Factory::getApplication(); + } + + /** + * Build the Single Files & Folders + * + * @return bool + * @since 3.2.0 + */ + public function build(): bool + { + if ($this->settings->exists()) + { + // TODO needs more looking at this must be dynamic actually + $this->registry->appendArray('files.not.new', 'LICENSE.txt'); + + // do license check + $LICENSE = $this->doLicenseCheck(); + + // do README check + $README = $this->doReadmeCheck(); + + // do CHANGELOG check + $CHANGELOG = $this->doChangelogCheck(); + + // start moving + foreach ($this->settings->single() as $target => $details) + { + // if not gnu/gpl license dont add the LICENSE.txt file + if ($details->naam === 'LICENSE.txt' && !$LICENSE) + { + continue; + } + + // if not needed do not add + if (($details->naam === 'README.md' || $details->naam === 'README.txt') + && !$README) + { + continue; + } + + // if not needed do not add + if ($details->naam === 'CHANGELOG.md' && !$CHANGELOG) + { + continue; + } + + // set new name + $this->setNewName($details); + + // set all paths + $this->setPaths($details); + + // check if the path exists + if ($this->pathExist($details)) + { + // set the target + $this->setTarget($target, $details); + } + + // set dynamic target as needed + $this->setDynamicTarget($details); + } + + return true; + } + + return false; + } + + /** + * Check if license must be added + * + * @return bool + * @since 3.2.0 + */ + private function doLicenseCheck(): bool + { + $licenseChecker = strtolower((string) $this->component->get('license', '')); + + if (strpos($licenseChecker, 'gnu') !== false + && strpos( + $licenseChecker, '2' + ) !== false + && (strpos($licenseChecker, 'gpl') !== false + || strpos( + $licenseChecker, 'general public license' + ) !== false)) + { + return true; + } + + return false; + } + + /** + * Check if readme must be added + * + * @return bool + * @since 3.2.0 + */ + private function doReadmeCheck(): bool + { + return (bool) $this->component->get('addreadme', false); + } + + /** + * Check if changelog must be added + * + * @return bool + * @since 3.2.0 + */ + private function doChangelogCheck(): bool + { + return (bool) $this->component->get('changelog', false); + } + + /** + * Set the new name + * + * @param object $details + * + * @return void + * @since 3.2.0 + */ + private function setNewName(object $details) + { + // do the file renaming + if (isset($details->rename) && $details->rename) + { + if ($details->rename === 'new') + { + $this->newName = $details->newName; + } + else + { + $this->newName = str_replace( + $details->rename, + $this->config->component_code_name, + (string) $details->naam + ); + } + } + else + { + $this->newName = $details->naam; + } + } + + /** + * Set all needed paths + * + * @param object $details + * + * @return void + * @since 3.2.0 + */ + private function setPaths(object $details) + { + // check if we have a target value + if (isset($details->_target)) + { + // set destination path + $zipPath = str_replace( + $details->_target['type'] . '/', '', (string) $details->path + ); + $path = str_replace( + $details->_target['type'] . '/', + $this->registry->get('dynamic_paths.' . $details->_target['key'], '') . '/', + (string) $details->path + ); + } + else + { + // set destination path + $zipPath = str_replace('c0mp0n3nt/', '', (string) $details->path); + $path = str_replace( + 'c0mp0n3nt/', $this->paths->component_path . '/', (string) $details->path + ); + } + + // set the template folder path + $templatePath = (isset($details->custom) && $details->custom) + ? (($details->custom !== 'full') ? $this->paths->template_path_custom + . '/' : '') : $this->paths->template_path . '/'; + + // set the final paths + $currentFullPath = (preg_match('/^[a-z]:/i', (string) $details->naam)) ? $details->naam + : $templatePath . '/' . $details->naam; + + $this->currentFullPath = str_replace('//', '/', (string) $currentFullPath); + + $this->packageFullPath = str_replace('//', '/', $path . '/' . $this->newName); + + $this->zipFullPath = str_replace( + '//', '/', $zipPath . '/' . $this->newName + ); + } + + /** + * Check if path exists + * + * @param object $details + * + * @return bool + * @since 3.2.0 + */ + private function pathExist(object $details): bool + { + // check if this has a type + if (!isset($details->type)) + { + return false; + } + // take action based on type + elseif ($details->type === 'file' && !File::exists($this->currentFullPath)) + { + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEFILE_PATH_ERRORHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_FILE_PATH_BSB_DOES_NOT_EXIST_AND_WAS_NOT_ADDED', + $this->currentFullPath + ), 'Error' + ); + + return false; + } + elseif ($details->type === 'folder' && !Folder::exists($this->currentFullPath)) + { + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEFOLDER_PATH_ERRORHTHREE'), + 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_FOLDER_PATH_BSB_DOES_NOT_EXIST_AND_WAS_NOT_ADDED', + $this->currentFullPath + ), 'Error' + ); + + return false; + } + + return true; + } + + /** + * Set the target based on target type + * + * @param string $target + * @param object $details + * + * @return void + * @since 3.2.0 + */ + private function setTarget(string $target, object $details) + { + // take action based on type + if ($details->type === 'file') + { + // move the file + $this->moveFile(); + + // register the file + $this->registerFile($target, $details); + } + elseif ($details->type === 'folder') + { + // move the folder to its place + Folder::copy( + $this->currentFullPath, $this->packageFullPath, '', true + ); + + // count the folder created + $this->counter->folder++; + } + } + + /** + * Move/Copy the file into place + * + * @return void + * @since 3.2.0 + */ + private function moveFile() + { + // get base name && get the path only + $packageFullPath0nly = str_replace( + basename($this->packageFullPath), '', $this->packageFullPath + ); + + // check if path exist, if not creat it + if (!Folder::exists($packageFullPath0nly)) + { + Folder::create($packageFullPath0nly); + } + + // move the file to its place + File::copy($this->currentFullPath, $this->packageFullPath); + + // count the file created + $this->counter->file++; + } + + /** + * Register the file + * + * @param string $target + * @param object $details + * + * @return void + * @since 3.2.0 + */ + private function registerFile(string $target, object $details) + { + // store the new files + if (!in_array($target, $this->registry->get('files.not.new', []))) + { + if (isset($details->_target)) + { + $this->files->appendArray($details->_target['key'], + [ + 'path' => $this->packageFullPath, + 'name' => $this->newName, + 'zip' => $this->zipFullPath + ] + ); + } + else + { + $this->files->appendArray('static', + [ + 'path' => $this->packageFullPath, + 'name' => $this->newName, + 'zip' => $this->zipFullPath + ] + ); + } + } + + // ensure we update this file if needed + if ($this->registry->exists('update.file.content.' . $target)) + { + // remove the pointer + $this->registry->remove('update.file.content.' . $target); + + // set the full path + $this->registry->set('update.file.content.' . $this->packageFullPath, $this->packageFullPath); + } + } + + /** + * Set Dynamic Target + * + * @param object $details + * + * @return void + * @since 3.2.0 + */ + private function setDynamicTarget(object $details) + { + // only add if no target found since those belong to plugins and modules + if (!isset($details->_target)) + { + // check if we should add the dynamic folder moving script to the installer script + $checker = array_values((array) explode('/', $this->zipFullPath)); + + // TODO <-- this may not be the best way, will keep an eye on this. + // We basicly only want to check if a folder is added that is not in the stdFolders array + if (isset($checker[0]) + && StringHelper::check($checker[0]) + && !$this->settings->standardFolder($checker[0])) + { + // activate dynamic folders + $this->setDynamicFolders(); + } + elseif (count((array) $checker) == 2 + && StringHelper::check($checker[0])) + { + $add_to_extra = false; + + // set the target + $eNAME = 'FILES'; + $ename = 'filename'; + + // this should not happen and must have been caught by the above if statment + if ($details->type === 'folder') + { + // only folders outside the standard folder are added + $eNAME = 'FOLDERS'; + $ename = 'folder'; + $add_to_extra = true; + } + // if this is a file, it can only be added to the admin/site/media folders + // all other folders are moved as a whole so their files do not need to be declared + elseif ($this->settings->standardFolder($checker[0]) + && !$this->settings->standardRootFile($checker[1])) + { + $add_to_extra = true; + } + + // add if valid folder/file + if ($add_to_extra) + { + // set the tab + $eTab = Indent::_(2); + if ('admin' === $checker[0]) + { + $eTab = Indent::_(3); + } + + // set the xml file + $key_ = 'EXSTRA_' + . StringHelper::safe( + $checker[0], 'U' + ) . '_' . $eNAME; + $this->content->add($key_, + PHP_EOL . $eTab . "<" . $ename . ">" + . $checker[1] . ""); + } + } + } + } + + /** + * Add the dynamic folders + * + * @return void + * @since 3.2.0 + */ + private function setDynamicFolders() + { + // check if we should add the dynamic folder moving script to the installer script + if (!$this->registry->get('set_move_folders_install_script')) + { + // add the setDynamicF0ld3rs() method to the install scipt.php file + $this->registry->set('set_move_folders_install_script', true); + + // set message that this was done (will still add a tutorial link later) + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDYNAMIC_FOLDERS_WERE_DETECTEDHTHREE'), + 'Notice' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_A_METHOD_SETDYNAMICFZEROLDTHREERS_WAS_ADDED_TO_THE_INSTALL_BSCRIPTPHPB_OF_THIS_PACKAGE_TO_INSURE_THAT_THE_FOLDERS_ARE_COPIED_INTO_THE_CORRECT_PLACE_WHEN_THIS_COMPONENT_IS_INSTALLED'), + 'Notice' + ); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php new file mode 100644 index 000000000..475959753 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php @@ -0,0 +1,1010 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use Joomla\Registry\Registry as JoomlaRegistry; +use Joomla\CMS\Factory as JoomlaFactory; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Abstraction\BaseConfig; + + +/** + * Compiler Configurations + * + * All these functions are accessed via the direct name without the get: + * example: $this->component_code_name calls: $this->getComponentcodename() + * + * All values once called are cached, yet can be updated directly: + * example: $this->component_code_name = 'new_code_name'; // be warned! + * + * @since 3.2.0 + */ +class Config extends BaseConfig +{ + /** + * The Global Joomla Configuration + * + * @var JoomlaRegistry + * @since 3.2.0 + */ + protected JoomlaRegistry $config; + + /** + * Constructor + * + * @param Input|null $input Input + * @param Registry|null $params The component parameters + * @param Registry|null $config The Joomla configuration + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Input $input = null, ?JoomlaRegistry $params = null, ?JoomlaRegistry $config = null) + { + parent::__construct($input, $params); + + $this->config = $config ?: JoomlaFactory::getConfig(); + } + + /** + * get Gitea Access Token + * + * @return string the access token + * @since 3.2.0 + */ + protected function getGiteatoken(): ?string + { + return $this->custom_gitea_token ?? $this->params->get('gitea_token'); + } + + /** + * get Add Custom Gitea URL + * + * @return int the add switch + * @since 3.2.0 + */ + protected function getAddcustomgiteaurl(): int + { + return $this->params->get('add_custom_gitea_url', 1); + } + + /** + * get Custom Gitea URL + * + * @return string the custom gitea url + * @since 3.2.0 + */ + protected function getCustomgiteaurl(): ?string + { + if ($this->add_custom_gitea_url == 2) + { + return $this->params->get('custom_gitea_url'); + } + + return null; + } + + /** + * get Custom Gitea Access Token + * + * @return string the custom access token + * @since 3.2.0 + */ + protected function getCustomgiteatoken(): ?string + { + if ($this->add_custom_gitea_url == 2) + { + return $this->params->get('custom_gitea_token'); + } + + return null; + } + + /** + * Get super power core organisation + * + * @return string The super power core organisation + * @since 3.2.0 + */ + protected function getSuperpowerscoreorganisation(): string + { + // the VDM default organisation is [joomla] + $organisation = 'joomla'; + + if ($this->add_custom_gitea_url == 2) + { + return $this->params->get('super_powers_core_organisation', $organisation); + } + + return $organisation; + } + + /** + * Get super power core repos + * + * @return array The core repositories on Gitea + * @since 3.2.0 + */ + protected function getSuperpowerscorerepos(): array + { + // some defaults repos we need by JCB + $repos = []; + + // only add custom init with custom gitea + $paths = null; + if ($this->add_custom_gitea_url == 2) + { + $paths = $this->params->get('super_powers_core_repos'); + } + + if (!empty($paths) && is_array($paths)) + { + foreach ($paths as $path) + { + $owner = $path->owner ?? null; + $repo = $path->repo ?? null; + if ($owner !== null && $repo !== null) + { + // we make sure to get only the objects + $repos = ["{$owner}.{$repo}" => $path] + $repos; + } + } + } + else + { + $repos[$this->super_powers_core_organisation . '.super-powers'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'super-powers', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.jcb-compiler'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'jcb-compiler', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.jcb-packager'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'jcb-packager', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.phpseclib'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'phpseclib', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.search'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'search', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.gitea'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'gitea', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.openai'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'openai', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.minify'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'minify', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.psr'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'psr', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.fof'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'fof', 'branch' => 'master']; + } + + return $repos; + } + + /** + * get add contributors switch + * + * @return bool Add contributors switch + * @since 3.2.0 + */ + protected function getAddcontributors(): bool + { + return false; // default is false + } + + /** + * get Add Ajax Switch + * + * @return bool Add Ajax Switch + * @since 3.2.0 + */ + protected function getAddajax(): bool + { + return false; // default is false + } + + /** + * get Add Site Ajax Switch + * + * @return bool Add Site Ajax Switch + * @since 3.2.0 + */ + protected function getAddsiteajax(): bool + { + return false; // default is false + } + + /** + * get add eximport + * + * @return bool add eximport switch + * @since 3.2.0 + */ + protected function getAddeximport(): bool + { + return false; // default is false + } + + /** + * get add checkin + * + * @return bool add checkin switch + * @since 3.2.0 + */ + protected function getAddcheckin(): bool + { + return false; // default is false + } + + /** + * get posted component id + * + * @return int Component id + * @since 3.2.0 + */ + protected function getComponentid(): int + { + return $this->input->post->get('component_id', 0, 'INT'); + } + + /** + * get component version + * + * @return string Component version + * @since 3.2.0 + */ + protected function getComponentversion(): string + { + return '1.0.0'; + } + + /** + * get components code name + * + * @return string The components code name + * @since 3.2.0 + */ + protected function getComponentcodename(): string + { + // get components code name + return StringHelper::safe(GetHelper::var( + 'joomla_component', $this->component_id, 'id', 'name_code' + )); + } + + /** + * get component context + * + * @return string The component context + * @since 3.2.0 + */ + protected function getComponentcontext(): string + { + // get component context + return $this->component_code_name . '.' . $this->component_id; + } + + /** + * get component code name length + * + * @return int The component code name length + * @since 3.2.0 + */ + protected function getComponentcodenamelength(): int + { + // get component name length + return strlen((string) $this->component_code_name); + } + + /** + * get posted Joomla version + * + * @return int Joomla version code + * @since 3.2.0 + */ + protected function getJoomlaversion(): int + { + return 3; // $this->input->post->get('joomla_version', 3, 'INT'); + } + + /** + * get Joomla versions + * + * @return array Joomla versions + * @since 3.2.0 + */ + protected function getJoomlaversions(): array + { + return [ + 3 => ['folder_key' => 3, 'xml_version' => 3.9], // only joomla 3 + 3.10 => ['folder_key' => 3, 'xml_version' => 4.0] // legacy joomla 4 + ]; + } + + /** + * get posted Joomla version name + * + * @return string Joomla version code name + * @since 3.2.0 + */ + protected function getJoomlaversionname(): string + { + return StringHelper::safe($this->joomla_version); + } + + /** + * set joomla fields + * + * @return bool set joomla fields + * @since 3.2.0 + */ + protected function getSetjoomlafields(): bool + { + return false; + } + + /** + * get show advanced options switch + * + * @return bool show advanced options + * @since 3.2.0 + */ + protected function getShowadvancedoptions(): bool + { + return (bool) $this->input->post->get('show_advanced_options', 0, 'INT'); + } + + /** + * get indentation value + * + * @return string Indentation value + * @since 3.2.0 + */ + protected function getIndentationvalue(): string + { + // if advanced options is active + if ($this->show_advanced_options) + { + $indentation_value = $this->input->post->get('indentation_value', 1, 'INT'); + + switch($indentation_value) + { + case 2: + // two spaces + return " "; + break; + case 4: + // four spaces + return " "; + break; + } + } + + return "\t"; + } + + /** + * get add build date switch + * + * @return int add build date options + * @since 3.2.0 + */ + protected function getAddbuilddate(): int + { + // if advanced options is active + if ($this->show_advanced_options) + { + // 1=default 2=manual 3=component + return $this->input->post->get('add_build_date', 1, 'INT'); + } + + return 1; + } + + /** + * get build date + * + * @return string build date + * @since 3.2.0 + */ + protected function getBuilddate(): string + { + // if advanced options is active and manual date selected + if ($this->show_advanced_options && $this->add_build_date == 2) + { + return $this->input->post->get('build_date', 'now', 'STRING'); + } + + return "now"; + } + + /** + * get posted backup switch + * + * @return int Backup switch number + * @since 3.2.0 + */ + protected function getBackup(): int + { + return $this->input->post->get('backup', 0, 'INT'); + } + + /** + * get posted repository switch + * + * @return int Repository switch number + * @since 3.2.0 + */ + protected function getRepository(): int + { + return $this->input->post->get('repository', 0, 'INT'); + } + + /** + * get posted debuglinenr switch + * + * @return int Debuglinenr switch number + * @since 3.2.0 + */ + protected function getDebuglinenr(): int + { + // get posted value + $value = $this->input->post->get('debug_line_nr', 2, 'INT'); + // get global value + if ($value > 1) + { + return (int) GetHelper::var('joomla_component', $this->component_id, 'id', 'debug_linenr'); + } + return $value; + } + + /** + * get posted minify switch + * + * @return int Minify switch number + * @since 3.2.0 + */ + protected function getMinify(): int + { + // get posted value + $minify = $this->input->post->get('minify', 2, 'INT'); + + // if value is 2 use global value + return ($minify != 2) ? $minify : $this->params->get('minify', 0); + } + + /** + * get posted remove line breaks switch + * + * @return bool Remove line breaks switch number + * @since 3.2.0 + */ + protected function getRemovelinebreaks(): bool + { + // get posted value + $value = $this->input->post->get('remove_line_breaks', 2, 'INT'); + // get global + if ($value > 1) + { + return (bool) GetHelper::var('joomla_component', $this->component_id, 'id', 'remove_line_breaks'); + } + return (bool) $value; + } + + /** + * get system tidy state + * + * @return bool Tidy is active + * @since 3.2.0 + */ + protected function getTidy(): bool + { + // check if we have Tidy enabled + return \extension_loaded('Tidy'); + } + + /** + * add tidy warning + * + * @return bool Set tidy warning + * @since 3.2.0 + */ + protected function getSettidywarning(): bool + { + // add warning once + return true; + } + + /** + * get history tag switch + * + * @return bool get history tag switch + * @since 3.2.0 + */ + protected function getSettaghistory(): bool + { + // add warning once + return true; + } + + /** + * get language tag + * + * @return string The active language tag + * @since 3.2.0 + */ + protected function getLangtag(): string + { + // get the global language + return $this->params->get('language', 'en-GB'); + } + + /** + * get language prefix + * + * @return string The language prefix + * @since 3.2.0 + */ + protected function getLangprefix(): string + { + // get components code name + return 'COM_' . StringHelper::safe(GetHelper::var( + 'joomla_component', $this->component_id, 'id', 'name_code' + ), 'U'); + } + + /** + * get language target + * + * @return string The language active target + * @since 3.2.0 + */ + protected function getLangtarget(): string + { + // we start with admin + // but this is a switch value and is changed many times + return 'admin'; + } + + /** + * get language string targets + * + * @return array The language prefix + * @since 3.2.0 + */ + protected function getLangstringtargets(): array + { + // these strings are used to search for language strings in all content + return array_values($this->lang_string_key_targets); + } + + /** + * get language string targets (by key name) + * + * @return array The language prefix + * @since 3.2.0 + */ + protected function getLangstringkeytargets(): array + { + // these strings are used to search for language strings in all content + return [ + 'jjt' => 'Joomla' . '.JText._(', + 'js' => 'JText:' . ':script(', + 't' => 'Text:' . ':_(', // namespace and J version will be found + 'ts' => 'Text:' . ':sprintf(', // namespace and J version will be found + 'jt' => 'JustTEXT:' . ':_(' + ]; + } + + /** + * get field builder type + * + * @return int The field builder type + * @since 3.2.0 + */ + protected function getFieldbuildertype(): int + { + // get the field type builder + return $this->params->get( + 'compiler_field_builder_type', 2 + ); + } + + /** + * get default fields + * + * @return array The default fields + * @since 3.2.0 + */ + protected function getDefaultfields(): array + { + // get the field type builder + return ['created', 'created_by', 'modified', 'modified_by', 'published', + 'ordering', 'access', 'version', 'hits', 'id']; + } + + /** + * get temporary path + * + * @return string The temporary path + * @since 3.2.0 + */ + protected function getTmppath(): string + { + // get the temporary path + return $this->config->get('tmp_path'); + } + + /** + * get compiler path + * + * @return string The compiler path + * @since 3.2.0 + */ + protected function getCompilerpath(): string + { + // get the compiler path + return $this->params->get( + 'compiler_folder_path', + JPATH_COMPONENT_ADMINISTRATOR . '/compiler' + ); + } + + /** + * get jcb powers path + * + * @return string The jcb powers path + * @since 3.2.0 + */ + protected function getJcbpowerspath(): string + { + // get jcb powers path + return $this->params->get('jcb_powers_path', 'libraries/jcb_powers'); + } + + /** + * Get local super powers repository path + * + * @return string The path to the local repository + * @since 3.2.0 + */ + protected function getLocalpowersrepositorypath(): string + { + $default = $this->tmp_path . '/super_powers'; + + if (!$this->add_super_powers) + { + return $default; + } + + $global = $this->params->get('local_powers_repository_path', $default); + + if (!$this->show_advanced_options) + { + return $global; + } + + $value = $this->input->post->get('powers_repository', 2, 'INT'); + + return $value == 1 + ? $this->input->post->get('local_powers_repository_path', $global, 'PATH') + : $global; + } + + /** + * Get super power approved paths + * + * @return array The approved paths to the repositories on Gitea + * @since 3.2.0 + */ + protected function getApprovedpaths(): array + { + // some defaults repos we need by JCB + $approved = $this->super_powers_core_repos; + + if (!$this->add_own_powers) + { + return array_values($approved); + } + + $paths = $this->params->get('approved_paths'); + + if (!empty($paths)) + { + foreach ($paths as $path) + { + $owner = $path->owner ?? null; + $repo = $path->repo ?? null; + if ($owner !== null && $repo !== null) + { + // we make sure to get only the objects + $approved = ["{$owner}.{$repo}" => $path] + $approved; + } + } + } + + return array_values($approved); + } + + /** + * get bom path + * + * @return string The bom path + * @since 3.2.0 + */ + protected function getBompath(): string + { + // get default bom path + return $this->compiler_path . '/default.txt'; + } + + /** + * get custom folder path + * + * @return string The custom folder path + * @since 3.2.0 + */ + protected function getCustomfolderpath(): string + { + // get the custom folder path + return $this->params->get( + 'custom_folder_path', + JPATH_COMPONENT_ADMINISTRATOR . '/custom' + ); + } + + /** + * get switch to add assets table fix + * + * @return int Switch number to add assets table fix + * @since 3.2.0 + */ + protected function getAddassetstablefix(): int + { + // get global add assets table fix + $global = $this->params->get( + 'assets_table_fix', 1 + ); + + // get component value + return (($add_assets_table_fix = (int) GetHelper::var( + 'joomla_component', $this->component_id, 'id', + 'assets_table_fix' + )) == 3) ? $global : $add_assets_table_fix; + } + + /** + * get switch to add assets table name fix + * + * @return bool Switch number to add assets table name fix + * @since 3.2.0 + */ + protected function getAddassetstablenamefix(): bool + { + // get global is false + return false; + } + + /** + * get access worse case size + * + * @return int access worse case size + * @since 3.2.0 + */ + protected function getAccessworsecase(): int + { + // we start at zero + return 0; + } + + /** + * get mysql table keys + * + * @return array + * @since 3.2.0 + */ + protected function getMysqltablekeys(): array + { + return [ + 'engine' => ['default' => 'MyISAM'], + 'charset' => ['default' => 'utf8'], + 'collate' => ['default' => 'utf8_general_ci'], + 'row_format' => ['default' => ''] + ]; + } + + /** + * get switch add placeholders + * + * @return bool Switch to add placeholders + * @since 3.2.0 + */ + protected function getAddplaceholders(): bool + { + // get posted value + $value = $this->input->post->get('add_placeholders', 2, 'INT'); + + // get global value + if ($value > 1) + { + return (bool) GetHelper::var('joomla_component', $this->component_id, 'id', 'add_placeholders'); + } + return (bool) $value; + } + + /** + * get switch add power + * + * @return bool Switch to add power + * @since 3.2.0 + */ + protected function getAddpower(): bool + { + // get posted value + $value = $this->input->post->get('powers', 2, 'INT'); + + // get global value + if ($value > 1) + { + return (bool) GetHelper::var('joomla_component', $this->component_id, 'id', 'add_powers'); + } + return (bool) $value; + } + + /** + * Get switch to add super powers + * + * @return bool Switch to add super powers + * @since 3.2.0 + */ + protected function getAddsuperpowers(): bool + { + $default = (bool) $this->params->get('powers_repository', 0); + + if (!$this->show_advanced_options) + { + return $default; + } + + $value = $this->input->post->get('powers_repository', 2, 'INT'); + + return $value == 2 ? $default : (bool) $value; + } + + /** + * Get switch to add own super powers + * + * @return bool Switch to add own super powers + * @since 3.2.0 + */ + protected function getAddownpowers(): bool + { + if ($this->add_super_powers) + { + return (bool) $this->params->get('super_powers_repositories', 0); + } + + return false; + } + + /** + * get switch build target switch + * + * @return string Switch to control the build flow + * @since 3.2.0 + */ + protected function getBuildtarget(): string + { + // we start with admin + // but this is a switch value and is changed many times + return 'admin'; + } + + /** + * get encryption types + * + * @return array encryption types + * @since 3.2.0 + */ + protected function getCryptiontypes(): array + { + return ['basic', 'medium', 'whmcs', 'expert']; + } + + /** + * get basic encryption switch + * + * @return bool Switch to control the encryption + * @since 3.2.0 + */ + protected function getBasicencryption(): bool + { + return false; + } + + /** + * get medium encryption switch + * + * @return bool Switch to control the encryption + * @since 3.2.0 + */ + protected function getMediumencryption(): bool + { + return false; + } + + /** + * get whmcs encryption switch + * + * @return bool Switch to control the encryption + * @since 3.2.0 + */ + protected function getWhmcsencryption(): bool + { + return false; + } + + /** + * Should we remove the site folder + * + * @return bool Switch to control the removal + * @since 3.2.0 + */ + protected function getRemovesitefolder(): bool + { + return false; + } + + /** + * Should we remove the site edit folder + * + * @return bool Switch to control the removal + * @since 3.2.0 + */ + protected function getRemovesiteeditfolder(): bool + { + return true; + } + + /** + * The Uikit switch + * + * @return int Switch to control the adding uikit + * @since 3.2.0 + */ + protected function getUikit(): int + { + return 0; // default its not added + } + + /** + * The google chart switch + * + * @return bool Switch to control the adding googlechart + * @since 3.2.0 + */ + protected function getGooglechart(): bool + { + return false; // default its not added + } + + /** + * The footable switch + * + * @return bool Switch to control the adding footable + * @since 3.2.0 + */ + protected function getFootable(): bool + { + return false; // default its not added + } + + /** + * The footable version + * + * @return int Switch to control the adding footable + * @since 3.2.0 + */ + protected function getFootableversion(): int + { + return 2; // default is version 2 + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Builders.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Builders.php new file mode 100644 index 000000000..016921747 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Builders.php @@ -0,0 +1,1290 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Application\CMSApplication; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Layout; +use VDM\Joomla\Componentbuilder\Compiler\Creator\SiteFieldData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Tags; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseTables; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseUniqueKeys; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseKeys; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseUniqueGuid; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListJoin; +use VDM\Joomla\Componentbuilder\Compiler\Builder\History; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Alias; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Title; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CategoryOtherName; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Lists; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomList; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldRelations; +use VDM\Joomla\Componentbuilder\Compiler\Builder\HiddenFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\IntegerFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DynamicFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MainTextField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomFieldLinks; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ScriptUserSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ScriptMediaSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Category; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CategoryCode; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CheckBox; +use VDM\Joomla\Componentbuilder\Compiler\Builder\JsonString; +use VDM\Joomla\Componentbuilder\Compiler\Builder\BaseSixFour; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelBasicField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelWhmcsField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelMediumField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelExpertFieldInitiator; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelExpertField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\JsonItem; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ItemsMethodListString; +use VDM\Joomla\Componentbuilder\Compiler\Builder\JsonItemArray; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ItemsMethodEximportString; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SelectionTranslation; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AdminFilterType; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Sort; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Search; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Filter; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ComponentFields; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Compiler Creator Builders + * + * @since 3.2.0 + */ +final class Builders +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Layout Class. + * + * @var Layout + * @since 3.2.0 + */ + protected Layout $layout; + + /** + * The SiteFieldData Class. + * + * @var SiteFieldData + * @since 3.2.0 + */ + protected SiteFieldData $sitefielddata; + + /** + * The Tags Class. + * + * @var Tags + * @since 3.2.0 + */ + protected Tags $tags; + + /** + * The DatabaseTables Class. + * + * @var DatabaseTables + * @since 3.2.0 + */ + protected DatabaseTables $databasetables; + + /** + * The DatabaseUniqueKeys Class. + * + * @var DatabaseUniqueKeys + * @since 3.2.0 + */ + protected DatabaseUniqueKeys $databaseuniquekeys; + + /** + * The DatabaseKeys Class. + * + * @var DatabaseKeys + * @since 3.2.0 + */ + protected DatabaseKeys $databasekeys; + + /** + * The DatabaseUniqueGuid Class. + * + * @var DatabaseUniqueGuid + * @since 3.2.0 + */ + protected DatabaseUniqueGuid $databaseuniqueguid; + + /** + * The ListJoin Class. + * + * @var ListJoin + * @since 3.2.0 + */ + protected ListJoin $listjoin; + + /** + * The History Class. + * + * @var History + * @since 3.2.0 + */ + protected History $history; + + /** + * The Alias Class. + * + * @var Alias + * @since 3.2.0 + */ + protected Alias $alias; + + /** + * The Title Class. + * + * @var Title + * @since 3.2.0 + */ + protected Title $title; + + /** + * The CategoryOtherName Class. + * + * @var CategoryOtherName + * @since 3.2.0 + */ + protected CategoryOtherName $categoryothername; + + /** + * The Lists Class. + * + * @var Lists + * @since 3.2.0 + */ + protected Lists $lists; + + /** + * The CustomList Class. + * + * @var CustomList + * @since 3.2.0 + */ + protected CustomList $customlist; + + /** + * The FieldRelations Class. + * + * @var FieldRelations + * @since 3.2.0 + */ + protected FieldRelations $fieldrelations; + + /** + * The HiddenFields Class. + * + * @var HiddenFields + * @since 3.2.0 + */ + protected HiddenFields $hiddenfields; + + /** + * The IntegerFields Class. + * + * @var IntegerFields + * @since 3.2.0 + */ + protected IntegerFields $integerfields; + + /** + * The DynamicFields Class. + * + * @var DynamicFields + * @since 3.2.0 + */ + protected DynamicFields $dynamicfields; + + /** + * The MainTextField Class. + * + * @var MainTextField + * @since 3.2.0 + */ + protected MainTextField $maintextfield; + + /** + * The CustomField Class. + * + * @var CustomField + * @since 3.2.0 + */ + protected CustomField $customfield; + + /** + * The CustomFieldLinks Class. + * + * @var CustomFieldLinks + * @since 3.2.0 + */ + protected CustomFieldLinks $customfieldlinks; + + /** + * The ScriptUserSwitch Class. + * + * @var ScriptUserSwitch + * @since 3.2.0 + */ + protected ScriptUserSwitch $scriptuserswitch; + + /** + * The ScriptMediaSwitch Class. + * + * @var ScriptMediaSwitch + * @since 3.2.0 + */ + protected ScriptMediaSwitch $scriptmediaswitch; + + /** + * The Category Class. + * + * @var Category + * @since 3.2.0 + */ + protected Category $category; + + /** + * The CategoryCode Class. + * + * @var CategoryCode + * @since 3.2.0 + */ + protected CategoryCode $categorycode; + + /** + * The CheckBox Class. + * + * @var CheckBox + * @since 3.2.0 + */ + protected CheckBox $checkbox; + + /** + * The JsonString Class. + * + * @var JsonString + * @since 3.2.0 + */ + protected JsonString $jsonstring; + + /** + * The BaseSixFour Class. + * + * @var BaseSixFour + * @since 3.2.0 + */ + protected BaseSixFour $basesixfour; + + /** + * The ModelBasicField Class. + * + * @var ModelBasicField + * @since 3.2.0 + */ + protected ModelBasicField $modelbasicfield; + + /** + * The ModelWhmcsField Class. + * + * @var ModelWhmcsField + * @since 3.2.0 + */ + protected ModelWhmcsField $modelwhmcsfield; + + /** + * The ModelMediumField Class. + * + * @var ModelMediumField + * @since 3.2.0 + */ + protected ModelMediumField $modelmediumfield; + + /** + * The ModelExpertFieldInitiator Class. + * + * @var ModelExpertFieldInitiator + * @since 3.2.0 + */ + protected ModelExpertFieldInitiator $modelexpertfieldinitiator; + + /** + * The ModelExpertField Class. + * + * @var ModelExpertField + * @since 3.2.0 + */ + protected ModelExpertField $modelexpertfield; + + /** + * The JsonItem Class. + * + * @var JsonItem + * @since 3.2.0 + */ + protected JsonItem $jsonitem; + + /** + * The ItemsMethodListString Class. + * + * @var ItemsMethodListString + * @since 3.2.0 + */ + protected ItemsMethodListString $itemsmethodliststring; + + /** + * The JsonItemArray Class. + * + * @var JsonItemArray + * @since 3.2.0 + */ + protected JsonItemArray $jsonitemarray; + + /** + * The ItemsMethodEximportString Class. + * + * @var ItemsMethodEximportString + * @since 3.2.0 + */ + protected ItemsMethodEximportString $itemsmethodeximportstring; + + /** + * The SelectionTranslation Class. + * + * @var SelectionTranslation + * @since 3.2.0 + */ + protected SelectionTranslation $selectiontranslation; + + /** + * The AdminFilterType Class. + * + * @var AdminFilterType + * @since 3.2.0 + */ + protected AdminFilterType $adminfiltertype; + + /** + * The Sort Class. + * + * @var Sort + * @since 3.2.0 + */ + protected Sort $sort; + + /** + * The Search Class. + * + * @var Search + * @since 3.2.0 + */ + protected Search $search; + + /** + * The Filter Class. + * + * @var Filter + * @since 3.2.0 + */ + protected Filter $filter; + + /** + * The ComponentFields Class. + * + * @var ComponentFields + * @since 3.2.0 + */ + protected ComponentFields $componentfields; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Language $language The Language Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Layout $layout The Layout Class. + * @param SiteFieldData $sitefielddata The SiteFieldData Class. + * @param Tags $tags The Tags Class. + * @param DatabaseTables $databasetables The DatabaseTables Class. + * @param DatabaseUniqueKeys $databaseuniquekeys The DatabaseUniqueKeys Class. + * @param DatabaseKeys $databasekeys The DatabaseKeys Class. + * @param DatabaseUniqueGuid $databaseuniqueguid The DatabaseUniqueGuid Class. + * @param ListJoin $listjoin The ListJoin Class. + * @param History $history The History Class. + * @param Alias $alias The Alias Class. + * @param Title $title The Title Class. + * @param CategoryOtherName $categoryothername The CategoryOtherName Class. + * @param Lists $lists The Lists Class. + * @param CustomList $customlist The CustomList Class. + * @param FieldRelations $fieldrelations The FieldRelations Class. + * @param HiddenFields $hiddenfields The HiddenFields Class. + * @param IntegerFields $integerfields The IntegerFields Class. + * @param DynamicFields $dynamicfields The DynamicFields Class. + * @param MainTextField $maintextfield The MainTextField Class. + * @param CustomField $customfield The CustomField Class. + * @param CustomFieldLinks $customfieldlinks The CustomFieldLinks Class. + * @param ScriptUserSwitch $scriptuserswitch The ScriptUserSwitch Class. + * @param ScriptMediaSwitch $scriptmediaswitch The ScriptMediaSwitch Class. + * @param Category $category The Category Class. + * @param CategoryCode $categorycode The CategoryCode Class. + * @param CheckBox $checkbox The CheckBox Class. + * @param JsonString $jsonstring The JsonString Class. + * @param BaseSixFour $basesixfour The BaseSixFour Class. + * @param ModelBasicField $modelbasicfield The ModelBasicField Class. + * @param ModelWhmcsField $modelwhmcsfield The ModelWhmcsField Class. + * @param ModelMediumField $modelmediumfield The ModelMediumField Class. + * @param ModelExpertFieldInitiator $modelexpertfieldinitiator The ModelExpertFieldInitiator Class. + * @param ModelExpertField $modelexpertfield The ModelExpertField Class. + * @param JsonItem $jsonitem The JsonItem Class. + * @param ItemsMethodListString $itemsmethodliststring The ItemsMethodListString Class. + * @param JsonItemArray $jsonitemarray The JsonItemArray Class. + * @param ItemsMethodEximportString $itemsmethodeximportstring The ItemsMethodEximportString Class. + * @param SelectionTranslation $selectiontranslation The SelectionTranslation Class. + * @param AdminFilterType $adminfiltertype The AdminFilterType Class. + * @param Sort $sort The Sort Class. + * @param Search $search The Search Class. + * @param Filter $filter The Filter Class. + * @param ComponentFields $componentfields The ComponentFields Class. + * @param CMSApplication|null $app The app object. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Language $language, + Placeholder $placeholder, Layout $layout, + SiteFieldData $sitefielddata, Tags $tags, + DatabaseTables $databasetables, + DatabaseUniqueKeys $databaseuniquekeys, + DatabaseKeys $databasekeys, + DatabaseUniqueGuid $databaseuniqueguid, + ListJoin $listjoin, History $history, Alias $alias, + Title $title, CategoryOtherName $categoryothername, + Lists $lists, CustomList $customlist, + FieldRelations $fieldrelations, + HiddenFields $hiddenfields, IntegerFields $integerfields, + DynamicFields $dynamicfields, + MainTextField $maintextfield, CustomField $customfield, + CustomFieldLinks $customfieldlinks, + ScriptUserSwitch $scriptuserswitch, + ScriptMediaSwitch $scriptmediaswitch, Category $category, + CategoryCode $categorycode, CheckBox $checkbox, + JsonString $jsonstring, BaseSixFour $basesixfour, + ModelBasicField $modelbasicfield, + ModelWhmcsField $modelwhmcsfield, + ModelMediumField $modelmediumfield, + ModelExpertFieldInitiator $modelexpertfieldinitiator, + ModelExpertField $modelexpertfield, JsonItem $jsonitem, + ItemsMethodListString $itemsmethodliststring, + JsonItemArray $jsonitemarray, + ItemsMethodEximportString $itemsmethodeximportstring, + SelectionTranslation $selectiontranslation, + AdminFilterType $adminfiltertype, Sort $sort, + Search $search, Filter $filter, + ComponentFields $componentfields, ?CMSApplication $app = null) + { + $this->config = $config; + $this->language = $language; + $this->placeholder = $placeholder; + $this->layout = $layout; + $this->sitefielddata = $sitefielddata; + $this->tags = $tags; + $this->databasetables = $databasetables; + $this->databaseuniquekeys = $databaseuniquekeys; + $this->databasekeys = $databasekeys; + $this->databaseuniqueguid = $databaseuniqueguid; + $this->listjoin = $listjoin; + $this->history = $history; + $this->alias = $alias; + $this->title = $title; + $this->categoryothername = $categoryothername; + $this->lists = $lists; + $this->customlist = $customlist; + $this->fieldrelations = $fieldrelations; + $this->hiddenfields = $hiddenfields; + $this->integerfields = $integerfields; + $this->dynamicfields = $dynamicfields; + $this->maintextfield = $maintextfield; + $this->customfield = $customfield; + $this->customfieldlinks = $customfieldlinks; + $this->scriptuserswitch = $scriptuserswitch; + $this->scriptmediaswitch = $scriptmediaswitch; + $this->category = $category; + $this->categorycode = $categorycode; + $this->checkbox = $checkbox; + $this->jsonstring = $jsonstring; + $this->basesixfour = $basesixfour; + $this->modelbasicfield = $modelbasicfield; + $this->modelwhmcsfield = $modelwhmcsfield; + $this->modelmediumfield = $modelmediumfield; + $this->modelexpertfieldinitiator = $modelexpertfieldinitiator; + $this->modelexpertfield = $modelexpertfield; + $this->jsonitem = $jsonitem; + $this->itemsmethodliststring = $itemsmethodliststring; + $this->jsonitemarray = $jsonitemarray; + $this->itemsmethodeximportstring = $itemsmethodeximportstring; + $this->selectiontranslation = $selectiontranslation; + $this->adminfiltertype = $adminfiltertype; + $this->sort = $sort; + $this->search = $search; + $this->filter = $filter; + $this->componentfields = $componentfields; + $this->app = $app ?: Factory::getApplication(); + } + + /** + * set Builders + * + * @param string $langLabel The language string for field label + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param string $name The field name + * @param array $view The view data + * @param array $field The field data + * @param string $typeName The field type + * @param bool $multiple The switch to set multiple selection option + * @param array|null $custom The custom field switch + * @param array|null $options The options switch + * + * @return void + * @since 3.2.0 + */ + public function set(string $langLabel, string $langView, string $nameSingleCode, + string $nameListCode, string $name, array $view, array $field, + string $typeName, bool $multiple, ?array $custom = null, + ?array $options = null): void + { + // check if this is a tag field + if ($typeName === 'tag') + { + // set tags for this view but don't load to DB + $this->tags->set($nameSingleCode, true); + } + // dbSwitch + $dbSwitch = true; + if (isset($field['list']) && $field['list'] == 2) + { + // do not add this field to the database + $dbSwitch = false; + } + elseif (isset($field['settings']->datatype)) + { + // insure default not none if number type + $numberKeys = array('INT', 'TINYINT', 'BIGINT', 'FLOAT', 'DECIMAL', + 'DOUBLE'); + // don't use these as index or uniqe keys + $textKeys = array('TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', + 'BLOB', 'TINYBLOB', 'MEDIUMBLOB', 'LONGBLOB'); + // build the query values + $this->databasetables->set($nameSingleCode . '.' . $name . '.type', + $field['settings']->datatype); + // check if this is a number + if (in_array($field['settings']->datatype, $numberKeys)) + { + if ($field['settings']->datadefault === 'Other') + { + // setup the checking + $number_check = $field['settings']->datadefault_other; + // Decimals in SQL needs some help + if ('DECIMAL' === $field['settings']->datatype + && !is_numeric($number_check)) + { + $number_check = str_replace( + ',', '.', (string) $field['settings']->datadefault_other + ); + } + // check if we have a valid number value + if (!is_numeric($number_check)) + { + $field['settings']->datadefault_other = '0'; + } + } + elseif (!is_numeric($field['settings']->datadefault)) + { + $field['settings']->datadefault = '0'; + } + } + // check if this is not text + if (!in_array($field['settings']->datatype, $textKeys)) + { + $this->databasetables->set($nameSingleCode . '.' . $name . '.lenght', + $field['settings']->datalenght); + $this->databasetables->set($nameSingleCode . '.' . $name . '.lenght_other', + $field['settings']->datalenght_other); + $this->databasetables->set($nameSingleCode . '.' . $name . '.default', + $field['settings']->datadefault); + $this->databasetables->set($nameSingleCode . '.' . $name . '.other', + $field['settings']->datadefault_other); + } + // fall back unto EMPTY for text + else + { + $this->databasetables->set($nameSingleCode . '.' . $name . '.default', + 'EMPTY'); + } + // to identify the field + $this->databasetables->set($nameSingleCode . '.' . $name . '.ID', + $field['settings']->id); + $this->databasetables->set($nameSingleCode . '.' . $name . '.null_switch', + $field['settings']->null_switch); + // set index types + $_guid = true; + if ($field['settings']->indexes == 1 + && !in_array( + $field['settings']->datatype, $textKeys + )) + { + // build unique keys of this view for db + $this->databaseuniquekeys->add($nameSingleCode, $name, true); + // prevent guid from being added twice + if ('guid' === $name) + { + $_guid = false; + } + } + elseif (($field['settings']->indexes == 2 + || (isset($field['alias']) + && $field['alias']) + || (isset($field['title']) && $field['title']) + || $typeName === 'category') + && !in_array($field['settings']->datatype, $textKeys)) + { + // build keys of this view for db + $this->databasekeys->add($nameSingleCode, $name, true); + } + // special treatment for GUID + if ('guid' === $name && $_guid) + { + $this->databaseuniqueguid->set($nameSingleCode, true); + } + } + // set list switch + $listSwitch = (isset($field['list']) + && ($field['list'] == 1 + || $field['list'] == 3 + || $field['list'] == 4)); + // set list join + $listJoin + = $this->listjoin->exists($nameListCode . '.' . (int) $field['field']); + // add history to this view + if (isset($view['history']) && $view['history']) + { + $this->history->set($nameSingleCode, true); + } + // set Alias (only one title per view) + if ($dbSwitch && isset($field['alias']) && $field['alias'] + && !$this->alias->get($nameSingleCode)) + { + $this->alias->set($nameSingleCode, $name); + } + // set Titles (only one title per view) + if ($dbSwitch && isset($field['title']) && $field['title'] + && !$this->title->get($nameSingleCode)) + { + $this->title->set($nameSingleCode, $name); + } + // category name fix + if ($typeName === 'category') + { + $tempName = $this->categoryothername-> + get($nameListCode . '.name', $nameListCode . ' categories'); + // set lang + $listLangName = $langView . '_' + . FieldHelper::safe($tempName, true); + // set field name + $listFieldName = StringHelper::safe($tempName, 'W'); + // add to lang array + $this->language->set( + $this->config->lang_target, $listLangName, $listFieldName + ); + } + else + { + // if label was set use instead + if (StringHelper::check($langLabel)) + { + $listLangName = $langLabel; + // get field label from the lang label + if ($this->language->exist($this->config->lang_target, $langLabel)) + { + $listFieldName + = $this->language->get($this->config->lang_target, $langLabel); + } + else + { + // get it from the field xml string + $listFieldName = (string) $this->placeholder->update_( + GetHelper::between( + $field['settings']->xml, 'label="', + '"' + ) + ); + } + // make sure there is no html in the list field name + $listFieldName = strip_tags($listFieldName); + } + else + { + // set lang (just in case) + $listLangName = $langView . '_' + . FieldHelper::safe($name, true); + // set field name + $listFieldName = StringHelper::safe($name, 'W'); + // add to lang array + $this->language->set( + $this->config->lang_target, $listLangName, $listFieldName + ); + } + } + // build the list values + if (($listSwitch || $listJoin) && $typeName != 'repeatable' + && $typeName != 'subform') + { + // load to list builder + if ($listSwitch) + { + // append values + $this->lists->add($nameListCode, [ + 'id' => (int) $field['field'], + 'type' => $typeName, + 'code' => $name, + 'lang' => $listLangName, + 'title' => (isset($field['title']) && $field['title']) + ? true : false, + 'alias' => (isset($field['alias']) && $field['alias']) + ? true : false, + 'link' => (isset($field['link']) && $field['link']) + ? true : false, + 'sort' => (isset($field['sort']) && $field['sort']) + ? true : false, + 'custom' => $custom, + 'multiple' => $multiple, + 'options' => $options, + 'target' => (int) $field['list'] + ], true); + } + // build custom builder list + if ($listSwitch || $listJoin) + { + $this->customlist->set($nameSingleCode . '.' . $name, true); + } + } + // load the list join builder + if ($listJoin) + { + $this->listjoin->set($nameListCode . '.' . (int) $field['field'], [ + 'type' => $typeName, + 'code' => $name, + 'lang' => $listLangName, + 'title' => (isset($field['title']) && $field['title']) ? true + : false, + 'alias' => (isset($field['alias']) && $field['alias']) ? true + : false, + 'link' => (isset($field['link']) && $field['link']) ? true + : false, + 'sort' => (isset($field['sort']) && $field['sort']) ? true + : false, + 'custom' => $custom, + 'multiple' => $multiple, + 'options' => $options + ]); + } + // update the field relations + if (($field_relations = + $this->fieldrelations->get($nameListCode . '.' . (int) $field['field'])) !== null) + { + $field_relations = (array) $field_relations; + foreach ($field_relations as $area => &$field_values) + { + $field_values['type'] = $typeName; + $field_values['code'] = $name; + $field_values['custom'] = $custom; + } + $this->fieldrelations->set($nameListCode . '.' . (int) $field['field'], $field_relations); + } + // set the hidden field of this view + if ($dbSwitch && $typeName === 'hidden') + { + $this->hiddenfields->add($nameSingleCode, ',"' . $name . '"', true); + } + // set all int fields of this view + if ($dbSwitch && isset($field['settings']->datatype) + && ($field['settings']->datatype === 'INT' + || $field['settings']->datatype === 'TINYINT' + || $field['settings']->datatype === 'BIGINT')) + { + $this->integerfields->add($nameSingleCode, ',"' . $name . '"', true); + } + // Get the default fields + $default_fields = $this->config->default_fields; + // set all dynamic field of this view + if ($dbSwitch && $typeName != 'category' && $typeName != 'repeatable' + && $typeName != 'subform' && !in_array($name, $default_fields)) + { + $this->dynamicfields->add($nameSingleCode, '"' . $name . '":"' . $name . '"', true); + } + // TODO we may need to add a switch instead (since now it uses the first editor field) + // set the main(biggest) text field of this view + if ($dbSwitch && $typeName === 'editor') + { + if (!$this->maintextfield->exists($nameSingleCode)) + { + $this->maintextfield->set($nameSingleCode, $name); + } + } + // set the custom builder + if (ArrayHelper::check($custom) + && $typeName != 'category' + && $typeName != 'repeatable' + && $typeName != 'subform') + { + $this->customfield->add($nameListCode, [ + 'type' => $typeName, + 'code' => $name, + 'lang' => $listLangName, + 'custom' => $custom, + 'method' => $field['settings']->store + ], true); + + // only load this if table is set + if (isset($custom['table']) + && StringHelper::check( + $custom['table'] + )) + { + // set the custom fields needed in content type data + $this->customfieldlinks->add( + $nameSingleCode, + ',{"sourceColumn": "' . $name . '","targetTable": "' . $custom['table'] + . '","targetColumn": "' . $custom['id'] . '","displayColumn": "' . $custom['text'] . '"}', + true + ); + } + // build script switch for user + if ($custom['extends'] === 'user') + { + $this->scriptuserswitch->set($typeName, $typeName); + } + } + if ($typeName === 'media') + { + $this->scriptmediaswitch->set($typeName, $typeName); + } + // setup category for this view + if ($dbSwitch && $typeName === 'category') + { + $otherViews = $this->categoryothername-> + get($nameListCode . '.views', $nameListCode); + $otherView = $this->categoryothername-> + get($nameListCode . '.view', $nameSingleCode); + // get the xml extension name + $_extension = $this->placeholder->update_( + GetHelper::between( + $field['settings']->xml, 'extension="', '"' + ) + ); + // if they left out the extension for some reason + if (!StringHelper::check($_extension)) + { + $_extension = 'com_' . $this->config->component_code_name . '.' + . $otherView; + } + // check the context (does our target match) + if (strpos((string) $_extension, '.') !== false) + { + $target_view = trim(explode('.', (string) $_extension)[1]); + // from my understanding the target extension view and the otherView must align + // so I will here check that it does, and if not raise an error message to fix this + if ($target_view !== $otherView) + { + $target_extension = trim(explode('.', (string) $_extension)[0]); + $correction = $target_extension . '.' . $otherView; + $this->app->enqueueMessage( + Text::sprintf( + '

Category targeting view mismatch

+

The + category field in (%s) admin view has a mismatching target view. +
To correct the mismatch, the extension value %s in the + field must be changed to %s + for + best category integration with Joomla. +
Please watch + this tutorial before proceeding!!!, + code fix

', + $field['field'], $nameSingleCode, $_extension, + $field['field'], $correction + ), 'Error' + ); + } + } + // load the category builder - TODO must move all to single view + $this->category->set($nameListCode, [ + 'code' => $name, + 'name' => $listLangName, + 'extension' => $_extension, + 'filter' => $field['filter'] + ]); + // also set code name for title alias fix + $this->categorycode->set($nameSingleCode, [ + 'code' => $name, + 'views' => $otherViews, + 'view' => $otherView + ]); + } + // setup checkbox for this view + if ($dbSwitch && ($typeName === 'checkbox' || + (ArrayHelper::check($custom) && isset($custom['extends']) && $custom['extends'] === 'checkboxes'))) + { + $this->checkbox->add($nameSingleCode, $name, true); + } + // setup checkboxes and other json items for this view + // if we have advance field modeling and the field is not being set in the DB + // this could mean that field is modeled manually (so we add it) + if (($dbSwitch || $field['settings']->store == 6) + && (($typeName === 'subform' || $typeName === 'checkboxes' + || $multiple + || $field['settings']->store != 0) + && $typeName != 'tag')) + { + $subformJsonSwitch = true; + switch ($field['settings']->store) + { + case 1: + // JSON_STRING_ENCODE + $this->jsonstring->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'json', $typeName + ); + // add open close method to field data + $field['store'] = 'json'; + break; + case 2: + // BASE_SIXTY_FOUR + $this->basesixfour->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'base64', $typeName + ); + // add open close method to field data + $field['store'] = 'base64'; + break; + case 3: + // BASIC_ENCRYPTION_LOCALKEY + $this->modelbasicfield->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'basic_encryption', $typeName + ); + // add open close method to field data + $field['store'] = 'basic_encryption'; + break; + case 4: + // WHMCS_ENCRYPTION_VDMKEY (DUE REMOVAL) + $this->modelwhmcsfield->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'whmcs_encryption', $typeName + ); + // add open close method to field data + $field['store'] = 'whmcs_encryption'; + break; + case 5: + // MEDIUM_ENCRYPTION_LOCALFILE + $this->modelmediumfield->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'medium_encryption', $typeName + ); + // add open close method to field data + $field['store'] = 'medium_encryption'; + break; + case 6: + // EXPERT_MODE + if (isset($field['settings']->model_field)) + { + if (isset($field['settings']->initiator_save_key)) + { + $this->modelexpertfieldinitiator->set( + $nameSingleCode . '.save.' . $field['settings']->initiator_save_key + , $field['settings']->initiator_save + ); + } + if (isset($field['settings']->initiator_get_key)) + { + $this->modelexpertfieldinitiator->set( + $nameSingleCode . '.get.' . $field['settings']->initiator_get_key + , $field['settings']->initiator_get + ); + } + $this->modelexpertfield->set( + $nameSingleCode . '.' . $name, $field['settings']->model_field + ); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'expert_mode', $typeName + ); + } + break; + default: + // JSON_ARRAY_ENCODE + $this->jsonitem->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'json', $typeName + ); + // no londer add the json again (already added) + $subformJsonSwitch = false; + // add open close method to field data + $field['store'] = 'json'; + break; + } + // just a heads-up for usergroups set to multiple + if ($typeName === 'usergroup') + { + $this->sitefielddata->set( + $nameSingleCode, $name, 'json', $typeName + ); + } + + // load the model list display fix + if (($listSwitch || $listJoin) + && (($typeName != 'repeatable' && $typeName != 'subform') || $field['settings']->store == 6)) + { + $this->itemsmethodliststring->add($nameSingleCode, [ + 'name' => $name, + 'type' => $typeName, + 'translation' => (bool) ArrayHelper::check($options), + 'custom' => $custom, + 'method' => $field['settings']->store + ], true); + } + + // subform housekeeping (only if not advance modeling) + if ('subform' === $typeName && $field['settings']->store != 6) + { + // the values must revert to array + $this->jsonitemarray->add($nameSingleCode, $name, true); + // should the json builder still be added + if ($subformJsonSwitch) + { + // and insure the if is converted to json + $this->jsonitem->add($nameSingleCode, $name, true); + // Site settings of each field if needed + $this->sitefielddata->set( + $nameSingleCode, $name, 'json', $typeName + ); + } + } + } + // build the data for the export & import methods $typeName === 'repeatable' || + if ($dbSwitch && (($typeName === 'checkboxes' || $multiple || $field['settings']->store != 0) + && !ArrayHelper::check($options))) + { + $this->itemsmethodeximportstring->add($nameSingleCode, [ + 'name' => $name, + 'type' => $typeName, + 'translation' => false, + 'custom' => $custom, + 'method' => $field['settings']->store + ], true); + } + // check if field should be added to uikit + $this->sitefielddata->set($nameSingleCode, $name, 'uikit', $typeName); + // load the selection translation fix + if (ArrayHelper::check($options) && ($listSwitch || $listJoin) + && $typeName != 'repeatable' && $typeName != 'subform') + { + $this->selectiontranslation->set($nameListCode . '.' . $name, $options); + } + // main lang filter prefix + $lang_filter_ = $this->config->lang_prefix . '_FILTER_'; + // build the sort values + if ($dbSwitch && (isset($field['sort']) && $field['sort'] == 1) + && ($listSwitch || $listJoin) + && (!$multiple && $typeName != 'checkbox' && $typeName != 'checkboxes' + && $typeName != 'repeatable' && $typeName != 'subform')) + { + // add the language only for new filter option + $filter_name_asc_lang = ''; + $filter_name_desc_lang = ''; + if ($this->adminfiltertype->get($nameListCode, 1) == 2) + { + // set the language strings for ascending + $filter_name_asc = $listFieldName . ' ascending'; + $filter_name_asc_lang = $lang_filter_ + . StringHelper::safe( + $filter_name_asc, 'U' + ); + // and to translation + $this->language->set( + $this->config->lang_target, $filter_name_asc_lang, $filter_name_asc + ); + // set the language strings for descending + $filter_name_desc = $listFieldName . ' descending'; + $filter_name_desc_lang = $lang_filter_ + . StringHelper::safe( + $filter_name_desc, 'U' + ); + // and to translation + $this->language->set( + $this->config->lang_target, $filter_name_desc_lang, $filter_name_desc + ); + } + $this->sort->add($nameListCode, [ + 'type' => $typeName, + 'code' => $name, + 'lang' => $listLangName, + 'lang_asc' => $filter_name_asc_lang, + 'lang_desc' => $filter_name_desc_lang, + 'custom' => $custom, + 'options' => $options + ], true); + } + // build the search values + if ($dbSwitch && isset($field['search']) && $field['search'] == 1) + { + $_list = (isset($field['list'])) ? $field['list'] : 0; + $this->search->add($nameListCode, [ + 'type' => $typeName, + 'code' => $name, + 'custom' => $custom, + 'list' => $_list + ], true); + } + // build the filter values + if ($dbSwitch && (isset($field['filter']) && $field['filter'] >= 1) + && ($listSwitch || $listJoin) + && (!$multiple && $typeName != 'checkbox' + && $typeName != 'checkboxes' + && $typeName != 'repeatable' + && $typeName != 'subform')) + { + // this pains me... but to avoid collusion + $filter_type_code = StringHelper::safe( + $nameListCode . 'filter' . $name + ); + $filter_type_code = preg_replace('/_+/', '', (string) $filter_type_code); + $filter_function_name = StringHelper::safe( + $name, 'F' + ); + // add the language only for new filter option + $filter_name_select_lang = ''; + if ($this->adminfiltertype->get($nameListCode, 1) == 2) + { + // set the language strings for selection + $filter_name_select = 'Select ' . $listFieldName; + $filter_name_select_lang = $lang_filter_ + . StringHelper::safe( + $filter_name_select, 'U' + ); + // and to translation + $this->language->set( + $this->config->lang_target, $filter_name_select_lang, $filter_name_select + ); + } + + // add the filter details + $this->filter->add($nameListCode, [ + 'id' => (int) $field['field'], + 'type' => $typeName, + 'multi' => $field['filter'], + 'code' => $name, + 'label' => $langLabel, + 'lang' => $listLangName, + 'lang_select' => $filter_name_select_lang, + 'database' => $nameSingleCode, + 'function' => $filter_function_name, + 'custom' => $custom, + 'options' => $options, + 'filter_type' => $filter_type_code + ], true); + } + + // build the layout + $tabName = ''; + if (isset($view['settings']->tabs) + && isset($view['settings']->tabs[(int) $field['tab']])) + { + $tabName = $view['settings']->tabs[(int) $field['tab']]; + } + elseif ((int) $field['tab'] == 15) + { + // set to publishing tab + $tabName = 'publishing'; + } + $this->layout->set($nameSingleCode, $tabName, $name, $field); + + // load all fields that are in the database + if ($dbSwitch) + { + // load array of view, field, and [encryption, type, tab] + $title_ = $this->title->get($nameSingleCode); + $this->componentfields->set($nameSingleCode . '.' . $name, + [ + 'name' => $name, + 'label' => $langLabel, + 'type' => $typeName, + 'title' => (is_string($title_) && $name === $title_) ? true : false, + 'list' => $nameListCode, + 'store' => (isset($field['store'])) ? $field['store'] : null, + 'tab_name' => $tabName + ] + ); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/CustomFieldTypeFile.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/CustomFieldTypeFile.php new file mode 100644 index 000000000..6fc8ca30e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/CustomFieldTypeFile.php @@ -0,0 +1,532 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Application\CMSApplication; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti as Contents; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFieldData as SiteField; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder as ComponentPlaceholder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure; +use VDM\Joomla\Componentbuilder\Compiler\Field\InputButton; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldGroupControl; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ExtensionCustomFields; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Utilities\String\FieldHelper; + + +/** + * Custom Field Type File Creator Class + * + * @since 3.2.0 + */ +final class CustomFieldTypeFile +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The ContentOne Class. + * + * @var Content + * @since 3.2.0 + */ + protected Content $content; + + /** + * The ContentMulti Class. + * + * @var Contents + * @since 3.2.0 + */ + protected Contents $contents; + + /** + * The SiteFieldData Class. + * + * @var SiteField + * @since 3.2.0 + */ + protected SiteField $sitefield; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Placeholder Class. + * + * @var ComponentPlaceholder + * @since 3.2.0 + */ + protected ComponentPlaceholder $componentplaceholder; + + /** + * The Structure Class. + * + * @var Structure + * @since 3.2.0 + */ + protected Structure $structure; + + /** + * The InputButton Class. + * + * @var InputButton + * @since 3.2.0 + */ + protected InputButton $inputbutton; + + /** + * The FieldGroupControl Class. + * + * @var FieldGroupControl + * @since 3.2.0 + */ + protected FieldGroupControl $fieldgroupcontrol; + + /** + * The ExtensionCustomFields Class. + * + * @var ExtensionCustomFields + * @since 3.2.0 + */ + protected ExtensionCustomFields $extensioncustomfields; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Array of php fields Allowed (16) + * + * @var array + * @since 3.2.0 + **/ + protected array $phpFieldArray = ['', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'x', 'HEADER']; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Content $content The ContentOne Class. + * @param Contents $contents The ContentMulti Class. + * @param SiteField $sitefield The SiteFieldData Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Language $language The Language Class. + * @param ComponentPlaceholder $componentplaceholder The Placeholder Class. + * @param Structure $structure The Structure Class. + * @param InputButton $inputbutton The InputButton Class. + * @param FieldGroupControl $fieldgroupcontrol The FieldGroupControl Class. + * @param ExtensionCustomFields $extensioncustomfields The ExtensionCustomFields Class. + * @param CMSApplication|null $app The app object. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Content $content, Contents $contents, + SiteField $sitefield, Placeholder $placeholder, + Language $language, + ComponentPlaceholder $componentplaceholder, + Structure $structure, InputButton $inputbutton, + FieldGroupControl $fieldgroupcontrol, + ExtensionCustomFields $extensioncustomfields, + ?CMSApplication $app = null) + { + $this->config = $config; + $this->content = $content; + $this->contents = $contents; + $this->sitefield = $sitefield; + $this->placeholder = $placeholder; + $this->language = $language; + $this->componentplaceholder = $componentplaceholder; + $this->structure = $structure; + $this->inputbutton = $inputbutton; + $this->fieldgroupcontrol = $fieldgroupcontrol; + $this->extensioncustomfields = $extensioncustomfields; + $this->app = $app ?: Factory::getApplication(); + } + + /** + * set Custom Field Type File + * + * @param array $data The field complete data set + * @param string $nameListCode The list view code name + * @param string $nameSingleCode The single view code name + * + * @return void + * @since 3.2.0 + */ + public function set(array $data, string $nameListCode, string $nameSingleCode): void + { + // make sure it is not already been build or if it is prime + if (isset($data['custom']) && isset($data['custom']['extends']) + && ((isset($data['custom']['prime_php']) && $data['custom']['prime_php'] == 1) + || !$this->contents->isArray('customfield_' . $data['type'])) + ) + { + // set J prefix + $jprefix = 'J'; + // check if this field has a dot in field type name + if (strpos((string) $data['type'], '.') !== false) + { + // so we have name spacing in custom field type name + $dotTypeArray = explode('.', (string) $data['type']); + // set the J prefix + if (count((array) $dotTypeArray) > 1) + { + $jprefix = strtoupper(array_shift($dotTypeArray)); + } + // update the type name now + $data['type'] = implode('', $dotTypeArray); + $data['custom']['type'] = $data['type']; + } + // set the contents key + $contents_key = "customfield_{$data['type']}|"; + // set tab and break replacements + $tabBreak = array( + '\t' => Indent::_(1), + '\n' => PHP_EOL + ); + // set the [[[PLACEHOLDER]]] options + $replace = array( + Placefix::_('JPREFIX') => $jprefix, + Placefix::_('TABLE') => (isset($data['custom']['table'])) + ? $data['custom']['table'] : '', + Placefix::_('ID') => (isset($data['custom']['id'])) + ? $data['custom']['id'] : '', + Placefix::_('TEXT') => (isset($data['custom']['text'])) + ? $data['custom']['text'] : '', + Placefix::_('CODE_TEXT') => (isset($data['code'], $data['custom']['text'])) + ? $data['code'] . '_' . $data['custom']['text'] : '', + Placefix::_('CODE') => (isset($data['code'])) + ? $data['code'] : '', + Placefix::_('view_type') => $nameSingleCode + . '_' . $data['type'], + Placefix::_('type') => (isset($data['type'])) + ? $data['type'] : '', + Placefix::_('com_component') => (isset($data['custom']['component']) + && StringHelper::check( + $data['custom']['component'] + )) ? StringHelper::safe( + $data['custom']['component'] + ) : 'com_' . $this->config->component_code_name, + // set the generic values + Placefix::_('component') => $this->config->component_code_name, + Placefix::_('Component') => $this->content->get('Component'), + Placefix::_('view') => (isset($data['custom']['view']) + && StringHelper::check( + $data['custom']['view'] + )) ? StringHelper::safe( + $data['custom']['view'] + ) : $nameSingleCode, + Placefix::_('views') => (isset($data['custom']['views']) + && StringHelper::check( + $data['custom']['views'] + )) ? StringHelper::safe( + $data['custom']['views'] + ) : $nameListCode + ); + // now set the ###PLACEHOLDER### options + foreach ($replace as $replacekey => $replacevalue) + { + // update the key value + $replacekey = str_replace( + array(Placefix::b(), Placefix::d()), + array(Placefix::h(), Placefix::h()), $replacekey + ); + // now set the value + $replace[$replacekey] = $replacevalue; + } + // load the global placeholders + foreach ($this->componentplaceholder->get() as $globalPlaceholder => $gloabalValue) + { + $replace[$globalPlaceholder] = $gloabalValue; + } + // start loading the field type + + // JPREFIX <<>> + $this->contents->set("{$contents_key}JPREFIX", $jprefix); + // Type <<>> + $this->contents->set("{$contents_key}Type", + StringHelper::safe( + $data['custom']['type'], 'F' + ) + ); + // type <<>> + $this->contents->set("{$contents_key}type", StringHelper::safe($data['custom']['type'])); + // is this a own custom field + if (isset($data['custom']['own_custom'])) + { + // make sure the button option notice is set to notify the developer that the button option is not available in own custom field types + if (isset($data['custom']['add_button']) + && ($data['custom']['add_button'] === 'true' + || 1 == $data['custom']['add_button'])) + { + // set error + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDYNAMIC_BUTTON_ERRORHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_THE_OPTION_TO_ADD_A_DYNAMIC_BUTTON_IS_NOT_AVAILABLE_IN_BOWN_CUSTOM_FIELD_TYPESB_YOU_WILL_HAVE_TO_CUSTOM_CODE_IT'), 'Error' + ); + } + // load another file + $target = array('admin' => 'customfield'); + $this->structure->build( + $target, 'fieldcustom', $data['custom']['type'] + ); + // get the extends name + $JFORM_extends = StringHelper::safe( + $data['custom']['extends'] + ); + // JFORM_TYPE_HEADER <<>> + $add_default_header = true; + $this->contents->set("{$contents_key}JFORM_TYPE_HEADER", + "//" . Line::_( + __LINE__,__CLASS__ + ) . " Import the " . $JFORM_extends + . " field type classes needed" + ); + // JFORM_extens <<>> + $this->contents->set("{$contents_key}JFORM_extends", $JFORM_extends + ); + // JFORM_EXTENDS <<>> + $this->contents->set("{$contents_key}JFORM_EXTENDS", + StringHelper::safe( + $data['custom']['extends'], 'F' + ) + ); + // JFORM_TYPE_PHP <<>> + $this->contents->set("{$contents_key}JFORM_TYPE_PHP", + PHP_EOL . PHP_EOL . Indent::_(1) . "//" . Line::_( + __LINE__,__CLASS__ + ) . " A " . $data['custom']['own_custom'] . " Field" + ); + // load the other PHP options + foreach ($this->phpFieldArray as $x) + { + // reset the php bucket + $phpBucket = ''; + // only set if available + if (isset($data['custom']['php' . $x]) + && ArrayHelper::check( + $data['custom']['php' . $x] + )) + { + foreach ($data['custom']['php' . $x] as $line => $code) + { + if (StringHelper::check($code)) + { + $phpBucket .= PHP_EOL . $this->placeholder->update( + $code, $tabBreak + ); + } + } + // check if this is header text + if ('HEADER' === $x) + { + $this->contents->add("{$contents_key}JFORM_TYPE_HEADER", + PHP_EOL . $this->placeholder->update( + $phpBucket, $replace + ), false + ); + // stop default headers from loading + $add_default_header = false; + } + else + { + // JFORM_TYPE_PHP <<>> + $this->contents->add("{$contents_key}JFORM_TYPE_PHP", + PHP_EOL . $this->placeholder->update( + $phpBucket, $replace + ), false + ); + } + } + } + // check if we should add default header + if ($add_default_header) + { + $this->contents->add("{$contents_key}JFORM_TYPE_HEADER", + PHP_EOL . "jimport('joomla.form.helper');", + false + ); + $this->contents->add("{$contents_key}JFORM_TYPE_HEADER", + PHP_EOL . "JFormHelper::loadFieldClass('" . $JFORM_extends . "');", + false + ); + } + // check the the JFormHelper::loadFieldClass(..) was set + elseif (strpos((string) $this->contents->get("{$contents_key}JFORM_TYPE_HEADER"), + 'JFormHelper::loadFieldClass(') === false) + { + $this->contents->add("{$contents_key}JFORM_TYPE_HEADER", + PHP_EOL . "JFormHelper::loadFieldClass('" + . $JFORM_extends . "');", false + ); + } + } + else + { + // first build the custom field type file + $target = array('admin' => 'customfield'); + $this->structure->build( + $target, 'field' . $data['custom']['extends'], + $data['custom']['type'] + ); + // make sure the value is reset + $phpCode = ''; + // now load the php script + if (isset($data['custom']['php']) + && ArrayHelper::check( + $data['custom']['php'] + )) + { + foreach ($data['custom']['php'] as $line => $code) + { + if (StringHelper::check($code)) + { + if ($line == 1) + { + $phpCode .= $this->placeholder->update( + $code, $tabBreak + ); + } + else + { + $phpCode .= PHP_EOL . Indent::_(2) + . $this->placeholder->update($code, $tabBreak); + } + } + } + // replace the placholders + $phpCode = $this->placeholder->update($phpCode, $replace); + } + // catch empty stuff + if (!StringHelper::check($phpCode)) + { + $phpCode = 'return null;'; + } + // some house cleaning for users + if ($data['custom']['extends'] === 'user') + { + // make sure the value is reset + $phpxCode = ''; + // now load the php xclude script + if (ArrayHelper::check( + $data['custom']['phpx'] + )) + { + foreach ($data['custom']['phpx'] as $line => $code) + { + if (StringHelper::check($code)) + { + if ($line == 1) + { + $phpxCode .= $this->placeholder->update( + $code, $tabBreak + ); + } + else + { + $phpxCode .= PHP_EOL . Indent::_(2) + . $this->placeholder->update( + $code, $tabBreak + ); + } + } + } + // replace the placholders + $phpxCode = $this->placeholder->update($phpxCode, $replace); + } + // catch empty stuff + if (!StringHelper::check($phpxCode)) + { + $phpxCode = 'return null;'; + } + // temp holder for name + $tempName = $data['custom']['label'] . ' Group'; + // set lang + $groupLangName = $this->config->lang_prefix . '_' + . FieldHelper::safe( + $tempName, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $groupLangName, + StringHelper::safe($tempName, 'W') + ); + // build the Group Control + $this->fieldgroupcontrol->set($data['type'], $groupLangName); + // JFORM_GETGROUPS_PHP <<>> + $this->contents->set("{$contents_key}JFORM_GETGROUPS_PHP", + $phpCode + ); + // JFORM_GETEXCLUDED_PHP <<>> + $this->contents->set("{$contents_key}JFORM_GETEXCLUDED_PHP", + $phpxCode + ); + } + else + { + // JFORM_GETOPTIONS_PHP <<>> + $this->contents->set("{$contents_key}JFORM_GETOPTIONS_PHP", + $phpCode + ); + } + // type <<>> + $this->contents->set("{$contents_key}ADD_BUTTON", + $this->inputbutton->get($data['custom']) + ); + } + } + // if this field gets used in plug-in or module we should track it so if needed we can copy it over + if ((strpos($nameSingleCode, 'pLuG!n') !== false || strpos($nameSingleCode, 'M0dUl3') !== false) + && isset($data['custom']) + && isset($data['custom']['type'])) + { + $this->extensioncustomfields->set($data['type'], $data['custom']['type']); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldAsString.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldAsString.php new file mode 100644 index 000000000..b95c51263 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldAsString.php @@ -0,0 +1,102 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldDynamic; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Xml; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; + + +/** + * Get any field as a string Creator Class + * + * @since 3.2.0 + */ +final class FieldAsString +{ + /** + * The FieldDynamic Class. + * + * @var FieldDynamic + * @since 3.2.0 + */ + protected FieldDynamic $fielddynamic; + + /** + * The Xml Class. + * + * @var Xml + * @since 3.2.0 + */ + protected Xml $xml; + + /** + * Constructor. + * + * @param FieldDynamic $fielddynamic The FieldDynamic Class. + * @param Xml $xml The Xml Class. + * + * @since 3.2.0 + */ + public function __construct(FieldDynamic $fielddynamic, Xml $xml) + { + $this->fielddynamic = $fielddynamic; + $this->xml = $xml; + } + + /** + * Get field as a string (no matter the build type) + * + * @param array $field The field data + * @param array $view The view data + * @param int $viewType The view type + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The placeholder and replace values + * @param string $dbkey The custom table key + * @param boolean $build The switch to set the build option + * + * @return string The complete field in xml-string + * @since 3.2.0 + */ + public function get(array &$field, array &$view, int $viewType, string $langView, + string $nameSingleCode, string $nameListCode, array &$placeholders, + string &$dbkey, bool $build = false): string + { + // get field + $field_xml = $this->fielddynamic->get( + $field, $view, $viewType, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $dbkey, $build + ); + + if (is_string($field_xml)) + { + return $field_xml; + } + elseif (is_object($field_xml) && isset($field_xml->fieldXML)) + { + return PHP_EOL . Indent::_(2) . "' . PHP_EOL + . Indent::_(1) . $this->xml->pretty( + $field_xml->fieldXML, 'field' + ); + } + + return ''; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldDynamic.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldDynamic.php new file mode 100644 index 000000000..5e18e05c4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldDynamic.php @@ -0,0 +1,302 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Field\Name; +use VDM\Joomla\Componentbuilder\Compiler\Field\TypeName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Attributes; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldNames; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldtypeinterface as Field; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Builders; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Layout; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fielddynamicinterface; + + +/** + * Dynamic Field Creator Class + * + * @since 3.2.0 + */ +final class FieldDynamic implements Fielddynamicinterface +{ + /** + * The Name Class. + * + * @var Name + * @since 3.2.0 + */ + protected Name $name; + + /** + * The TypeName Class. + * + * @var TypeName + * @since 3.2.0 + */ + protected TypeName $typename; + + /** + * The Attributes Class. + * + * @var Attributes + * @since 3.2.0 + */ + protected Attributes $attributes; + + /** + * The Groups Class. + * + * @var Groups + * @since 3.2.0 + */ + protected Groups $groups; + + /** + * The FieldNames Class. + * + * @var FieldNames + * @since 3.2.0 + */ + protected FieldNames $fieldnames; + + /** + * The Fieldtypeinterface Class. + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * The Builders Class. + * + * @var Builders + * @since 3.2.0 + */ + protected Builders $builders; + + /** + * The Layout Class. + * + * @var Layout + * @since 3.2.0 + */ + protected Layout $layout; + + /** + * Constructor. + * + * @param Name $name The Name Class. + * @param TypeName $typename The TypeName Class. + * @param Attributes $attributes The Attributes Class. + * @param Groups $groups The Groups Class. + * @param FieldNames $fieldnames The FieldNames Class. + * @param Field $field The Fieldtypeinterface Class. + * @param Builders $builders The Builders Class. + * @param Layout $layout The Layout Class. + * + * @since 3.2.0 + */ + public function __construct(Name $name, TypeName $typename, + Attributes $attributes, Groups $groups, FieldNames $fieldnames, + Field $field, Builders $builders, Layout $layout) + { + $this->name = $name; + $this->typename = $typename; + $this->attributes = $attributes; + $this->groups = $groups; + $this->fieldnames = $fieldnames; + $this->field = $field; + $this->builders = $builders; + $this->layout = $layout; + } + + /** + * Get the Dynamic field and build all it needs + * + * @param array $field The field data + * @param array $view The view data + * @param int $viewType The view type + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The placeholder and replace values + * @param string $dbkey The custom table key + * @param boolean $build The switch to set the build option + * + * @return mixed The complete field + * @since 3.2.0 + */ + public function get(array &$field, array &$view, int &$viewType, string &$langView, string &$nameSingleCode, + string &$nameListCode, array &$placeholders, string &$dbkey, bool $build) + { + // set default return + $dynamicField = null; + + // make sure we have settings + if (isset($field['settings']) + && ObjectHelper::check($field['settings'])) + { + // reset some values + $name = $this->name->get($field, $nameListCode); + $typeName = $this->typename->get($field); + $multiple = false; + $langLabel = ''; + $fieldSet = ''; + // set field attributes + $fieldAttributes = $this->attributes->set( + $field, $viewType, $name, $typeName, $multiple, $langLabel, + $langView, $nameListCode, $nameSingleCode, $placeholders + ); + // check if values were set + if (ArrayHelper::check($fieldAttributes)) + { + // set the array of field names + $this->fieldnames->set( + $nameSingleCode . '.' . $fieldAttributes['name'], $fieldAttributes['name'] + ); + + // set options as null + $optionArray = null; + + if ($this->groups->check($typeName, 'option')) + { + // set options array + $optionArray = array(); + + // now add to the field set + $dynamicField = $this->field->get( + 'option', $fieldAttributes, $name, $typeName, $langView, + $nameSingleCode, $nameListCode, $placeholders, + $optionArray + ); + + if ($build) + { + // set builders + $this->builders->set( + $langLabel, $langView, $nameSingleCode, + $nameListCode, $name, $view, $field, $typeName, + $multiple, null, $optionArray + ); + } + } + elseif ($this->groups->check($typeName, 'spacer')) + { + if ($build) + { + // make sure spacers gets loaded to layout + $tabName = ''; + if (isset($view['settings']->tabs) + && isset($view['settings']->tabs[(int) $field['tab']])) + { + $tabName + = $view['settings']->tabs[(int) $field['tab']]; + } + elseif ((int) $field['tab'] == 15) + { + // set to publishing tab + $tabName = 'publishing'; + } + + $this->layout->set( + $nameSingleCode, $tabName, $name, $field + ); + } + + // now add to the field set + $dynamicField = $this->field->get( + 'spacer', $fieldAttributes, $name, $typeName, $langView, + $nameSingleCode, $nameListCode, $placeholders, + $optionArray + ); + } + elseif ($this->groups->check($typeName, 'special')) + { + // set the repeatable field or subform field + if ($typeName === 'repeatable' || $typeName === 'subform') + { + if ($build) + { + // set builders + $this->builders->set( + $langLabel, $langView, $nameSingleCode, + $nameListCode, $name, $view, $field, + $typeName, $multiple, null + ); + } + + // now add to the field set + $dynamicField = $this->field->get( + 'special', $fieldAttributes, $name, $typeName, + $langView, $nameSingleCode, $nameListCode, + $placeholders, $optionArray + ); + } + } + elseif (isset($fieldAttributes['custom']) + && ArrayHelper::check($fieldAttributes['custom'])) + { + // set the custom array + $custom = $fieldAttributes['custom']; + unset($fieldAttributes['custom']); + // set db key + $custom['db'] = $dbkey; + // increment the db key + $dbkey++; + if ($build) + { + // set builders + $this->builders->set( + $langLabel, $langView, $nameSingleCode, + $nameListCode, $name, $view, $field, $typeName, + $multiple, $custom + ); + } + + // now add to the field set + $dynamicField = $this->field->get( + 'custom', $fieldAttributes, $name, $typeName, $langView, + $nameSingleCode, $nameListCode, $placeholders, + $optionArray, $custom + ); + } + else + { + if ($build) + { + // set builders + $this->builders->set( + $langLabel, $langView, $nameSingleCode, + $nameListCode, $name, $view, $field, $typeName, + $multiple + ); + } + + // now add to the field set + $dynamicField = $this->field->get( + 'plain', $fieldAttributes, $name, $typeName, $langView, + $nameSingleCode, $nameListCode, $placeholders, + $optionArray + ); + } + } + } + + return $dynamicField; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldString.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldString.php new file mode 100644 index 000000000..d31ff4b55 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldString.php @@ -0,0 +1,1167 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Field; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name; +use VDM\Joomla\Componentbuilder\Compiler\Field\TypeName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Attributes; +use VDM\Joomla\Componentbuilder\Compiler\Creator\CustomFieldTypeFile; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldtypeinterface; + + +/** + * Field String Creator Class + * + * @since 3.2.0 + */ +final class FieldString implements Fieldtypeinterface +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Field Class. + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * The Groups Class. + * + * @var Groups + * @since 3.2.0 + */ + protected Groups $groups; + + /** + * The Name Class. + * + * @var Name + * @since 3.2.0 + */ + protected Name $name; + + /** + * The TypeName Class. + * + * @var TypeName + * @since 3.2.0 + */ + protected TypeName $typename; + + /** + * The Attributes Class. + * + * @var Attributes + * @since 3.2.0 + */ + protected Attributes $attributes; + + /** + * The CustomFieldTypeFile Class. + * + * @var CustomFieldTypeFile + * @since 3.2.0 + */ + protected CustomFieldTypeFile $customfieldtypefile; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Language $language The Language Class. + * @param Field $field The Field Class. + * @param Groups $groups The Groups Class. + * @param Name $name The Name Class. + * @param TypeName $typename The TypeName Class. + * @param Attributes $attributes The Attributes Class. + * @param CustomFieldTypeFile $customfieldtypefile The CustomFieldTypeFile Class. + * @param Counter $counter The Counter Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Language $language, Field $field, + Groups $groups, Name $name, TypeName $typename, + Attributes $attributes, + CustomFieldTypeFile $customfieldtypefile, + Counter $counter) + { + $this->config = $config; + $this->language = $language; + $this->field = $field; + $this->groups = $groups; + $this->name = $name; + $this->typename = $typename; + $this->attributes = $attributes; + $this->customfieldtypefile = $customfieldtypefile; + $this->counter = $counter; + } + + /** + * Create a field using string manipulation + * + * @param string $setType The set of fields type + * @param array $fieldAttributes The field values + * @param string $name The field name + * @param string $typeName The field type + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The place holder and replace values + * @param array|null $optionArray The option bucket array used to set the field options if needed. + * @param array|null $custom Used when field is from config + * @param string $taber The tabs to add in layout + * + * @return string The field in a string + * @since 3.2.0 + */ + public function get(string $setType, array &$fieldAttributes, string &$name, + string &$typeName, string &$langView, string &$nameSingleCode, string &$nameListCode, + array $placeholders, ?array &$optionArray, ?array $custom = null, string $taber = ''): string + { + // count the dynamic fields created + $this->counter->field++; + + // build field set using string manipulation + $field = ''; + if ($setType === 'option') + { + // now add to the field set + $field .= PHP_EOL . Indent::_(1) . $taber . Indent::_(1) + . ""; + $field .= PHP_EOL . Indent::_(1) . $taber . Indent::_(1) + . " $value) + { + if ($property != 'option') + { + $field .= PHP_EOL . Indent::_(2) . $taber . Indent::_(1) + . $property . '="' . $value . '"'; + } + elseif ($property === 'option') + { + $optionSet = ''; + if (strtolower($typeName) === 'groupedlist' + && strpos( + (string) $value, ',' + ) !== false + && strpos((string) $value, '@@') !== false) + { + // reset the group temp arrays + $groups_ = array(); + $grouped_ = array('group' => array(), + 'option' => array()); + $order_ = array(); + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + if (strpos($option, '@@') !== false) + { + // set the group label + $valueKeyArray = explode('@@', $option); + if (count((array) $valueKeyArray) == 2) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[0], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[0] + ); + // now add group label + $groups_[$valueKeyArray[1]] = PHP_EOL + . Indent::_(1) . $taber . Indent::_(2) + . ''; + // set order + $order_['group' . $valueKeyArray[1]] + = $valueKeyArray[1]; + } + } + elseif (strpos($option, '|') !== false) + { + // has other value then text + $valueKeyArray = explode('|', $option); + if (count((array) $valueKeyArray) == 3) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['group'][$valueKeyArray[2]][] + = PHP_EOL . Indent::_(1) . $taber + . Indent::_(3) . ''; + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['group' . $valueKeyArray[2]] + = $valueKeyArray[2]; + } + else + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['option'][$valueKeyArray[0]] + = PHP_EOL . Indent::_(1) . $taber + . Indent::_(2) . ''; + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['option' . $valueKeyArray[0]] + = $valueKeyArray[0]; + } + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $grouped_['option'][$option] = PHP_EOL + . Indent::_(1) . $taber . Indent::_(2) + . ''; + $optionArray[$option] = $langValue; + // set order + $order_['option' . $option] = $option; + } + } + // now build the groups + foreach ($order_ as $pointer_ => $_id) + { + // load the default key + $key_ = 'group'; + if (strpos($pointer_, 'option') !== false) + { + // load the option field + $key_ = 'option'; + } + // check if this is a group loader + if ('group' === $key_ && isset($groups_[$_id]) + && isset($grouped_[$key_][$_id]) + && ArrayHelper::check( + $grouped_[$key_][$_id] + )) + { + // set group label + $optionSet .= $groups_[$_id]; + foreach ($grouped_[$key_][$_id] as $option_) + { + $optionSet .= $option_; + } + unset($groups_[$_id]); + unset($grouped_[$key_][$_id]); + // close the group + $optionSet .= PHP_EOL . Indent::_(1) . $taber + . Indent::_(2) . ''; + } + elseif (isset($grouped_[$key_][$_id]) + && StringHelper::check( + $grouped_[$key_][$_id] + )) + { + $optionSet .= $grouped_[$key_][$_id]; + } + } + } + elseif (strpos((string) $value, ',') !== false) + { + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + if (strpos($option, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', $option); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $t + ); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(1) + . $taber . Indent::_(2) . ''; + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(2) + . $taber . Indent::_(1) . ''; + $optionArray[$option] = $langValue; + } + } + } + else + { + // one option + if (strpos((string) $value, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', (string) $value); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set($this->config->lang_target, $langValue, $t); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(2) . $taber + . Indent::_(1) . ''; + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $value, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $value + ); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(2) + . $taber . Indent::_(1) . ''; + $optionArray[$value] = $langValue; + } + } + } + } + // if options were found + if (StringHelper::check($optionSet)) + { + $field .= '>'; + $field .= PHP_EOL . Indent::_(3) . $taber . ""; + $field .= $optionSet; + $field .= PHP_EOL . Indent::_(2) . $taber . ""; + } + // if no options found and must have a list of options + elseif ($this->groups->check($typeName, 'list')) + { + $optionArray = null; + $field .= PHP_EOL . Indent::_(2) . $taber . "/>"; + $field .= PHP_EOL . Indent::_(2) . $taber . "" + . PHP_EOL; + } + else + { + $optionArray = null; + $field .= PHP_EOL . Indent::_(2) . $taber . "/>"; + } + } + elseif ($setType === 'plain') + { + // now add to the field set + $field .= PHP_EOL . Indent::_(2) . $taber . ""; + $field .= PHP_EOL . Indent::_(2) . $taber . " $value) + { + if ($property != 'option') + { + $field .= PHP_EOL . Indent::_(2) . $taber . Indent::_(1) + . $property . '="' . $value . '"'; + } + } + $field .= PHP_EOL . Indent::_(2) . $taber . "/>"; + } + elseif ($setType === 'spacer') + { + // now add to the field set + $field .= PHP_EOL . Indent::_(2) . ""; + $field .= PHP_EOL . Indent::_(2) . " $value) + { + if ($property != 'option') + { + $field .= " " . $property . '="' . $value . '"'; + } + } + $field .= " />"; + } + elseif ($setType === 'special') + { + // set the repeatable field + if ($typeName === 'repeatable') + { + // now add to the field set + $field .= PHP_EOL . Indent::_(2) . ""; + $field .= PHP_EOL . Indent::_(2) . " $value) + { + if ($property != 'fields') + { + $field .= PHP_EOL . Indent::_(3) . $property . '="' + . $value . '"'; + } + } + $field .= ">"; + $field .= PHP_EOL . Indent::_(3) . ''; + $field .= PHP_EOL . Indent::_(4) + . '"; + $field .= PHP_EOL . Indent::_(3) . ""; + $field .= PHP_EOL . Indent::_(2) . ""; + } + // set the subform fields (it is a repeatable without the modal) + elseif ($typeName === 'subform') + { + // now add to the field set + $field .= PHP_EOL . Indent::_(2) . $taber . ""; + $field .= PHP_EOL . Indent::_(2) . $taber . " $value) + { + if ($property != 'fields') + { + $field .= PHP_EOL . Indent::_(3) . $taber . $property + . '="' . $value . '"'; + } + } + $field .= ">"; + $field .= PHP_EOL . Indent::_(3) . $taber + . '"; + $field .= PHP_EOL . Indent::_(2) . $taber . ""; + } + } + elseif ($setType === 'custom') + { + // now add to the field set + $field .= PHP_EOL . Indent::_(2) . $taber . ""; + $field .= PHP_EOL . Indent::_(2) . $taber . " $value) + { + if ($property != 'option') + { + $field .= PHP_EOL . Indent::_(2) . $taber . Indent::_(1) + . $property . '="' . $value . '"'; + } + elseif ($property === 'option') + { + $optionSet = ''; + if (strtolower($typeName) === 'groupedlist' + && strpos( + (string) $value, ',' + ) !== false + && strpos((string) $value, '@@') !== false) + { + // reset the group temp arrays + $groups_ = array(); + $grouped_ = array('group' => array(), + 'option' => array()); + $order_ = array(); + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + if (strpos($option, '@@') !== false) + { + // set the group label + $valueKeyArray = explode('@@', $option); + if (count((array) $valueKeyArray) == 2) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[0], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[0] + ); + // now add group label + $groups_[$valueKeyArray[1]] = PHP_EOL + . Indent::_(1) . $taber . Indent::_(2) + . ''; + // set order + $order_['group' . $valueKeyArray[1]] + = $valueKeyArray[1]; + } + } + elseif (strpos($option, '|') !== false) + { + // has other value then text + $valueKeyArray = explode('|', $option); + if (count((array) $valueKeyArray) == 3) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['group'][$valueKeyArray[2]][] + = PHP_EOL . Indent::_(1) . $taber + . Indent::_(3) . ''; + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['group' . $valueKeyArray[2]] + = $valueKeyArray[2]; + } + else + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['option'][$valueKeyArray[0]] + = PHP_EOL . Indent::_(1) . $taber + . Indent::_(2) . ''; + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['option' . $valueKeyArray[0]] + = $valueKeyArray[0]; + } + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $grouped_['option'][$option] = PHP_EOL + . Indent::_(1) . $taber . Indent::_(2) + . ''; + $optionArray[$option] = $langValue; + // set order + $order_['option' . $option] = $option; + } + } + // now build the groups + foreach ($order_ as $pointer_ => $_id) + { + // load the default key + $key_ = 'group'; + if (strpos($pointer_, 'option') !== false) + { + // load the option field + $key_ = 'option'; + } + // check if this is a group loader + if ('group' === $key_ && isset($groups_[$_id]) + && isset($grouped_[$key_][$_id]) + && ArrayHelper::check( + $grouped_[$key_][$_id] + )) + { + // set group label + $optionSet .= $groups_[$_id]; + foreach ($grouped_[$key_][$_id] as $option_) + { + $optionSet .= $option_; + } + unset($groups_[$_id]); + unset($grouped_[$key_][$_id]); + // close the group + $optionSet .= PHP_EOL . Indent::_(1) . $taber + . Indent::_(2) . ''; + } + elseif (isset($grouped_[$key_][$_id]) + && StringHelper::check( + $grouped_[$key_][$_id] + )) + { + $optionSet .= $grouped_[$key_][$_id]; + } + } + } + elseif (strpos((string) $value, ',') !== false) + { + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + if (strpos($option, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', $option); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $t + ); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(1) + . $taber . Indent::_(2) . ''; + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(2) + . $taber . Indent::_(1) . ''; + $optionArray[$option] = $langValue; + } + } + } + else + { + // one option + if (strpos((string) $value, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', (string) $value); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set($this->config->lang_target, $langValue, $t); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(2) . $taber + . Indent::_(1) . ''; + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $value, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $value + ); + // now add to option set + $optionSet .= PHP_EOL . Indent::_(2) + . $taber . Indent::_(1) . ''; + $optionArray[$value] = $langValue; + } + } + } + } + // if options were found + if (StringHelper::check($optionSet)) + { + $field .= '>'; + $field .= PHP_EOL . Indent::_(3) . $taber . ""; + $field .= $optionSet; + $field .= PHP_EOL . Indent::_(2) . $taber . ""; + } + // if no options found and must have a list of options + elseif ($this->groups->check($typeName, 'list')) + { + $optionArray = null; + $field .= PHP_EOL . Indent::_(2) . $taber . "/>"; + $field .= PHP_EOL . Indent::_(2) . $taber . "" + . PHP_EOL; + } + else + { + $optionArray = null; + $field .= PHP_EOL . Indent::_(2) . $taber . "/>"; + } + // incase the field is in the config and has not been set + if ('config' === $nameSingleCode && 'configs' === $nameListCode + || (strpos($nameSingleCode, 'pLuG!n') !== false + || strpos( + $nameSingleCode, 'M0dUl3' + ) !== false)) + { + // set lang (just incase) + $listLangName = $langView . '_' + . StringHelper::safe($name, 'U'); + // set the custom array + $data = array('type' => $typeName, 'code' => $name, + 'lang' => $listLangName, 'custom' => $custom); + // set the custom field file + $this->customfieldtypefile->set( + $data, $nameListCode, $nameSingleCode + ); + } + } + + // return field + return $field; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldXML.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldXML.php new file mode 100644 index 000000000..0c7da8818 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldXML.php @@ -0,0 +1,1145 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Field; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name; +use VDM\Joomla\Componentbuilder\Compiler\Field\TypeName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Attributes; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Xml; +use VDM\Joomla\Componentbuilder\Compiler\Creator\CustomFieldTypeFile; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldtypeinterface; + + +/** + * Field Simple XML Creator Class + * + * @since 3.2.0 + */ +final class FieldXML implements Fieldtypeinterface +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Field Class. + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * The Groups Class. + * + * @var Groups + * @since 3.2.0 + */ + protected Groups $groups; + + /** + * The Name Class. + * + * @var Name + * @since 3.2.0 + */ + protected Name $name; + + /** + * The TypeName Class. + * + * @var TypeName + * @since 3.2.0 + */ + protected TypeName $typename; + + /** + * The Attributes Class. + * + * @var Attributes + * @since 3.2.0 + */ + protected Attributes $attributes; + + /** + * The Xml Class. + * + * @var Xml + * @since 3.2.0 + */ + protected Xml $xml; + + /** + * The CustomFieldTypeFile Class. + * + * @var CustomFieldTypeFile + * @since 3.2.0 + */ + protected CustomFieldTypeFile $customfieldtypefile; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Language $language The Language Class. + * @param Field $field The Field Class. + * @param Groups $groups The Groups Class. + * @param Name $name The Name Class. + * @param TypeName $typename The TypeName Class. + * @param Attributes $attributes The Attributes Class. + * @param Xml $xml The Xml Class. + * @param CustomFieldTypeFile $customfieldtypefile The CustomFieldTypeFile Class. + * @param Counter $counter The Counter Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Language $language, Field $field, + Groups $groups, Name $name, TypeName $typename, + Attributes $attributes, Xml $xml, + CustomFieldTypeFile $customfieldtypefile, + Counter $counter) + { + $this->config = $config; + $this->language = $language; + $this->field = $field; + $this->groups = $groups; + $this->name = $name; + $this->typename = $typename; + $this->attributes = $attributes; + $this->xml = $xml; + $this->customfieldtypefile = $customfieldtypefile; + $this->counter = $counter; + } + + /** + * Create a field with simpleXMLElement class + * + * @param string $setType The set of fields type + * @param array $fieldAttributes The field values + * @param string $name The field name + * @param string $typeName The field type + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The place holder and replace values + * @param array|null $optionArray The option bucket array used to set the field options if needed. + * @param array|null $custom Used when field is from config + * @param string $taber The tabs not used... hmm + * + * @return \stdClass The field in xml object + * @since 3.2.0 + */ + public function get(string $setType, array &$fieldAttributes, string &$name, + string &$typeName, string &$langView, string &$nameSingleCode, string &$nameListCode, + array $placeholders, ?array &$optionArray, ?array $custom = null, string $taber = ''): \stdClass + { + // count the dynamic fields created + $this->counter->field++; + + $field = new \stdClass(); + if ($setType === 'option') + { + // now add to the field set + $field->fieldXML = new \SimpleXMLElement(''); + $field->comment = Line::_(__Line__, __Class__) . " " . ucfirst($name) + . " Field. Type: " . StringHelper::safe( + $typeName, 'F' + ) . ". (joomla)"; + + foreach ($fieldAttributes as $property => $value) + { + if ($property != 'option') + { + $field->fieldXML->addAttribute($property, $value); + } + elseif ($property === 'option') + { + $this->xml->comment( + $field->fieldXML, + Line::_(__Line__, __Class__) . " Option Set." + ); + if (strtolower($typeName) === 'groupedlist' + && strpos( + (string) $value, ',' + ) !== false + && strpos((string) $value, '@@') !== false) + { + // reset the group temp arrays + $groups_ = array(); + $grouped_ = array('group' => array(), + 'option' => array()); + $order_ = array(); + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + if (strpos($option, '@@') !== false) + { + // set the group label + $valueKeyArray = explode('@@', $option); + if (count((array) $valueKeyArray) == 2) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[0], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[0] + ); + // now add group label + $groups_[$valueKeyArray[1]] = $langValue; + // set order + $order_['group' . $valueKeyArray[1]] + = $valueKeyArray[1]; + } + } + elseif (strpos($option, '|') !== false) + { + // has other value then text + $valueKeyArray = explode('|', $option); + if (count((array) $valueKeyArray) == 3) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['group'][$valueKeyArray[2]][] + = array('value' => $valueKeyArray[0], + 'text' => $langValue); + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['group' . $valueKeyArray[2]] + = $valueKeyArray[2]; + } + else + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['option'][$valueKeyArray[0]] + = array('value' => $valueKeyArray[0], + 'text' => $langValue); + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['option' . $valueKeyArray[0]] + = $valueKeyArray[0]; + } + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $grouped_['option'][$option] + = array('value' => $option, + 'text' => $langValue); + $optionArray[$option] = $langValue; + // set order + $order_['option' . $option] = $option; + } + } + // now build the groups + foreach ($order_ as $pointer_ => $_id) + { + // load the default key + $key_ = 'group'; + if (strpos($pointer_, 'option') !== false) + { + // load the option field + $key_ = 'option'; + } + // check if this is a group loader + if ('group' === $key_ && isset($groups_[$_id]) + && isset($grouped_[$key_][$_id]) + && ArrayHelper::check( + $grouped_[$key_][$_id] + )) + { + // set group label + $groupXML = $field->fieldXML->addChild('group'); + $groupXML->addAttribute( + 'label', $groups_[$_id] + ); + + foreach ($grouped_[$key_][$_id] as $option_) + { + $groupOptionXML = $groupXML->addChild( + 'option' + ); + $groupOptionXML->addAttribute( + 'value', $option_['value'] + ); + $groupOptionXML[] = $option_['text']; + } + unset($groups_[$_id]); + unset($grouped_[$key_][$_id]); + } + elseif (isset($grouped_[$key_][$_id]) + && StringHelper::check( + $grouped_[$key_][$_id] + )) + { + $optionXML = $field->fieldXML->addChild( + 'option' + ); + $optionXML->addAttribute( + 'value', $grouped_[$key_][$_id]['value'] + ); + $optionXML[] = $grouped_[$key_][$_id]['text']; + } + } + } + elseif (strpos((string) $value, ',') !== false) + { + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + $optionXML = $field->fieldXML->addChild('option'); + if (strpos($option, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', $option); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $t + ); + // now add to option set + $optionXML->addAttribute('value', $v); + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $optionXML->addAttribute('value', $option); + $optionArray[$option] = $langValue; + } + $optionXML[] = $langValue; + } + } + else + { + // one option + $optionXML = $field->fieldXML->addChild('option'); + if (strpos((string) $value, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', (string) $value); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set($this->config->lang_target, $langValue, $t); + // now add to option set + $optionXML->addAttribute('value', $v); + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $value, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $value + ); + // now add to option set + $optionXML->addAttribute('value', $value); + $optionArray[$value] = $langValue; + } + $optionXML[] = $langValue; + } + } + } + // if no options found and must have a list of options + if (!$field->fieldXML->count() + && $this->groups->check($typeName, 'list')) + { + $this->xml->comment( + $field->fieldXML, Line::_(__Line__, __Class__) + . " No Manual Options Were Added In Field Settings." + ); + } + } + elseif ($setType === 'plain') + { + // now add to the field set + $field->fieldXML = new \SimpleXMLElement(''); + $field->comment = Line::_(__Line__, __Class__) . " " . ucfirst($name) + . " Field. Type: " . StringHelper::safe( + $typeName, 'F' + ) . ". (joomla)"; + + foreach ($fieldAttributes as $property => $value) + { + if ($property != 'option') + { + $field->fieldXML->addAttribute($property, $value); + } + } + } + elseif ($setType === 'spacer') + { + // now add to the field set + $field->fieldXML = new \SimpleXMLElement(''); + $field->comment = Line::_(__Line__, __Class__) . " " . ucfirst($name) + . " Field. Type: " . StringHelper::safe( + $typeName, 'F' + ) . ". A None Database Field. (joomla)"; + + foreach ($fieldAttributes as $property => $value) + { + if ($property != 'option') + { + $field->fieldXML->addAttribute($property, $value); + } + } + } + elseif ($setType === 'special') + { + // set the repeatable field + if ($typeName === 'repeatable') + { + // now add to the field set + $field->fieldXML = new \SimpleXMLElement(''); + $field->comment = Line::_(__Line__, __Class__) . " " . ucfirst( + $name + ) . " Field. Type: " . StringHelper::safe( + $typeName, 'F' + ) . ". (depreciated)"; + + foreach ($fieldAttributes as $property => $value) + { + if ($property != 'fields') + { + $field->fieldXML->addAttribute($property, $value); + } + } + $fieldsXML = $field->fieldXML->addChild('fields'); + $fieldsXML->addAttribute( + 'name', $fieldAttributes['name'] . '_fields' + ); + $fieldsXML->addAttribute('label', ''); + $fieldSetXML = $fieldsXML->addChild('fieldset'); + $fieldSetXML->addAttribute('hidden', 'true'); + $fieldSetXML->addAttribute( + 'name', $fieldAttributes['name'] . '_modal' + ); + $fieldSetXML->addAttribute('repeat', 'true'); + + if (strpos((string) $fieldAttributes['fields'], ',') !== false) + { + // mulitpal fields + $fieldsSets = (array) explode( + ',', (string) $fieldAttributes['fields'] + ); + } + elseif (is_numeric($fieldAttributes['fields'])) + { + // single field + $fieldsSets[] = (int) $fieldAttributes['fields']; + } + // only continue if we have a field set + if (ArrayHelper::check($fieldsSets)) + { + // set the resolver + $_resolverKey = $fieldAttributes['name']; + // load the field data + $fieldsSets = array_map( + function ($id) use ( + $nameSingleCode, $nameListCode, $_resolverKey + ) { + // start field + $field = array(); + $field['field'] = $id; + // set the field details + $this->field->set( + $field, $nameSingleCode, $nameListCode, + $_resolverKey + ); + + // return field + return $field; + }, array_values($fieldsSets) + ); + // start the build + foreach ($fieldsSets as $fieldData) + { + // if we have settings continue + if (ObjectHelper::check( + $fieldData['settings'] + )) + { + $r_name = $this->name->get( + $fieldData, $nameListCode, $_resolverKey + ); + $r_typeName = $this->typename->get($fieldData); + $r_multiple = false; + $viewType = 0; + $r_langLabel = ''; + // get field values + $r_fieldValues = $this->attributes->set( + $fieldData, $viewType, $r_name, $r_typeName, + $r_multiple, $r_langLabel, $langView, + $nameListCode, $nameSingleCode, + $placeholders, true + ); + // check if values were set + if (ArrayHelper::check( + $r_fieldValues + )) + { + //reset options array + $r_optionArray = array(); + if ($this->groups->check( + $r_typeName, 'option' + )) + { + // now add to the field set + $this->xml->append( + $fieldSetXML, $this->get( + 'option', $r_fieldValues, $r_name, + $r_typeName, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $r_optionArray + ) + ); + } + elseif (isset($r_fieldValues['custom']) + && ArrayHelper::check( + $r_fieldValues['custom'] + )) + { + // add to custom + $custom = $r_fieldValues['custom']; + unset($r_fieldValues['custom']); + // now add to the field set + $this->xml->append( + $fieldSetXML, $this->get( + 'custom', $r_fieldValues, $r_name, + $r_typeName, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $r_optionArray + ) + ); + // set lang (just incase) + $r_listLangName = $langView . '_' + . FieldHelper::safe( + $r_name, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $r_listLangName, + StringHelper::safe( + $r_name, 'W' + ) + ); + // if label was set use instead + if (StringHelper::check( + $r_langLabel + )) + { + $r_listLangName = $r_langLabel; + } + // set the custom array + $data = array('type' => $r_typeName, + 'code' => $r_name, + 'lang' => $r_listLangName, + 'custom' => $custom); + // set the custom field file + $this->customfieldtypefile->set( + $data, $nameListCode, + $nameSingleCode + ); + } + else + { + // now add to the field set + $this->xml->append( + $fieldSetXML, $this->get( + 'plain', $r_fieldValues, $r_name, + $r_typeName, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $r_optionArray + ) + ); + } + } + } + } + } + } + // set the subform fields (it is a repeatable without the modal) + elseif ($typeName === 'subform') + { + // now add to the field set + $field->fieldXML = new \SimpleXMLElement(''); + $field->comment = Line::_(__Line__, __Class__) . " " . ucfirst( + $name + ) . " Field. Type: " . StringHelper::safe( + $typeName, 'F' + ) . ". (joomla)"; + // add all properties + foreach ($fieldAttributes as $property => $value) + { + if ($property != 'fields' && $property != 'formsource') + { + $field->fieldXML->addAttribute($property, $value); + } + } + // if we detect formsource we do not add the form + if (isset($fieldAttributes['formsource']) + && StringHelper::check( + $fieldAttributes['formsource'] + )) + { + $field->fieldXML->addAttribute( + 'formsource', $fieldAttributes['formsource'] + ); + } + // add the form + else + { + $form = $field->fieldXML->addChild('form'); + $attributes = array( + 'hidden' => 'true', + 'name' => 'list_' . $fieldAttributes['name'] + . '_modal', + 'repeat' => 'true' + ); + $this->xml->attributes( + $form, $attributes + ); + + if (strpos((string) $fieldAttributes['fields'], ',') !== false) + { + // multiple fields + $fieldsSets = (array) explode( + ',', (string) $fieldAttributes['fields'] + ); + } + elseif (is_numeric($fieldAttributes['fields'])) + { + // single field + $fieldsSets[] = (int) $fieldAttributes['fields']; + } + // only continue if we have a field set + if (ArrayHelper::check($fieldsSets)) + { + // set the resolver + $_resolverKey = $fieldAttributes['name']; + // load the field data + $fieldsSets = array_map( + function ($id) use ( + $nameSingleCode, $nameListCode, + $_resolverKey + ) { + // start field + $field = array(); + $field['field'] = $id; + // set the field details + $this->field->set( + $field, $nameSingleCode, $nameListCode, + $_resolverKey + ); + + // return field + return $field; + }, array_values($fieldsSets) + ); + // start the build + foreach ($fieldsSets as $fieldData) + { + // if we have settings continue + if (ObjectHelper::check( + $fieldData['settings'] + )) + { + $r_name = $this->name->get( + $fieldData, $nameListCode, $_resolverKey + ); + $r_typeName = $this->typename->get($fieldData); + $r_multiple = false; + $viewType = 0; + $r_langLabel = ''; + // get field values + $r_fieldValues = $this->attributes->set( + $fieldData, $viewType, $r_name, $r_typeName, + $r_multiple, $r_langLabel, $langView, + $nameListCode, $nameSingleCode, + $placeholders, true + ); + // check if values were set + if (ArrayHelper::check( + $r_fieldValues + )) + { + //reset options array + $r_optionArray = array(); + if ($this->groups->check( + $r_typeName, 'option' + )) + { + // now add to the field set + $this->xml->append( + $form, $this->get( + 'option', $r_fieldValues, $r_name, + $r_typeName, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $r_optionArray + ) + ); + } + elseif ($r_typeName === 'subform') + { + // set nested depth + if (isset($fieldAttributes['nested_depth'])) + { + $r_fieldValues['nested_depth'] + = ++$fieldAttributes['nested_depth']; + } + else + { + $r_fieldValues['nested_depth'] = 1; + } + // only continue if nest is bellow 20 (this should be a safe limit) + if ($r_fieldValues['nested_depth'] + <= 20) + { + // now add to the field set + $this->xml->append( + $form, $this->get( + 'special', $r_fieldValues, + $r_name, $r_typeName, $langView, + $nameSingleCode, + $nameListCode, $placeholders, + $r_optionArray + ) + ); + } + + } + elseif (isset($r_fieldValues['custom']) + && ArrayHelper::check( + $r_fieldValues['custom'] + )) + { + // add to custom + $custom = $r_fieldValues['custom']; + unset($r_fieldValues['custom']); + // now add to the field set + $this->xml->append( + $form, $this->get( + 'custom', $r_fieldValues, $r_name, + $r_typeName, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $r_optionArray + ) + ); + // set lang (just incase) + $r_listLangName = $langView . '_' + . FieldHelper::safe( + $r_name, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $r_listLangName, + StringHelper::safe( + $r_name, 'W' + ) + ); + // if label was set use instead + if (StringHelper::check( + $r_langLabel + )) + { + $r_listLangName = $r_langLabel; + } + // set the custom array + $data = array('type' => $r_typeName, + 'code' => $r_name, + 'lang' => $r_listLangName, + 'custom' => $custom); + // set the custom field file + $this->customfieldtypefile->set( + $data, $nameListCode, + $nameSingleCode + ); + } + else + { + // now add to the field set + $this->xml->append( + $form, $this->get( + 'plain', $r_fieldValues, $r_name, + $r_typeName, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $r_optionArray + ) + ); + } + } + } + } + } + } + } + } + elseif ($setType === 'custom') + { + // now add to the field set + $field->fieldXML = new \SimpleXMLElement(''); + $field->comment = Line::_(__Line__, __Class__) . " " . ucfirst($name) + . " Field. Type: " . StringHelper::safe( + $typeName, 'F' + ) . ". (custom)"; + foreach ($fieldAttributes as $property => $value) + { + if ($property != 'option') + { + $field->fieldXML->addAttribute($property, $value); + } + elseif ($property === 'option') + { + $this->xml->comment( + $field->fieldXML, + Line::_(__Line__, __Class__) . " Option Set." + ); + if (strtolower($typeName) === 'groupedlist' + && strpos( + (string) $value, ',' + ) !== false + && strpos((string) $value, '@@') !== false) + { + // reset the group temp arrays + $groups_ = array(); + $grouped_ = array('group' => array(), + 'option' => array()); + $order_ = array(); + // mulitpal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + if (strpos($option, '@@') !== false) + { + // set the group label + $valueKeyArray = explode('@@', $option); + if (count((array) $valueKeyArray) == 2) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[0], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[0] + ); + // now add group label + $groups_[$valueKeyArray[1]] = $langValue; + // set order + $order_['group' . $valueKeyArray[1]] + = $valueKeyArray[1]; + } + } + elseif (strpos($option, '|') !== false) + { + // has other value then text + $valueKeyArray = explode('|', $option); + if (count((array) $valueKeyArray) == 3) + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['group'][$valueKeyArray[2]][] + = array('value' => $valueKeyArray[0], + 'text' => $langValue); + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['group' . $valueKeyArray[2]] + = $valueKeyArray[2]; + } + else + { + $langValue = $langView . '_' + . FieldHelper::safe( + $valueKeyArray[1], true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, + $valueKeyArray[1] + ); + // now add to option set + $grouped_['option'][$valueKeyArray[0]] + = array('value' => $valueKeyArray[0], + 'text' => $langValue); + $optionArray[$valueKeyArray[0]] + = $langValue; + // set order + $order_['option' . $valueKeyArray[0]] + = $valueKeyArray[0]; + } + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $grouped_['option'][$option] + = array('value' => $option, + 'text' => $langValue); + $optionArray[$option] = $langValue; + // set order + $order_['option' . $option] = $option; + } + } + // now build the groups + foreach ($order_ as $pointer_ => $_id) + { + // load the default key + $key_ = 'group'; + if (strpos($pointer_, 'option') !== false) + { + // load the option field + $key_ = 'option'; + } + // check if this is a group loader + if ('group' === $key_ && isset($groups_[$_id]) + && isset($grouped_[$key_][$_id]) + && ArrayHelper::check( + $grouped_[$key_][$_id] + )) + { + // set group label + $groupXML = $field->fieldXML->addChild('group'); + $groupXML->addAttribute( + 'label', $groups_[$_id] + ); + + foreach ($grouped_[$key_][$_id] as $option_) + { + $groupOptionXML = $groupXML->addChild( + 'option' + ); + $groupOptionXML->addAttribute( + 'value', $option_['value'] + ); + $groupOptionXML[] = $option_['text']; + } + unset($groups_[$_id]); + unset($grouped_[$key_][$_id]); + } + elseif (isset($grouped_[$key_][$_id]) + && StringHelper::check( + $grouped_[$key_][$_id] + )) + { + $optionXML = $field->fieldXML->addChild( + 'option' + ); + $optionXML->addAttribute( + 'value', $grouped_[$key_][$_id]['value'] + ); + $optionXML[] = $grouped_[$key_][$_id]['text']; + } + } + } + elseif (strpos((string) $value, ',') !== false) + { + // municipal options + $options = explode(',', (string) $value); + foreach ($options as $option) + { + $optionXML = $field->fieldXML->addChild('option'); + if (strpos($option, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', $option); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $t + ); + // now add to option set + $optionXML->addAttribute('value', $v); + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $option, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $option + ); + // now add to option set + $optionXML->addAttribute('value', $option); + $optionArray[$option] = $langValue; + } + $optionXML[] = $langValue; + } + } + else + { + // one option + $optionXML = $field->fieldXML->addChild('option'); + if (strpos((string) $value, '|') !== false) + { + // has other value then text + list($v, $t) = explode('|', (string) $value); + $langValue = $langView . '_' + . FieldHelper::safe( + $t, true + ); + // add to lang array + $this->language->set($this->config->lang_target, $langValue, $t); + // now add to option set + $optionXML->addAttribute('value', $v); + $optionArray[$v] = $langValue; + } + else + { + // text is also the value + $langValue = $langView . '_' + . FieldHelper::safe( + $value, true + ); + // add to lang array + $this->language->set( + $this->config->lang_target, $langValue, $value + ); + // now add to option set + $optionXML->addAttribute('value', $value); + $optionArray[$value] = $langValue; + } + $optionXML[] = $langValue; + } + } + } + // incase the field is in the config and has not been set (or is part of a plugin or module) + if (('config' === $nameSingleCode + && 'configs' === $nameListCode) + || (strpos($nameSingleCode, 'pLuG!n') !== false + || strpos( + $nameSingleCode, 'M0dUl3' + ) !== false)) + { + // set lang (just incase) + $listLangName = $langView . '_' + . StringHelper::safe($name, 'U'); + // set the custom array + $data = array('type' => $typeName, 'code' => $name, + 'lang' => $listLangName, 'custom' => $custom); + // set the custom field file + $this->customfieldtypefile->set( + $data, $nameListCode, $nameSingleCode + ); + } + } + + return $field; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetDynamic.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetDynamic.php new file mode 100644 index 000000000..611e8c853 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetDynamic.php @@ -0,0 +1,107 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldAsString; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Fieldset Dynamic Creator Class + * + * @since 3.2.0 + */ +final class FieldsetDynamic +{ + /** + * The FieldAsString Class. + * + * @var FieldAsString + * @since 3.2.0 + */ + protected FieldAsString $fieldasstring; + + /** + * Constructor. + * + * @param FieldAsString $fieldasstring The FieldAsString Class. + * + * @since 3.2.0 + */ + public function __construct(FieldAsString $fieldasstring) + { + $this->fieldasstring = $fieldasstring; + } + + /** + * build field set + * + * @param array $fields The fields data + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The placeholder and replace values + * @param string $dbkey The custom table key + * @param boolean $build The switch to set the build option + * @param int $return_type The return type 1 = string, 2 = array + * + * @return mixed The complete field in string or array + * @since 3.2.0 + */ + public function get(array &$fields, string &$langView, string &$nameSingleCode, + string &$nameListCode, array &$placeholders, string &$dbkey, bool $build = false, + int $returnType = 1) + { + // set some defaults + $view = []; + $view_type = 0; + // build the fieldset + if ($returnType == 1) + { + $fieldset = ''; + } + else + { + $fieldset = []; + } + // loop over the fields to build + if (ArrayHelper::check($fields)) + { + foreach ($fields as $field) + { + // get the field + $field_xml_string = $this->fieldasstring->get( + $field, $view, $view_type, $langView, + $nameSingleCode, $nameListCode, + $placeholders, $dbkey, $build + ); + // make sure the xml is set and a string + if (StringHelper::check($field_xml_string)) + { + if ($returnType == 1) + { + $fieldset .= $field_xml_string; + } + else + { + $fieldset[] = $field_xml_string; + } + } + } + } + + return $fieldset; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetString.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetString.php new file mode 100644 index 000000000..270627e53 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetString.php @@ -0,0 +1,616 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language\Fieldset as Language; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Componentbuilder\Compiler\Adminview\Permission; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldDynamic; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldNames; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MetaData; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Layout; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldsetinterface; + + +/** + * Fieldset String Creator Class + * + * @since 3.2.0 + */ +final class FieldsetString implements Fieldsetinterface +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Fieldset Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * The Permission Class. + * + * @var Permission + * @since 3.2.0 + */ + protected Permission $permission; + + /** + * The FieldDynamic Class. + * + * @var FieldDynamic + * @since 3.2.0 + */ + protected FieldDynamic $fielddynamic; + + /** + * The FieldNames Class. + * + * @var FieldNames + * @since 3.2.0 + */ + protected FieldNames $fieldnames; + + /** + * The AccessSwitch Class. + * + * @var AccessSwitch + * @since 3.2.0 + */ + protected AccessSwitch $accessswitch; + + /** + * The MetaData Class. + * + * @var MetaData + * @since 3.2.0 + */ + protected MetaData $metadata; + + /** + * The Layout Class. + * + * @var Layout + * @since 3.2.0 + */ + protected Layout $layout; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Language $language The Fieldset Class. + * @param Event $event The EventInterface Class. + * @param Permission $permission The Permission Class. + * @param FieldDynamic $fielddynamic The FieldDynamic Class. + * @param FieldNames $fieldnames The FieldNames Class. + * @param AccessSwitch $accessswitch The AccessSwitch Class. + * @param MetaData $metadata The MetaData Class. + * @param Layout $layout The Layout Class. + * @param Counter $counter The Counter Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Placeholder $placeholder, + Language $language, Event $event, Permission $permission, + FieldDynamic $fielddynamic, FieldNames $fieldnames, + AccessSwitch $accessswitch, MetaData $metadata, + Layout $layout, Counter $counter) + { + $this->config = $config; + $this->placeholder = $placeholder; + $this->language = $language; + $this->event = $event; + $this->permission = $permission; + $this->fielddynamic = $fielddynamic; + $this->fieldnames = $fieldnames; + $this->accessswitch = $accessswitch; + $this->metadata = $metadata; + $this->layout = $layout; + $this->counter = $counter; + } + + /** + * Get a fieldset + * + * @param array $view The view data + * @param string $component The component name + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * + * @return string The fields set as a string or empty string if no field found. + * @since 3.2.0 + */ + public function get(array $view, string $component, string $nameSingleCode, + string $nameListCode): string + { + // setup the fieldset language values of this view + if (!isset($view['settings']->fields) + || !ArrayHelper::check($view['settings']->fields)) + { + return ''; + } + + // add metadata to the view + $metadata = false; + if (isset($view['metadata']) && $view['metadata']) + { + $metadata = true; + } + + // add access to the view + $access = false; + if (isset($view['access']) && $view['access']) + { + $access = true; + } + + // main lang prefix + $lang_view = $this->config->lang_prefix . '_' + . $this->placeholder->get('VIEW'); + $lang_views = $this->config->lang_prefix . '_' + . $this->placeholder->get('VIEWS'); + + $name_single = $view['settings']->name_single ?? 'Error'; + $name_list = $view['settings']->name_list ?? 'Error'; + $lang_target = $this->config->lang_target ?? 'both'; + + // load the language values + $this->language->set( + $access, + $metadata, + $lang_target, + $lang_view, + $lang_views, + $name_single, + $name_list, + $nameSingleCode, + $nameListCode + ); + + // set the read only + $read_only = false; + if ($view['settings']->type == 2) + { + $read_only = Indent::_(3) . 'readonly="true"' . PHP_EOL . Indent::_( + 3 + ) . 'disabled="true"'; + } + // start adding dynamic fields + $dynamic_fields = ''; + // set the custom table key + $dbkey = 'g'; + // for plugin event TODO change event api signatures + $placeholders = $this->placeholder->active; + $component_context = $this->config->component_context; + // Trigger Event: jcb_ce_onBeforeBuildFields + $this->event->trigger( + 'jcb_ce_onBeforeBuildFields', + array(&$component_context, &$dynamic_fields, &$read_only, + &$dbkey, &$view, &$component, &$nameSingleCode, + &$nameListCode, &$placeholders, &$lang_view, + &$lang_views) + ); + unset($placeholders); + // TODO we should add the global and local view switch if field for front end + foreach ($view['settings']->fields as $field) + { + $dynamic_fields .= $this->fielddynamic->get( + $field, $view, $view['settings']->type, $lang_view, + $nameSingleCode, $nameListCode, $this->placeholder->active, $dbkey, + true + ); + } + // for plugin event TODO change event api signatures + $placeholders = $this->placeholder->active; + // Trigger Event: jcb_ce_onAfterBuildFields + $this->event->trigger( + 'jcb_ce_onAfterBuildFields', + array(&$component_context, &$dynamic_fields, &$read_only, + &$dbkey, &$view, &$component, &$nameSingleCode, + &$nameListCode, &$placeholders, &$lang_view, + &$lang_views) + ); + unset($placeholders); + // set the default fields + $field_set = array(); + $field_set[] = '
'; + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // if id is not set + if (!$this->fieldnames->isString($nameSingleCode . '.id')) + { + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // if created is not set + if (!$this->fieldnames->isString($nameSingleCode . '.created')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // if created_by is not set + if (!$this->fieldnames->isString($nameSingleCode . '.created_by')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // if published is not set + if (!$this->fieldnames->isString($nameSingleCode . '.published')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . "'; + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // if modified is not set + if (!$this->fieldnames->isString($nameSingleCode . '.modified')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) + . ''; + // count the static field created + $this->counter->field++; + } + // if modified_by is not set + if (!$this->fieldnames->isString($nameSingleCode . '.modified_by')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) + . '"; + // count the static field created + $this->counter->field++; + } + // check if view has access + if ($this->accessswitch->exists($nameSingleCode) + && !$this->fieldnames->isString($nameSingleCode . '.access')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . '"; + // count the static field created + $this->counter->field++; + } + // if ordering is not set + if (!$this->fieldnames->isString($nameSingleCode . '.ordering')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // if version is not set + if (!$this->fieldnames->isString($nameSingleCode . '.version')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // check if metadata is added to this view + if ($this->metadata->isString($nameSingleCode)) + { + // metakey + if (!$this->fieldnames->isString($nameSingleCode . '.metakey')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + // metadesc + if (!$this->fieldnames->isString($nameSingleCode . '.metadesc')) + { + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + } + } + // fix the permissions field "title" issue gh-629 + // check if the title is not already set + if (!$this->fieldnames->isString($nameSingleCode . '.title') + && $this->permission->check($view, $nameSingleCode)) + { + // set the field/tab name + $field_name = "title"; + $tab_name = "publishing"; + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + $field_set[] = Indent::_(2) . ""; + // at this point we know that we must add a hidden title field + // and make sure it does not get stored to the database + $field_set[] = Indent::_(2) . ""; + // count the static field created + $this->counter->field++; + // setup needed field values for layout + $field_array = array(); + $field_array['order_edit'] = 0; + $field_array['tab'] = 15; + $field_array['alignment'] = 1; + // make sure it gets added to view + $this->layout->set( + $nameSingleCode, $tab_name, $field_name, $field_array + ); + } + // load the dynamic fields now + if (StringHelper::check($dynamic_fields)) + { + $field_set[] = Indent::_(2) . "" . $dynamic_fields; + } + // close fieldset + $field_set[] = Indent::_(1) . "
"; + // check if metadata is added to this view + if ($this->metadata->isString($nameSingleCode)) + { + if (!$this->fieldnames->isString($nameSingleCode . '.robots') + || !$this->fieldnames->isString($nameSingleCode . '.rights') + || !$this->fieldnames->isString($nameSingleCode . '.author')) + { + $field_set[] = PHP_EOL . Indent::_(1) . ""; + $field_set[] = Indent::_(1) . "'; + $field_set[] = Indent::_(2) . '
'; + // robots + if (!$this->fieldnames->isString($nameSingleCode . '.robots')) + { + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(3) . ''; + $field_set[] = Indent::_(4) + . ''; + $field_set[] = Indent::_(4) + . ''; + $field_set[] = Indent::_(4) + . ''; + $field_set[] = Indent::_(4) + . ''; + $field_set[] = Indent::_(4) + . ''; + $field_set[] = Indent::_(3) . ''; + // count the static field created + $this->counter->field++; + } + // author + if (!$this->fieldnames->isString($nameSingleCode . '.author')) + { + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(3) . '"; + // count the static field created + $this->counter->field++; + } + // rights + if (!$this->fieldnames->isString($nameSingleCode . '.rights')) + { + $field_set[] = Indent::_(3) . ""; + $field_set[] = Indent::_(3) + . '"; + // count the static field created + $this->counter->field++; + } + $field_set[] = Indent::_(2) . "
"; + $field_set[] = Indent::_(1) . ""; + } + } + + // return the set + return implode(PHP_EOL, $field_set); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetXML.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetXML.php new file mode 100644 index 000000000..4e5292c67 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/FieldsetXML.php @@ -0,0 +1,680 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language\Fieldset as Language; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Componentbuilder\Compiler\Adminview\Permission; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldDynamic; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldNames; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MetaData; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Layout; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Xml; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldsetinterface; + + +/** + * Fieldset XML Creator Class + * + * @since 3.2.0 + */ +final class FieldsetXML implements Fieldsetinterface +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Fieldset Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * The Permission Class. + * + * @var Permission + * @since 3.2.0 + */ + protected Permission $permission; + + /** + * The FieldDynamic Class. + * + * @var FieldDynamic + * @since 3.2.0 + */ + protected FieldDynamic $fielddynamic; + + /** + * The FieldNames Class. + * + * @var FieldNames + * @since 3.2.0 + */ + protected FieldNames $fieldnames; + + /** + * The AccessSwitch Class. + * + * @var AccessSwitch + * @since 3.2.0 + */ + protected AccessSwitch $accessswitch; + + /** + * The MetaData Class. + * + * @var MetaData + * @since 3.2.0 + */ + protected MetaData $metadata; + + /** + * The Layout Class. + * + * @var Layout + * @since 3.2.0 + */ + protected Layout $layout; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * The Xml Class. + * + * @var Xml + * @since 3.2.0 + */ + protected Xml $xml; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Language $language The Fieldset Class. + * @param Event $event The EventInterface Class. + * @param Permission $permission The Permission Class. + * @param FieldDynamic $fielddynamic The FieldDynamic Class. + * @param FieldNames $fieldnames The FieldNames Class. + * @param AccessSwitch $accessswitch The AccessSwitch Class. + * @param MetaData $metadata The MetaData Class. + * @param Layout $layout The Layout Class. + * @param Counter $counter The Counter Class. + * @param Xml $xml The Xml Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Placeholder $placeholder, + Language $language, Event $event, Permission $permission, + FieldDynamic $fielddynamic, FieldNames $fieldnames, + AccessSwitch $accessswitch, MetaData $metadata, + Layout $layout, Counter $counter, Xml $xml) + { + $this->config = $config; + $this->placeholder = $placeholder; + $this->language = $language; + $this->event = $event; + $this->permission = $permission; + $this->fielddynamic = $fielddynamic; + $this->fieldnames = $fieldnames; + $this->accessswitch = $accessswitch; + $this->metadata = $metadata; + $this->layout = $layout; + $this->counter = $counter; + $this->xml = $xml; + } + + /** + * Get a fieldset + * + * @param array $view The view data + * @param string $component The component name + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * + * @return string The fields set as a string or empty string if no field found. + * @since 3.2.0 + */ + public function get(array $view, string $component, string $nameSingleCode, + string $nameListCode): string + { + // setup the fieldset language values of this view + if (!isset($view['settings']->fields) + || !ArrayHelper::check($view['settings']->fields)) + { + return ''; + } + + // add metadata to the view + $metadata = false; + if (isset($view['metadata']) && $view['metadata']) + { + $metadata = true; + } + + // add access to the view + $access = false; + if (isset($view['access']) && $view['access']) + { + $access = true; + } + + // main lang prefix + $lang_view = $this->config->lang_prefix . '_' + . $this->placeholder->get('VIEW'); + $lang_views = $this->config->lang_prefix . '_' + . $this->placeholder->get('VIEWS'); + + $name_single = $view['settings']->name_single ?? 'Error'; + $name_list = $view['settings']->name_list ?? 'Error'; + $lang_target = $this->config->lang_target ?? 'both'; + + // load the language values + $this->language->set( + $access, + $metadata, + $lang_target, + $lang_view, + $lang_views, + $name_single, + $name_list, + $nameSingleCode, + $nameListCode + ); + + // set the read only + $read_only_xml = []; + if ($view['settings']->type == 2) + { + $read_only_xml['readonly'] = true; + $read_only_xml['disabled'] = true; + } + // start adding dynamc fields + $dynamic_fields_xml = []; + // set the custom table key + $dbkey = 'g'; + // for plugin event TODO change event api signatures + $placeholders = $this->placeholder->active; + $component_context = $this->config->component_context; + // Trigger Event: jcb_ce_onBeforeBuildFields + $this->event->trigger( + 'jcb_ce_onBeforeBuildFields', + array(&$component_context, &$dynamic_fields_xml, &$read_only_xml, + &$dbkey, &$view, &$component, &$nameSingleCode, + &$nameListCode, &$placeholders, &$lang_view, + &$lang_views) + ); + unset($placeholders); + // TODO we should add the global and local view switch if field for front end + foreach ($view['settings']->fields as $field) + { + $dynamic_fields_xml[] = $this->fielddynamic->get( + $field, $view, $view['settings']->type, $lang_view, + $nameSingleCode, $nameListCode, $this->placeholder->active, $dbkey, + true + ); + } + // for plugin event TODO change event api signatures + $placeholders = $this->placeholder->active; + // Trigger Event: jcb_ce_onAfterBuildFields + $this->event->trigger( + 'jcb_ce_onAfterBuildFields', + array(&$component_context, &$dynamic_fields_xml, &$read_only_xml, + &$dbkey, &$view, &$component, &$nameSingleCode, + &$nameListCode, &$placeholders, &$lang_view, + &$lang_views) + ); + unset($placeholders); + // set the default fields + $main_xml = new \simpleXMLElement(''); + $field_set_xml = $main_xml->addChild('fieldset'); + $field_set_xml->addAttribute('name', 'details'); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) . " Default Fields." + ); + $this->xml->comment( + $field_set_xml, + Line::_(__Line__, __Class__) . " Id Field. Type: Text (joomla)" + ); + // if id is not set + if (!$this->fieldnames->isString($nameSingleCode . '.id')) + { + $attributes = [ + 'name' => 'id', + 'type' => 'text', + 'class' => 'readonly', + 'readonly' => "true", + 'label' => 'JGLOBAL_FIELD_ID_LABEL', + 'description' => 'JGLOBAL_FIELD_ID_DESC', + 'size' => 10, + 'default' => 0 + ]; + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // if created is not set + if (!$this->fieldnames->isString($nameSingleCode . '.created')) + { + $attributes = [ + 'name' => 'created', + 'type' => 'calendar', + 'label' => $lang_view . '_CREATED_DATE_LABEL', + 'description' => $lang_view . '_CREATED_DATE_DESC', + 'size' => 22, + 'format' => '%Y-%m-%d %H:%M:%S', + 'filter' => 'user_utc' + ]; + $attributes = array_merge($attributes, $read_only_xml); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Date Created Field. Type: Calendar (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // if created_by is not set + if (!$this->fieldnames->isString($nameSingleCode . '.created_by')) + { + $attributes = [ + 'name' => 'created_by', + 'type' => 'user', + 'label' => $lang_view . '_CREATED_BY_LABEL', + 'description' => $lang_view . '_CREATED_BY_DESC', + ]; + $attributes = array_merge($attributes, $read_only_xml); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " User Created Field. Type: User (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // if published is not set + if (!$this->fieldnames->isString($nameSingleCode . '.published')) + { + $attributes = [ + 'name' => 'published', + 'type' => 'list', + 'label' => 'JSTATUS' + ]; + $attributes = array_merge($attributes, $read_only_xml); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Published Field. Type: List (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + foreach (['JPUBLISHED' => 1, 'JUNPUBLISHED' => 0, + 'JARCHIVED' => 2, 'JTRASHED' => -2] as $text => $value + ) + { + $optionXML = $field_xml->addChild('option'); + $optionXML->addAttribute('value', $value); + $optionXML[] = $text; + } + } + // if modified is not set + if (!$this->fieldnames->isString($nameSingleCode . '.modified')) + { + $attributes = [ + 'name' => 'modified', + 'type' => 'calendar', + 'class' => 'readonly', + 'label' => $lang_view . '_MODIFIED_DATE_LABEL', + 'description' => $lang_view . '_MODIFIED_DATE_DESC', + 'size' => 22, + 'readonly' => "true", + 'format' => '%Y-%m-%d %H:%M:%S', + 'filter' => 'user_utc' + ]; + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Date Modified Field. Type: Calendar (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // if modified_by is not set + if (!$this->fieldnames->isString($nameSingleCode . '.modified_by')) + { + $attributes = [ + 'name' => 'modified_by', + 'type' => 'user', + 'label' => $lang_view . '_MODIFIED_BY_LABEL', + 'description' => $lang_view . '_MODIFIED_BY_DESC', + 'class' => 'readonly', + 'readonly' => 'true', + 'filter' => 'unset' + ]; + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " User Modified Field. Type: User (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // check if view has access + if ($this->accessswitch->exists($nameSingleCode) + && !$this->fieldnames->isString($nameSingleCode . '.access')) + { + $attributes = [ + 'name' => 'access', + 'type' => 'accesslevel', + 'label' => 'JFIELD_ACCESS_LABEL', + 'description' => 'JFIELD_ACCESS_DESC', + 'default' => 1, + 'required' => "false" + ]; + $attributes = array_merge($attributes, $read_only_xml); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Access Field. Type: Accesslevel (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // if ordering is not set + if (!$this->fieldnames->isString($nameSingleCode . '.ordering')) + { + $attributes = [ + 'name' => 'ordering', + 'type' => 'number', + 'class' => 'inputbox validate-ordering', + 'label' => $lang_view . '_ORDERING_LABEL', + 'description' => '', + 'default' => 0, + 'size' => 6, + 'required' => "false" + ]; + $attributes = array_merge($attributes, $read_only_xml); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Ordering Field. Type: Numbers (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // if version is not set + if (!$this->fieldnames->isString($nameSingleCode . '.version')) + { + $attributes = [ + 'name' => 'version', + 'type' => 'text', + 'class' => 'readonly', + 'label' => $lang_view . '_VERSION_LABEL', + 'description' => $lang_view . '_VERSION_DESC', + 'size' => 6, + 'readonly' => "true", + 'filter' => 'unset' + ]; + $this->xml->comment( + $field_set_xml, + Line::_(__Line__, __Class__) . " Version Field. Type: Text (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + } + // check if metadata is added to this view + if ($this->metadata->isString($nameSingleCode)) + { + // metakey + if (!$this->fieldnames->isString($nameSingleCode . '.metakey')) + { + $attributes = [ + 'name' => 'metakey', + 'type' => 'textarea', + 'label' => 'JFIELD_META_KEYWORDS_LABEL', + 'description' => 'JFIELD_META_KEYWORDS_DESC', + 'rows' => 3, + 'cols' => 30 + ]; + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Metakey Field. Type: Textarea (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes( + $field_xml, $attributes + ); + // count the static field created + $this->counter->field++; + } + // metadesc + if (!$this->fieldnames->isString($nameSingleCode . '.metadesc')) + { + $attributes['name'] = 'metadesc'; + $attributes['label'] = 'JFIELD_META_DESCRIPTION_LABEL'; + $attributes['description'] = 'JFIELD_META_DESCRIPTION_DESC'; + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Metadesc Field. Type: Textarea (joomla)" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes( + $field_xml, $attributes + ); + // count the static field created + $this->counter->field++; + } + } + // fix the permissions field "title" issue gh-629 + // check if the title is not already set + if (!$this->fieldnames->isString($nameSingleCode . '.title') + && $this->permission->check($view, $nameSingleCode)) + { + // set the field/tab name + $field_name = "title"; + $tab_name = "publishing"; + + $attributes = [ + 'name' => $field_name, + 'type' => 'hidden', + 'default' => $component . ' ' . $nameSingleCode + ]; + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Was added due to Permissions JS needing a Title field" + ); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " Let us know at gh-629 should this change" + ); + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) + . " https://github.com/vdm-io/Joomla-Component-Builder/issues/629#issuecomment-750117235" + ); + $field_xml = $field_set_xml->addChild('field'); + $this->xml->attributes($field_xml, $attributes); + // count the static field created + $this->counter->field++; + // setup needed field values for layout + $field_array = []; + $field_array['order_edit'] = 0; + $field_array['tab'] = 15; + $field_array['alignment'] = 1; + // make sure it gets added to view + $this->layout->set( + $nameSingleCode, $tab_name, $field_name, $field_array + ); + } + // load the dynamic fields now + if (count((array) $dynamic_fields_xml)) + { + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) . " Dynamic Fields." + ); + foreach ($dynamic_fields_xml as $dynamicfield) + { + $this->xml->append($field_set_xml, $dynamicfield); + } + } + // check if metadata is added to this view + if ($this->metadata->isString($nameSingleCode)) + { + if (!$this->fieldnames->isString($nameSingleCode . '.robots') + || !$this->fieldnames->isString($nameSingleCode . '.author') + || !$this->fieldnames->isString($nameSingleCode . '.rights')) + { + $this->xml->comment( + $field_set_xml, Line::_(__Line__, __Class__) . " Metadata Fields" + ); + $fields_xml = $field_set_xml->addChild('fields'); + $fields_xml->addAttribute('name', 'metadata'); + $fields_xml->addAttribute( + 'label', 'JGLOBAL_FIELDSET_METADATA_OPTIONS' + ); + $fields_field_set_xml = $fields_xml->addChild('fieldset'); + $fields_field_set_xml->addAttribute('name', 'vdmmetadata'); + $fields_field_set_xml->addAttribute( + 'label', 'JGLOBAL_FIELDSET_METADATA_OPTIONS' + ); + // robots + if (!$this->fieldnames->isString($nameSingleCode . '.robots')) + { + $this->xml->comment( + $fields_field_set_xml, Line::_(__Line__, __Class__) + . " Robots Field. Type: List (joomla)" + ); + $robots = $fields_field_set_xml->addChild('field'); + $attributes = [ + 'name' => 'robots', + 'type' => 'list', + 'label' => 'JFIELD_METADATA_ROBOTS_LABEL', + 'description' => 'JFIELD_METADATA_ROBOTS_DESC' + ]; + $this->xml->attributes( + $robots, $attributes + ); + // count the static field created + $this->counter->field++; + $options = [ + 'JGLOBAL_USE_GLOBAL' => '', + 'JGLOBAL_INDEX_FOLLOW' => 'index, follow', + 'JGLOBAL_NOINDEX_FOLLOW' => 'noindex, follow', + 'JGLOBAL_INDEX_NOFOLLOW' => 'index, nofollow', + 'JGLOBAL_NOINDEX_NOFOLLOW' => 'noindex, nofollow', + ]; + foreach ($options as $text => $value) + { + $option = $robots->addChild('option'); + $option->addAttribute('value', $value); + $option[] = $text; + } + } + // author + if (!$this->fieldnames->isString($nameSingleCode . '.author')) + { + $this->xml->comment( + $fields_field_set_xml, Line::_(__Line__, __Class__) + . " Author Field. Type: Text (joomla)" + ); + $author = $fields_field_set_xml->addChild('field'); + $attributes = [ + 'name' => 'author', + 'type' => 'text', + 'label' => 'JAUTHOR', + 'description' => 'JFIELD_METADATA_AUTHOR_DESC', + 'size' => 20 + ]; + $this->xml->attributes( + $author, $attributes + ); + // count the static field created + $this->counter->field++; + } + // rights + if (!$this->fieldnames->isString($nameSingleCode . '.rights')) + { + $this->xml->comment( + $fields_field_set_xml, Line::_(__Line__, __Class__) + . " Rights Field. Type: Textarea (joomla)" + ); + $rights = $fields_field_set_xml->addChild('field'); + $attributes = [ + 'name' => 'rights', + 'type' => 'textarea', + 'label' => 'JFIELD_META_RIGHTS_LABEL', + 'description' => 'JFIELD_META_RIGHTS_DESC', + 'required' => 'false', + 'filter' => 'string', + 'cols' => 30, + 'rows' => 2 + ]; + $this->xml->attributes( + $rights, $attributes + ); + // count the static field created + $this->counter->field++; + } + } + } + + // return the set + return $this->xml->pretty($main_xml, 'fieldset'); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Layout.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Layout.php new file mode 100644 index 000000000..77047ed28 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Layout.php @@ -0,0 +1,218 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OrderZero; +use VDM\Joomla\Componentbuilder\Compiler\Builder\TabCounter; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Layout as BuilderLayout; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MovedPublishingFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\NewPublishingFields; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Layout Creator Class + * + * @since 3.2.0 + */ +final class Layout +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The OrderZero Class. + * + * @var OrderZero + * @since 3.2.0 + */ + protected OrderZero $orderzero; + + /** + * The TabCounter Class. + * + * @var TabCounter + * @since 3.2.0 + */ + protected TabCounter $tabcounter; + + /** + * The Builder Layout Class. + * + * @var BuilderLayout + * @since 3.2.0 + */ + protected BuilderLayout $layout; + + /** + * The MovedPublishingFields Class. + * + * @var MovedPublishingFields + * @since 3.2.0 + */ + protected MovedPublishingFields $movedpublishingfields; + + /** + * The NewPublishingFields Class. + * + * @var NewPublishingFields + * @since 3.2.0 + */ + protected NewPublishingFields $newpublishingfields; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param OrderZero $orderzero The OrderZero Class. + * @param TabCounter $tabcounter The TabCounter Class. + * @param BuilderLayout $layout The Layout Class. + * @param MovedPublishingFields $movedpublishingfields The MovedPublishingFields Class. + * @param NewPublishingFields $newpublishingfields The NewPublishingFields Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, OrderZero $orderzero, + TabCounter $tabcounter, BuilderLayout $layout, + MovedPublishingFields $movedpublishingfields, + NewPublishingFields $newpublishingfields) + { + $this->config = $config; + $this->orderzero = $orderzero; + $this->tabcounter = $tabcounter; + $this->layout = $layout; + $this->movedpublishingfields = $movedpublishingfields; + $this->newpublishingfields = $newpublishingfields; + } + + /** + * set the layout builders + * + * @param string $nameSingleCode The single edit view code name + * @param string $tabName The tab code name + * @param string $name The field code name + * @param array $field The field details + * + * @return void + * @since 3.2.0 + */ + public function set(string $nameSingleCode, string $tabName, string $name, array &$field): void + { + // first fix the zero order + // to insure it lands before all the other fields + // as zero is expected to behave + if ($field['order_edit'] == 0) + { + // get the value + $zero_counter = $this->orderzero->get($nameSingleCode . '.' . $field['tab'], -999); + if ($zero_counter != -999) + { + $zero_counter++; + } + $field['order_edit'] = $zero_counter; + // set the value + $this->orderzero->set($nameSingleCode . '.' . $field['tab'], $zero_counter); + } + // get the default fields + $default_fields = $this->config->default_fields; + // now build the layout + if (StringHelper::check($tabName) + && strtolower($tabName) != 'publishing') + { + $this->tabcounter->set($nameSingleCode . '.' . $field['tab'], $tabName); + if ($this->layout->exists($nameSingleCode . '.' . $tabName . '.' + . $field['alignment'] . '.' . $field['order_edit'])) + { + $size = $this->layout->count($nameSingleCode . '.' . $tabName . '.' + . $field['alignment']) + 1; + while ($this->layout->exists($nameSingleCode . '.' . $tabName . '.' + . $field['alignment'] . '.' . $size)) + { + $size++; + } + $this->layout->set($nameSingleCode . '.' . $tabName . '.' + . $field['alignment'] . '.' . $size, $name); + } + else + { + $this->layout->set($nameSingleCode . '.' + . $tabName . '.' . $field['alignment'] . '.' . $field['order_edit'], $name); + } + // check if default fields were overwritten + if (in_array($name, $default_fields)) + { + // just to eliminate + $this->movedpublishingfields->set($nameSingleCode . '.' . $name, true); + } + } + elseif ($tabName === 'publishing' || $tabName === 'Publishing') + { + if (!in_array($name, $default_fields)) + { + if ($this->newpublishingfields->exists($nameSingleCode . '.' . + $field['alignment'] . '.' . $field['order_edit'])) + { + $size = $this->newpublishingfields->count($nameSingleCode . '.' . + $field['alignment']) + 1; + while ($this->newpublishingfields->exists($nameSingleCode . '.' . + $field['alignment'] . '.' . $size)) + { + $size++; + } + $this->newpublishingfields->set($nameSingleCode . '.' . + $field['alignment'] . '.' . $size, $name); + } + else + { + $this->newpublishingfields->set($nameSingleCode . '.' . + $field['alignment'] . '.' . $field['order_edit'], $name); + } + } + } + else + { + $this->tabcounter->set($nameSingleCode . '.1', 'Details'); + if ($this->layout->exists($nameSingleCode . '.Details.' + . $field['alignment'] . '.' . $field['order_edit'])) + { + $size = $this->layout->count($nameSingleCode . '.Details.' + . $field['alignment']) + 1; + while ($this->layout->exists($nameSingleCode . '.Details.' + . $field['alignment'] . '.' . $size)) + { + $size++; + } + $this->layout->set($nameSingleCode . '.Details.' + . $field['alignment'] . '.' . $size, $name); + } + else + { + $this->layout->set($nameSingleCode . '.Details.' . $field['alignment'] . '.' + . $field['order_edit'], $name); + } + // check if default fields were overwritten + if (in_array($name, $default_fields)) + { + // just to eliminate + $this->movedpublishingfields->set($nameSingleCode . '.' . $name, true); + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Permission.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Permission.php new file mode 100644 index 000000000..1b00a6c76 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/Permission.php @@ -0,0 +1,691 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionCore; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionViews; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionAction; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionComponent; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionGlobalAction; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionDashboard; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Permission Creator Class + * + * @since 3.2.0 + */ +final class Permission +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The PermissionCore Class. + * + * @var PermissionCore + * @since 3.2.0 + */ + protected PermissionCore $permissioncore; + + /** + * The PermissionViews Class. + * + * @var PermissionViews + * @since 3.2.0 + */ + protected PermissionViews $permissionviews; + + /** + * The PermissionAction Class. + * + * @var PermissionAction + * @since 3.2.0 + */ + protected PermissionAction $permissionaction; + + /** + * The PermissionComponent Class. + * + * @var PermissionComponent + * @since 3.2.0 + */ + protected PermissionComponent $permissioncomponent; + + /** + * The PermissionGlobalAction Class. + * + * @var PermissionGlobalAction + * @since 3.2.0 + */ + protected PermissionGlobalAction $permissionglobalaction; + + /** + * The PermissionDashboard Class. + * + * @var PermissionDashboard + * @since 3.2.0 + */ + protected PermissionDashboard $permissiondashboard; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The permissions + * + * @var array + * @since 3.2.0 + */ + protected array $permissions; + + /** + * The Name List View + * + * @var string + * @since 3.2.0 + */ + protected string $nameList; + + /** + * The Lowercase Name List View + * + * @var string + * @since 3.2.0 + */ + protected string $nameListLower; + + /** + * The Lowercase Name Single View + * + * @var string + * @since 3.2.0 + */ + protected string $nameSingleLower; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param PermissionCore $permissioncore The PermissionCore Class. + * @param PermissionViews $permissionviews The PermissionViews Class. + * @param PermissionAction $permissionaction The PermissionAction Class. + * @param PermissionComponent $permissioncomponent The PermissionComponent Class. + * @param PermissionGlobalAction $permissionglobalaction The PermissionGlobalAction Class. + * @param PermissionDashboard $permissiondashboard The PermissionDashboard Class. + * @param Counter $counter The Counter Class. + * @param Language $language The Language Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, PermissionCore $permissioncore, PermissionViews $permissionviews, + PermissionAction $permissionaction, PermissionComponent $permissioncomponent, PermissionGlobalAction $permissionglobalaction, + PermissionDashboard $permissiondashboard, Counter $counter, Language $language) + { + $this->config = $config; + $this->permissioncore = $permissioncore; + $this->permissionviews = $permissionviews; + $this->permissionaction = $permissionaction; + $this->permissioncomponent = $permissioncomponent; + $this->permissionglobalaction = $permissionglobalaction; + $this->permissiondashboard = $permissiondashboard; + $this->counter = $counter; + $this->language = $language; + } + + /** + * Get the permission action + * + * @param string $nameView View Single Code Name + * @param string $action The Permission Action + * + * @return string|null The action name if set + * @since 3.2.0 + */ + public function getAction(string $nameView, string $action): ?string + { + if (($set_action = $this->getCore($nameView, $action)) !== null && + $this->permissionaction->exists("{$set_action}|{$nameView}")) + { + return $set_action; + } + + return $action; + } + + /** + * Get the global permission action + * + * @param string $nameView View Single Code Name + * @param string $action The Permission Action + * + * @return string The action name if set + * @since 3.2.0 + */ + public function getGlobal(string $nameView, string $action): string + { + if (($set_action = $this->getCore($nameView, $action)) !== null && + $this->permissionglobalaction->exists("{$set_action}|{$nameView}")) + { + return $set_action; + } + + return $action; + } + + /** + * Check if the permission action exist + * + * @param string $nameView View Single Code Name + * @param string $action The Permission Action + * + * @return bool true if it exist + * @since 3.2.0 + */ + public function actionExist(string $nameView, string $action): bool + { + if (($set_action = $this->getCore($nameView, $action)) !== null && + $this->permissionaction->exists("{$set_action}|{$nameView}")) + { + return true; + } + + return false; + } + + /** + * Check if the global permission action exist + * + * @param string $nameView View Single Code Name + * @param string $action The Permission Action + * + * @return bool true if it exist + * @since 3.2.0 + */ + public function globalExist(string $nameView, string $action): bool + { + if (($set_action = $this->getCore($nameView, $action)) !== null && + $this->permissionglobalaction->exists("{$set_action}|{$nameView}")) + { + return true; + } + + return false; + } + + /** + * Set the permissions + * + * @param array $view View details + * @param string $nameView View Single Code Name + * @param string $nameViews View List Code Name + * @param array $menuControllers Menu Controllers + * @param string $type Type of permissions area + * + * @return void + * @since 3.2.0 + */ + public function set(array &$view, string $nameView, string $nameViews, array $menuControllers, string $type = 'admin'): void + { + if ($this->initialise($view, $type)) + { + $this->build($view, $nameView, $nameViews, $menuControllers, $type); + } + } + + /** + * Build of permissions + * + * @param array $view View details + * @param string $nameView View Single Code Name + * @param string $nameViews View List Code Name + * @param array $menuControllers Menu Controllers + * @param string $type Type of permissions area + * + * @return void + * @since 3.2.0 + */ + private function build(array &$view, string $nameView, string $nameViews, + array $menuControllers, string $type = 'admin'): void + { + // load the permissions + foreach ($this->permissions as &$permission) + { + // set action name + $arr = explode('.', trim((string) $permission['action'])); + if ($arr[0] != 'core' || $arr[0] === 'view') + { + array_shift($arr); + $action_main = implode('.', $arr); + $action = $nameView . '.' . $action_main; + } + else + { + if ($arr[0] === 'core') + { + // core is already set in global access + $permission['implementation'] = 1; + } + + $action = $permission['action']; + } + + // build action name + $action_name_builder = explode('.', trim((string) $permission['action'])); + array_shift($action_name_builder); + $name_builder = trim(implode('___', $action_name_builder)); + $custom_name = trim(implode(' ', $action_name_builder)); + + // check if we have access set for this view (if not skip) + if ($name_builder === 'edit___access' && $type === 'admin' + && (!isset($view['access']) || $view['access'] != 1)) + { + continue; + } + + // set the names + $this->setNames($view['settings'], $custom_name, $type); + + // set title (only if not set already) + if (!isset($permission['title']) || !StringHelper::check($permission['title'])) + { + $permission['title'] = $this->getTitle($name_builder, $custom_name); + } + + // set description (only if not set already) + if (!isset($permission['description']) || !StringHelper::check($permission['description'])) + { + $permission['description'] = $this->getDescription($name_builder, $custom_name); + } + + // if core is not used update all core strings + $core_check = explode('.', (string) $action); + $core_check[0] = 'core'; + $core_target = implode('.', $core_check); + + $this->permissioncore->set("{$nameView}|{$core_target}", $action); + + // set array sort name + $sort_key = StringHelper::safe($permission['title']); + + // set title + $title = $this->config->lang_prefix . '_' . StringHelper::safe($permission['title'], 'U'); + + // load the actions + if ($permission['implementation'] == 1) + { + // only related to view + $this->permissionviews->set("{$nameView}|{$action}", [ + 'name' => $action, + 'title' => $title, + 'description' => "{$title}_DESC" + ]); + + // load permission to action + $this->permissionaction->set("{$action}|{$nameView}", $nameView); + } + elseif ($permission['implementation'] == 2) + { + // relation to whole component + $this->permissioncomponent->set($sort_key, [ + 'name' => $action, + 'title' => $title, + 'description' => "{$title}_DESC" + ]); + + // the size needs increase + $this->counter->accessSize++; + + // build permission switch + $this->permissionglobalaction->set("{$action}|{$nameView}", $nameView); + + // add menu control view that has menus options + $this->setDashboard($nameView, $nameViews, $menuControllers, $action, $core_target); + } + elseif ($permission['implementation'] == 3) + { + // only related to view + $this->permissionviews->set("{$nameView}|{$action}", [ + 'name' => $action, + 'title' => $title, + 'description' => "{$title}_DESC" + ]); + + // load permission to action + $this->permissionaction->set("{$action}|{$nameView}", $nameView); + + // relation to whole component + $this->permissioncomponent->set($sort_key, [ + 'name' => $action, + 'title' => $title, + 'description' => "{$title}_DESC" + ]); + + // the size needs increase + $this->counter->accessSize++; + + // build permission switch + $this->permissionglobalaction->set("{$action}|{$nameView}", $nameView); + + // add menu control view that has menus options + $this->setDashboard($nameView, $nameViews, $menuControllers, $action, $core_target); + } + + // set to language file + $this->language->set( + 'bothadmin', $title, $permission['title'] + ); + + $this->language->set( + 'bothadmin', "{$title}_DESC", $permission['description'] + ); + } + + // update permissions + $view['settings']->permissions = $this->permissions; + } + + /** + * Set dashboard permissions + * + * @param string $nameView View Single Code Name + * @param string $nameViews View List Code Name + * @param array $menuControllers Menu Controllers + * @param string $action The targeted action + * @param string $coreTarget The core target + * + * @return void + * @since 3.2.0 + */ + private function setDashboard(string $nameView, string $nameViews, + array $menuControllers, string $action, string $coreTarget): void + { + // dashboard icon checker + if ($coreTarget === 'core.access') + { + $this->permissiondashboard->set( + "{$nameViews}.access", $action + ); + $this->permissiondashboard->set( + "{$nameView}.access", $action + ); + } + + if ($coreTarget === 'core.create') + { + $this->permissiondashboard->set( + "{$nameView}.create", $action + ); + } + + // add menu control view that has menus options + foreach ($menuControllers as $menu_controller) + { + if ($coreTarget === 'core.' . $menu_controller) + { + if ($menu_controller === 'dashboard_add') + { + $this->permissiondashboard->set( + "{$nameView}.{$menu_controller}", $action + ); + } + else + { + $this->permissiondashboard->set( + "{$nameViews}.{$menu_controller}", $action + ); + } + } + } + } + + /** + * Initialise build of permissions + * + * @param array $view View details + * @param string $type Type of permissions area + * + * @return bool true if build can continue + * @since 3.2.0 + */ + private function initialise(array $view, string $type): bool + { + if (isset($view['settings']) && (isset($view['settings']->permissions) + && ArrayHelper::check($view['settings']->permissions) + || (isset($view['port']) && $view['port']) + || (isset($view['history']) && $view['history']))) + { + if (isset($view['settings']->permissions) + && ArrayHelper::check($view['settings']->permissions)) + { + $this->permissions = $view['settings']->permissions; + } + else + { + $this->permissions = []; + } + + $this->initPort($view['port'] ?? 0); + $this->initHistory($view['history'] ?? 0); + $this->initBatch($type); + + return true; + } + + return false; + } + + /** + * Initialise build of import and export permissions + * + * @param int $port The port adding switch + * + * @return void + * @since 3.2.0 + */ + private function initPort(int $port): void + { + if ($port) + { + // export + $add = []; + $add['action'] = 'view.export'; + $add['implementation'] = '2'; + array_push($this->permissions, $add); + + // import + $add = []; + $add['action'] = 'view.import'; + $add['implementation'] = '2'; + array_push($this->permissions, $add); + } + } + + /** + * Initialise build of history permissions + * + * @param int $history The history adding switch + * + * @return void + * @since 3.2.0 + */ + private function initHistory(int $history): void + { + if ($history) + { + // export + $add = []; + $add['action'] = 'view.version'; + $add['implementation'] = '3'; + array_push($this->permissions, $add); + } + } + + /** + * Initialise build of batch permissions + * + * @param string $type Type of permissions area + * + * @return void + * @since 3.2.0 + */ + private function initBatch(string $type): void + { + // add batch permissions + if ($type === 'admin') + { + // set batch control + $add = []; + $add['action'] = 'view.batch'; + $add['implementation'] = '2'; + array_push($this->permissions, $add); + } + } + + /** + * Initialise build of names used in permissions + * + * @param object $settings The view settings object + * @param string $customName The custom name + * @param string $type Type of permissions area + * + * @return void + * @since 3.2.0 + */ + private function setNames(object $settings, string $customName, string $type): void + { + // build the names + if ($type === 'admin') + { + $this->nameList = StringHelper::safe( + $settings->name_list, 'W' + ); + $this->nameListLower = StringHelper::safe( + $customName . ' ' . $settings->name_list, 'w' + ); + $this->nameSingleLower = StringHelper::safe( + $settings->name_single, 'w' + ); + } + elseif ($type === 'customAdmin') + { + $this->nameList = StringHelper::safe( + $settings->name, 'W' + ); + $this->nameListLower = $settings->name; + $this->nameSingleLower = $settings->name; + } + } + + /** + * Get the dynamic title + * + * @param string $nameBuilder The target builder name + * @param string $customName The dynamic custom name + * + * @return string The title + * @since 3.2.0 + */ + private function getTitle(string $nameBuilder, string $customName): string + { + $actionTitles = [ + 'edit' => 'Edit', + 'edit___own' => 'Edit Own', + 'edit___access' => 'Edit Access', + 'edit___state' => 'Edit State', + 'edit___created_by' => 'Edit Created By', + 'edit___created' => 'Edit Created Date', + 'create' => 'Create', + 'delete' => 'Delete', + 'access' => 'Access', + 'export' => 'Export', + 'import' => 'Import', + 'version' => 'Edit Version', + 'batch' => 'Batch Use', + ]; + + $titleSuffix = $actionTitles[$nameBuilder] ?? StringHelper::safe($customName, 'W'); + + return $this->nameList . ' ' . $titleSuffix; + } + + /** + * Get the dynamic description + * + * @param string $nameBuilder The target builder name + * @param string $customName The dynamic custom name + * + * @return string The description + * @since 3.2.0 + */ + private function getDescription(string $nameBuilder, string $customName): string + { + $actionDescriptions = [ + 'edit' => 'edit the ' . $this->nameSingleLower, + 'edit___own' => 'edit ' . $this->nameListLower . ' created by them', + 'edit___access' => 'change the access of the ' . $this->nameListLower, + 'edit___state' => 'update the state of the ' . $this->nameSingleLower, + 'edit___created_by' => 'update the created by of the ' . $this->nameListLower, + 'edit___created' => 'update the created date of the ' . $this->nameListLower, + 'create' => 'create ' . $this->nameListLower, + 'delete' => 'delete ' . $this->nameListLower, + 'access' => 'access ' . $this->nameListLower, + 'export' => 'export ' . $this->nameListLower, + 'import' => 'import ' . $this->nameListLower, + 'version' => 'edit versions of ' . $this->nameListLower, + 'batch' => 'use batch copy/update method of ' . $this->nameListLower + ]; + + $description = $actionDescriptions[$nameBuilder] ?? StringHelper::safe($customName, 'w') . ' of ' . $this->nameSingleLower; + + return ' Allows the users in this group to ' . $description; + } + + /** + * Get the core permission action + * + * @param string $nameView View Single Code Name + * @param string $action The Permission Action + * + * @return string|null The action name if set + * @since 3.2.0 + */ + private function getCore(string $nameView, string $action): ?string + { + return $this->permissioncore->get("{$nameView}|{$action}"); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/SiteFieldData.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/SiteFieldData.php new file mode 100644 index 000000000..82d1659f8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/SiteFieldData.php @@ -0,0 +1,154 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Creator; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFieldData as SiteField; + + +/** + * Site Field Data Creator Class + * + * @since 3.2.0 + */ +final class SiteFieldData +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The SiteFields Class. + * + * @var SiteFields + * @since 3.2.0 + */ + protected SiteFields $sitefields; + + /** + * The SiteFieldData Class. + * + * @var SiteField + * @since 3.2.0 + */ + protected SiteField $sitefield; + + /** + * The decoding options + * + * @var array + * @since 3.2.0 + */ + protected array $decode = [ + 'json', + 'base64', + 'basic_encryption', + 'whmcs_encryption', + 'medium_encryption', + 'expert_mode' + ]; + + /** + * The text areas + * + * @var array + * @since 3.2.0 + */ + protected array $textareas = [ + 'textarea', + 'editor' + ]; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param SiteFields $sitefields The SiteFields Class. + * @param SiteField $sitefield The SiteFieldData Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, SiteFields $sitefields, + SiteField $sitefield) + { + $this->config = $config; + $this->sitefields = $sitefields; + $this->sitefield = $sitefield; + } + + /** + * set the site field data needed + * + * @param string $view The single edit view code name + * @param string $field The field name + * @param string $set The decoding set this field belongs to + * @param string $type The field type + * + * @return void + * + */ + public function set(string $view, string $field, string $set, string $type): void + { + if (($site_fields = $this->sitefields->get($view . '.' . $field)) !== null) + { + foreach ($site_fields as $codeString => $site_field) + { + // get the code array + $codeArray = explode('___', (string) $codeString); + // set the code + $code = trim($codeArray[0]); + // set the path + $path = $site_field['site'] . '.' . $code . '.' . $site_field['as'] . '.' . $site_field['key']; + + // set the decoding methods + if (in_array($set, $this->decode)) + { + if ($this->sitefield->exists('decode.' . $path . '.decode')) + { + if (!$this->sitefield->inArray($set, 'decode.' . $path . '.decode')) + { + $this->sitefield->add('decode.' . $path . '.decode', $set, true); + } + } + else + { + $this->sitefield->set('decode.' . $path, [ + 'decode' => [$set], + 'type' => $type, + 'admin_view' => $view + ]); + } + } + + // set the uikit checker + if ((2 == $this->config->uikit || 1 == $this->config->uikit) + && in_array($type, $this->textareas)) + { + $this->sitefield->add('uikit.' . $path, (array) $site_field, true); + } + + // set the text area checker + if (in_array($type, $this->textareas)) + { + $this->sitefield->add('textareas.' . $path, (array) $site_field, true); + } + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Creator/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php new file mode 100644 index 000000000..54510fd05 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php @@ -0,0 +1,647 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor as Power; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\External; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\CustomcodeInterface; + + +/** + * Compiler Custom Code + * + * @since 3.2.0 + */ +class Customcode implements CustomcodeInterface +{ + /** + * The function name memory ids + * + * @var array + * @since 3.2.0 + **/ + public array $functionNameMemory = []; + + /** + * The active custom code + * + * @var array + * @since 3.2.0 + */ + public $active = []; + + /** + * The custom code memory + * + * @var array + * @since 3.2.0 + */ + public $memory = []; + + /** + * The placeholders for custom code keys + * + * @var array + */ + protected $keys + = array( + '[' => '[', + ']' => ']', + ',' => ',', + '+' => '+', + '=' => '=' + ); + + /** + * The custom code to be added + * + * @var array + * @since 3.2.0 + */ + protected $data = []; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Compiler Language Extractor + * + * @var Extractor + * @since 3.2.0 + **/ + protected Extractor $extractor; + + /** + * Super Power Extractor + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Custom Code External + * + * @var External + * @since 3.2.0 + **/ + protected External $external; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected $db; + + /** + * Constructor. + * + * @param Config|null $config The compiler config object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Extractor|null $extractor The compiler language extractor object. + * @param Power|null $power The compiler power extractor object. + * @param External|null $external The compiler external custom code object. + * @param \JDatabaseDriver $db The Database Driver object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Placeholder $placeholder = null, + ?Extractor $extractor = null, ?Power $power = null, ?External $external = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->extractor = $extractor ?: Compiler::_('Language.Extractor'); + $this->power = $power ?: Compiler::_('Power.Extractor'); + $this->external = $external ?: Compiler::_('Customcode.External'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Update **ALL** dynamic values in a strings here + * + * @param string $string The content to check + * @param int $debug The switch to debug the update + * We can now at any time debug the + * dynamic build values if it gets broken + * + * @return string + * @since 3.2.0 + */ + public function update(string $string, int $debug = 0): string + { + if (StringHelper::check($string)) + { + $string = $this->extractor->engine( + $this->set( + $this->external->set($string, $debug), $debug + ) + ); + + // extract any found super powers + $this->power->search($string); + } + // if debug + if ($debug) + { + jexit(); + } + + return $string; + } + + /** + * Set the custom code data & can load it in to string + * + * @param string $string The content to check + * @param int $debug The switch to debug the update + * @param int|null $not The not switch + * + * @return string + * @since 3.2.0 + */ + public function set(string $string, int $debug = 0, ?int $not = null): string + { + // insure the code is loaded + $loaded = false; + // check if content has custom code place holder + if (strpos($string, '[CUSTO' . 'MCODE=') !== false) + { + // if debug + if ($debug) + { + echo 'Custom Code String:'; + var_dump($string); + } + // the ids found in this content + $bucket = []; + $found = GetHelper::allBetween( + $string, '[CUSTO' . 'MCODE=', ']' + ); + if (ArrayHelper::check($found)) + { + foreach ($found as $key) + { + // if debug + if ($debug) + { + echo '$key before update:'; + var_dump($key); + } + // check if we have args + if (is_numeric($key)) + { + $id = (int) $key; + } + elseif (StringHelper::check($key) + && strpos((string) $key, '+') === false) + { + $getFuncName = trim((string) $key); + if (!isset($this->functionNameMemory[$getFuncName])) + { + if (!$found_local = GetHelper::var( + 'custom_code', $getFuncName, 'function_name', + 'id' + )) + { + continue; + } + $this->functionNameMemory[$getFuncName] + = $found_local; + } + $id = (int) $this->functionNameMemory[$getFuncName]; + } + elseif (StringHelper::check($key) + && strpos( + (string) $key, '+' + ) !== false) + { + $array = explode('+', (string) $key); + // set ID + if (is_numeric($array[0])) + { + $id = (int) $array[0]; + } + elseif (StringHelper::check($array[0])) + { + $getFuncName = trim($array[0]); + if (!isset($this->functionNameMemory[$getFuncName])) + { + if (!$found_local + = GetHelper::var( + 'custom_code', $getFuncName, + 'function_name', 'id' + )) + { + continue; + } + $this->functionNameMemory[$getFuncName] + = $found_local; + } + $id = (int) $this->functionNameMemory[$getFuncName]; + } + else + { + continue; + } + // load args for this ID + if (isset($array[1])) + { + if (!isset($this->data[$id]['args'])) + { + $this->data[$id]['args'] = []; + } + // only load if not already loaded + if (!isset($this->data[$id]['args'][$key])) + { + if (strpos($array[1], ',') !== false) + { + // update the function values with the custom code key placeholders (this allow the use of [] + and , in the values) + $this->data[$id]['args'][$key] = array_map( + fn($_key) => $this->placeholder->update( + $_key, + $this->keys + ), (array) explode(',', $array[1]) + ); + } + elseif (StringHelper::check( + $array[1] + )) + { + $this->data[$id]['args'][$key] = []; + // update the function values with the custom code key placeholders (this allow the use of [] + and , in the values) + $this->data[$id]['args'][$key][] + = $this->placeholder->update( + $array[1], + $this->keys + ); + } + } + } + } + else + { + continue; + } + // make sure to remove the not if set + if ($not && is_numeric($not) && $not > 0 && $not == $id) + { + continue; + } + $bucket[$id] = $id; + } + } + // if debug + if ($debug) + { + echo 'Bucket:'; + var_dump($bucket); + } + // check if any custom code placeholders where found + if (ArrayHelper::check($bucket)) + { + $_tmpLang = $this->config->lang_target; + // insure we add the langs to both site and admin + $this->config->lang_target = 'both'; + // now load the code to memory + $loaded = $this->get($bucket, false, $debug); + // revert lang to current setting + $this->config->lang_target = $_tmpLang; + } + // if debug + if ($debug) + { + echo 'Loaded:'; + var_dump($loaded); + } + // when the custom code is loaded + if ($loaded === true) + { + $string = $this->insert($bucket, $string, $debug); + } + // if debug + if ($debug) + { + echo 'Custom Code String After Update:'; + var_dump($string); + } + } + + return $string; + } + + /** + * Load the custom code from the system + * + * @param array|null $ids The custom code ides if known + * @param bool $setLang The set lang switch + * @param int $debug The switch to debug the update + * + * @return bool + * @since 3.2.0 + */ + public function get(?array $ids = null, bool $setLang = true, $debug = 0): bool + { + // should the result be stored in memory + $loadInMemory = false; + // Create a new query object. + $query = $this->db->getQuery(true); + $query->from( + $this->db->quoteName('#__componentbuilder_custom_code', 'a') + ); + if (ArrayHelper::check($ids)) + { + if (($idArray = $this->check($ids)) !== false) + { + $query->select( + $this->db->quoteName( + array('a.id', 'a.code', 'a.comment_type') + ) + ); + $query->where( + $this->db->quoteName('a.id') . ' IN (' . implode( + ',', $idArray + ) . ')' + ); + $query->where( + $this->db->quoteName('a.target') . ' = 2' + ); // <--- to load the correct target + $loadInMemory = true; + } + else + { + // all values are already in memory continue + return true; + } + } + else + { + $query->select( + $this->db->quoteName( + array('a.id', 'a.code', 'a.comment_type', 'a.component', + 'a.from_line', 'a.hashtarget', 'a.hashendtarget', + 'a.path', 'a.to_line', 'a.type') + ) + ); + $query->where( + $this->db->quoteName('a.component') . ' = ' + . (int) $this->config->component_id + ); + $query->where( + $this->db->quoteName('a.target') . ' = 1' + ); // <--- to load the correct target + $query->order( + $this->db->quoteName('a.from_line') . ' ASC' + ); // <--- insure we always add code from top of file + // reset custom code + $this->active = []; + } + $query->where($this->db->quoteName('a.published') . ' >= 1'); + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + $bucket = $this->db->loadAssocList('id'); + // open the code + foreach ($bucket as $nr => &$customCode) + { + $customCode['code'] = base64_decode((string) $customCode['code']); + // always insure that the external code is loaded + $customCode['code'] = $this->external->set( + $customCode['code'] + ); + + // set the lang only if needed (we do the other later when we add it to the correct position) + if ($setLang) + { + $customCode['code'] = $this->extractor->engine( + $customCode['code'] + ); + } + // check for more custom code (since this is a custom code placeholder) + else + { + $customCode['code'] = $this->set( + $customCode['code'], $debug, $nr + ); + } + + // build the hash array + if (isset($customCode['hashtarget'])) + { + $customCode['hashtarget'] = explode( + "__", (string) $customCode['hashtarget'] + ); + // is this a replace code, set end has array + if ($customCode['type'] == 1 + && strpos((string) $customCode['hashendtarget'], '__') !== false) + { + $customCode['hashendtarget'] = explode( + "__", (string) $customCode['hashendtarget'] + ); + + // NOW see if this is an end of page target (TODO not sure if the string is always d41d8cd98f00b204e9800998ecf8427e) + // I know this fix is not air-tight, but it should work as the value of an empty line when md5'ed is ^^^^ + // Then if the line number is only >>>one<<< it is almost always end of the page. + // So I am using those two values to detect end of page replace ending, to avoid mismatching the ending target hash. + if ($customCode['hashendtarget'][0] == 1 + && 'd41d8cd98f00b204e9800998ecf8427e' === $customCode['hashendtarget'][1]) + { + // unset since this will force the replacement unto end of page. + unset($customCode['hashendtarget']); + } + } + } + } + + // load this code into memory if needed + if ($loadInMemory === true) + { + $this->memory = $this->memory + $bucket; + } + + // add to active set + $this->active = array_merge($this->active, $bucket); + + return true; + } + + return false; + } + + /** + * Insert the custom code into the string + * + * @param array|null $ids The custom code ides if known + * @param string $string The string to insert custom code into + * @param int $debug The switch to debug the update + * + * @return string on success + * @since 3.2.0 + */ + protected function insert(array $ids, string $string, int $debug = 0): string + { + $code = []; + // load the code + foreach ($ids as $id) + { + $this->buildPlaceholders( + $this->memory[$id], $code, $debug + ); + } + // if debug + if ($debug) + { + echo 'Place holders to Update String:'; + var_dump($code); + echo 'Custom Code String Before Update:'; + var_dump($string); + } + + // now update the string + return $this->placeholder->update($string, $code); + } + + /** + * Build custom code placeholders + * + * @param array $item The memory item + * @param array $code The custom code bucket + * @param int $debug The switch to debug the update + * + * @return void + * @since 3.2.0 + */ + protected function buildPlaceholders(array $item, array &$code, int $debug = 0) + { + // check if there is args for this code + if (isset($this->data[$item['id']]['args']) + && ArrayHelper::check( + $this->data[$item['id']]['args'] + )) + { + // since we have args we cant update this code via IDE (TODO) + $placeholder = $this->placeholder->keys(3, null); + // if debug + if ($debug) + { + echo 'Custom Code Placeholders:'; + var_dump($placeholder); + } + // we have args and so need to load each + foreach ( + $this->data[$item['id']]['args'] as $key => $args + ) + { + $this->placeholder->setType('arg', $args); + // if debug + if ($debug) + { + echo 'Custom Code Global Placeholders:'; + var_dump($this->placeholder->active); + } + $code['[CUSTOM' . 'CODE=' . $key . ']'] = $placeholder['start'] + . PHP_EOL . $this->placeholder->update_( + $item['code'] + ) . $placeholder['end']; + } + // always clear the args + $this->placeholder->clearType('arg'); + } + else + { + if (($keyPlaceholder = array_search( + $item['id'], $this->functionNameMemory + )) === false) + { + $keyPlaceholder = $item['id']; + } + // check what type of place holders we should load here + $placeholderType = (int) $item['comment_type'] . '2'; + if (stripos((string) $item['code'], Placefix::b() . 'view') !== false + || stripos((string) $item['code'], Placefix::b() . 'sview') !== false + || stripos((string) $item['code'], Placefix::b() . 'arg') !== false) + { + // if view is being set dynamicly then we can't update this code via IDE (TODO) + $placeholderType = 3; + } + // if now ars were found, clear it + $this->placeholder->clearType('arg'); + // load args for this code + $placeholder = $this->placeholder->keys( + $placeholderType, $item['id'] + ); + $code['[CUSTOM' . 'CODE=' . $keyPlaceholder . ']'] + = $placeholder['start'] . PHP_EOL + . $this->placeholder->update_( + $item['code'] + ) . $placeholder['end']; + } + } + + /** + * check if we already have these ids in local memory + * + * @param array $ids The custom code ids + * + * @return Mixed + * @since 3.2.0 + */ + protected function check(array $ids) + { + // reset custom code + $this->active = []; + + foreach ($ids as $pointer => $id) + { + if (isset($this->memory[$id])) + { + $this->active[] = $this->memory[$id]; + unset($ids[$pointer]); + } + } + + // check if any ids left to fetch + if (ArrayHelper::check($ids)) + { + return $ids; + } + + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php new file mode 100644 index 000000000..5e0b85de2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php @@ -0,0 +1,285 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Customcode; + + +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Hash; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\LockBase; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode\DispenserInterface; + + +/** + * Compiler Custom Code Dispenser + * + * @since 3.2.0 + */ +class Dispenser implements DispenserInterface +{ + /** + * Customcode Dispenser Hub + * + * @var array + * @since 3.2.0 + **/ + public array $hub; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + **/ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Customcode to Hash + * + * @var Hash + * @since 3.2.0 + **/ + protected Hash $hash; + + /** + * Compiler Customcode to LockBase + * + * @var LockBase + * @since 3.2.0 + **/ + protected LockBase $base64; + + /** + * Constructor. + * + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui object. + * @param Hash|null $hash The compiler customcode hash object. + * @param LockBase|null $base64 The compiler customcode lock base64 object. + * + * @since 3.2.0 + */ + public function __construct(?Placeholder $placeholder = null, ?Customcode $customcode = null, + ?Gui $gui = null, ?Hash $hash = null, ?LockBase $base64 = null) + { + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->hash = $hash ?: Compiler::_('Customcode.Hash'); + $this->base64 = $base64 ?: Compiler::_('Customcode.LockBase'); + } + + /** + * Set the script for the customcode dispenser + * + * @param string $script The script + * @param string $first The first key + * @param string|null $second The second key (if not set we use only first key) + * @param string|null $third The third key (if not set we use only first and second key) + * @param array $config The config options + * @param bool $base64 The switch to decode base64 the script + * default: true + * @param bool $dynamic The switch to dynamic update the script + * default: true + * @param bool $add The switch to add to exiting instead of replace + * default: false + * + * @return bool true on success + * @since 3.2.0 + */ + public function set(&$script, string $first, ?string $second = null, ?string $third = null, + array $config = [], bool $base64 = true, bool $dynamic = true, bool $add = false): bool + { + // only load if we have a string + if (!StringHelper::check($script)) + { + return false; + } + + // init all needed arrays + $this->initHub($first, $second, $third, $add); + + // prep the script string + if ($base64 && $dynamic) + { + $script = $this->customcode->update(base64_decode($script)); + } + elseif ($base64) + { + $script = base64_decode($script); + } + elseif ($dynamic) // this does not happen (just in-case) + { + $script = $this->customcode->update($script); + } + // check if we still have a string + if (StringHelper::check($script)) + { + // now load the placeholder snippet if needed + if ($base64 || $dynamic) + { + $script = $this->gui->set($script, $config); + } + + // add Dynamic HASHING option of a file/string + $script = $this->hash->set($script); + + // add base64 locking option of a string + $script = $this->base64->set($script); + + // load the script + $this->setHub($script, $first, $second, $third, $add); + + return true; + } + + return false; + } + + /** + * Get the script from the customcode dispenser + * + * @param string $first The first key + * @param string $second The second key + * @param string $prefix The prefix to add in front of the script if found + * @param string|null $note The switch/note to add to the script + * @param bool $unset The switch to unset the value if found + * @param mixed|null $default The switch/string to use as default return if script not found + * @param string $suffix The suffix to add after the script if found + * + * @return mixed The string/script if found or the default value if not found + * @since 3.2.0 + */ + public function get(string $first, string $second, string $prefix = '', ?string $note = null, + bool $unset = false, $default = null, string $suffix = '') + { + // default is to return an empty string + $script = ''; + // check if there is any custom script + if (isset($this->hub[$first][$second]) + && StringHelper::check( + $this->hub[$first][$second] + )) + { + // add not if set + if ($note) + { + $script .= $note; + } + // load the actual script + $script .= $prefix . str_replace( + array_keys($this->placeholder->active), + array_values($this->placeholder->active), + (string) $this->hub[$first][$second] + ) . $suffix; + // clear some memory + if ($unset) + { + unset($this->hub[$first][$second]); + } + } + // if not found return default + if (!StringHelper::check($script) && $default) + { + return $default; + } + + return $script; + } + + /** + * Make sure the hub arrays are all set + * + * @param string $first The first key + * @param string|null $second The second key (if not set we use only first key) + * @param string|null $third The third key (if not set we use only first and second key) + * @param bool $add The switch to add to exiting instead of replace + * default: false + * + * @return void + * @since 3.2.0 + */ + protected function initHub(string $first, ?string $second = null, ?string $third = null, bool $add = false) + { + if (!isset($this->hub[$first])) + { + $this->hub[$first] = ($second !== null || $add) ? ($second !== null ? [] : '') : []; + } + + if ($second !== null && !isset($this->hub[$first][$second])) + { + $this->hub[$first][$second] = ($third !== null || $add) ? ($third !== null ? [] : '') : []; + } + + if ($third !== null && !isset($this->hub[$first][$second][$third])) + { + $this->hub[$first][$second][$third] = $add ? '' : []; + } + } + + /** + * Set a script in the hub + * + * @param string $script The script + * @param string $first The first key + * @param string|null $second The second key (if not set we use only first key) + * @param string|null $third The third key (if not set we use only first and second key) + * @param bool $add The switch to add to exiting instead of replace + * default: false + * + * @return void + * @since 3.2.0 + */ + protected function setHub(string $script, string $first, ?string $second = null, ?string $third = null, bool $add = false) + { + // Load the script + if ($second !== null) + { + if ($third !== null) + { + $this->hub[$first][$second][$third] = + $add ? $this->hub[$first][$second][$third] . $script : $script; + } + else + { + $this->hub[$first][$second] = + $add ? $this->hub[$first][$second] . $script : $script; + } + } + else + { + $this->hub[$first] = + $add ? $this->hub[$first] . $script : $script; + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/External.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/External.php new file mode 100644 index 000000000..1b8acfc19 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/External.php @@ -0,0 +1,399 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Customcode; + + +use Joomla\CMS\Factory; +use Joomla\CMS\User\User; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Filesystem\Path; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode\ExternalInterface; + + +/** + * Compiler External Custom Code + * + * @since 3.2.0 + */ +class External implements ExternalInterface +{ + /** + * The external code/string to be added + * + * @var array + * @since 3.2.0 + */ + protected array $code = []; + + /** + * The external code/string cutter + * + * @var array + * @since 3.2.0 + */ + protected array $cutter = []; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * User object + * + * @var User + * @since 3.2.0 + **/ + protected User $user; + + /** + * Database object to query local DB + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param \JDatabaseDriver|null $db The Database Driver object. + * @param User|null $user The User object. + * @param CMSApplication|null $app The CMS Application object. + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Placeholder $placeholder = null, + ?\JDatabaseDriver $db = null, ?User $user = null, ?CMSApplication $app = null) + { + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->db = $db ?: Factory::getDbo(); + $this->user = $user ?: Factory::getUser(); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * Set the external code string & load it in to string + * + * @param string $string The content to check + * @param int $debug The switch to debug the update + * + * @return string + * @since 3.2.0 + */ + public function set(string $string, int $debug = 0): string + { + // check if content has custom code placeholder + if (strpos($string, '[EXTERNA' . 'LCODE=') !== false) + { + // if debug + if ($debug) + { + echo 'External Code String:'; + var_dump($string); + } + // target content + $bucket = []; + $found = GetHelper::allBetween( + $string, '[EXTERNA' . 'LCODE=', ']' + ); + if (ArrayHelper::check($found)) + { + // build local bucket + foreach ($found as $target) + { + // check for cutting sequence + // example: >{3|4 + // will cut 3 rows at top and 4 rows at bottom + // if the external code has 8 or more lines + if (($pos = strpos((string) $target, '>{')) !== false) + { + // the length + $target_len = strlen((string) $target); + // where to cut + $cutting = $target_len - $pos; + // get the sequence + $sequence = substr((string) $target, "-$cutting"); + // remove from the URL + $target_url = str_replace($sequence, '', (string) $target); + // set the cut key for this target if not set + $this->cutter[trim((string) $target)] = str_replace('>{', '', $sequence); + } + else + { + $target_url = $target; + } + // check if the target is valid URL or path + if ((!filter_var($target_url, FILTER_VALIDATE_URL) === false + && FileHelper::exists($target_url)) + || (Path::clean($target_url) === $target_url + && FileHelper::exists($target_url))) + { + $this->getCode($target, $bucket); + } + // give notice that target is not a valid url/path + else + { + // set key + $key = '[EXTERNA' . 'LCODE=' . $target . ']'; + // set the notice + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_WARNINGHTHREE' + ), 'Warning' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_IS_NOT_A_VALID_URLPATH', + $key + ), 'Warning' + ); + // remove the placeholder + $bucket[$key] = ''; + } + } + // now update local string if bucket has values + if (ArrayHelper::check($bucket)) + { + $string = $this->placeholder->update($string, $bucket); + } + } + // if debug + if ($debug) + { + echo 'External Code String After Update:'; + var_dump($string); + } + } + + return $string; + } + + /** + * Get the External Code/String + * + * @param string $string The content to check + * @param array $bucket The Placeholders bucket + * + * @return void + * @since 3.2.0 + */ + protected function getCode(string $target, array &$bucket) + { + // set URL key + $target_key = trim($target); + // set key + $key = '[EXTERNA' . 'LCODE=' . $target . ']'; + // remove the cut sequence from the url + if (isset($this->cutter[$target_key])) + { + // remove from the URL + $target_url = trim(str_replace('>{' . $this->cutter[$target_key], '', $target)); + } + else + { + $target_url = trim($target); + } + // check if we already fetched this + if (!isset($this->code[$target_key])) + { + // get the data string (code) + $this->code[$target_key] + = FileHelper::getContent($target_url); + // check if we must cut this + if (isset($this->cutter[$target_key]) && + $this->cutter[$target_key]) + { + $this->code[$target_key] = $this->cut( + $this->code[$target_key], + $this->cutter[$target_key], + $key + ); + } + // did we get any value + if (StringHelper::check( + $this->code[$target_key] + )) + { + // check for changes + $live_hash = md5($this->code[$target_key]); + // check if it exists local + if ($hash = GetHelper::var( + 'external_code', $target_key, 'target', 'hash' + )) + { + // must be an admin make a change to use EXTERNAL code (we may add a custom access switch - use ADMIN for now) + if ($hash !== $live_hash && $this->user->authorise( + 'core.admin', 'com_componentbuilder' + )) + { + // update the hash since it changed + $object = new \stdClass(); + $object->target = $target_key; + $object->hash = $live_hash; + // update local hash + $this->db->updateObject( + '#__componentbuilder_external_code', $object, + 'target' + ); + // give notice of the change + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_WARNINGHTHREE'), + 'Warning' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_CODESTRING_FROM_BSB_HAS_BEEN_BCHANGEDB_SINCE_THE_LAST_COMPILATION_PLEASE_INVESTIGATE_TO_ENSURE_THE_CHANGES_ARE_SAFE_BSHOULD_YOU_NOT_EXPECT_THIS_CHANGE_TO_THE_EXTERNAL_CODESTRING_BEING_ADDED_THEN_THIS_IS_A_SERIOUS_ISSUE_AND_REQUIRES_IMMEDIATE_ATTENTIONB_DO_NOT_IGNORE_THIS_WARNING_AS_IT_WILL_ONLY_SHOW_BONCEB', + $key + ), 'Warning' + ); + } + elseif ($hash !== $live_hash) + { + // set the notice + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_ERRORHTHREE'), + 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_S_WE_DETECTED_A_CHANGE_IN_BEXTERNALCODEB_BUT_YOU_DO_NOT_HAVE_PERMISSION_TO_ALLOW_THIS_CHANGE_SO_BSB_WAS_REMOVED_FROM_THE_COMPILATION_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFOBR_SMALLADMIN_ACCESS_REQUIREDSMALL', + $this->user->get('name'), $key + ), 'Error' + ); + // remove the code/string + $this->code[$target_key] = ''; + } + } + // only an admin can add new EXTERNAL code (we may add a custom access switch - use ADMIN for now) + elseif ($this->user->authorise( + 'core.admin', 'com_componentbuilder' + )) + { + // add the hash to track changes + $object = new \stdClass(); + $object->target = $target_key; + $object->hash = $live_hash; + // insert local hash + $this->db->insertObject( + '#__componentbuilder_external_code', $object + ); + // give notice the first time this is added + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_NOTICEHTHREE'), + 'Warning' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_CODESTRING_FROM_BSB_HAS_BEEN_ADDED_FOR_THE_BFIRST_TIMEB_PLEASE_IINVESTIGATEI_TO_ENSURE_THE_CORRECT_CODESTRING_WAS_USED_BSHOULD_YOU_NOT_KNOW_ABOUT_THIS_NEW_EXTERNAL_CODESTRING_BEING_ADDED_THEN_THIS_IS_A_SERIOUS_DANGER_AND_REQUIRES_IMMEDIATE_ATTENTIONB_DO_NOT_IGNORE_THIS_WARNING_AS_IT_WILL_ONLY_SHOW_BONCEB', + $key + ), 'Warning' + ); + } + else + { + // set the notice + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_ERRORHTHREE'), + 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_S_WE_DETECTED_BNEW_EXTERNALCODEB_BUT_YOU_DO_NOT_HAVE_PERMISSION_TO_ALLOW_THIS_NEW_CODESTRING_SO_BSB_WAS_REMOVED_FROM_THE_COMPILATION_PLEASE_CONTACT_YOU_SYSTEM_ADMINISTRATOR_FOR_MORE_INFOBR_SMALLADMIN_ACCESS_REQUIREDSMALL', + $this->user->get('name'), $key + ), 'Error' + ); + // remove the code/string + $this->code[$target_key] = ''; + } + } + else + { + // set notice that we could not get a valid string from the target + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_WARNINGHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_RETURNED_AN_INVALID_STRING', $key + ), 'Error' + ); + } + } + + // add to local bucket + $bucket[$key] = $this->code[$target_key] ?? ''; + } + + /** + * Cut the External Code/String + * + * @param string $string The content to cut + * @param string $sequence The cutting sequence + * @param string $key The content key + * + * @return string + * @since 3.2.0 + */ + protected function cut(string $string, string $sequence, string $key): string + { + // we first break the string up in rows + $rows = (array) explode(PHP_EOL, $string); + // get the cutting sequence + $cutter = (array) explode('|', $sequence); + // we only continue if we have more rows than we have to cut + if (array_sum($cutter) < ArrayHelper::check($rows)) + { + // remove the rows at the bottom if needed + if (isset($cutter[1]) && $cutter[1] > 0) + { + array_splice($rows, "-$cutter[1]"); + } + // remove the rows at the top if needed + if ($cutter[0] > 0) + { + $rows = array_splice($rows, $cutter[0]); + } + + // return the remaining rows + return implode(PHP_EOL, $rows); + } + + // we set an error message about too few lines to cut + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_NOTICEHTHREE'), + 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_CUT_SEQUENCE_FAILED_ON_THE_RETURNED_EXTERNAL_CODESTRING_AS_MORE_LINES_HAS_TO_BE_CUT_THEN_WAS_FOUND_IN_THE_CODESTRING_WE_HAVE_COMPLETELY_REMOVED_THE_CODE_PLEASE_CHECK_THIS_CODESTRING', + $key + ), 'Error' + ); + + return ''; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Extractor.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Extractor.php new file mode 100644 index 000000000..bc52c6801 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Extractor.php @@ -0,0 +1,930 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Customcode; + + +use Joomla\CMS\Factory; +use Joomla\CMS\User\User; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Extractor\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder\Reverse; +use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Pathfix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode\ExtractorInterface; + + +/** + * Compiler Custom Code Extractor + * + * The custom script placeholders - we use the (xxx) to avoid detection it should be (***) + * ##################################---> PHP/JS ---#################################### + * + * New Insert Code = /xxx[INSERT>$$$$]xxx/ /xxx[/INSERT>$$$$]xxx/ + * New Replace Code = /xxx[REPLACE>$$$$]xxx/ /xxx[/REPLACE>$$$$]xxx/ + * + * //////////////////////////////// when JCB adds it back ////////////////////////////////// + * JCB Add Inserted Code = /xxx[INSERTED$$$$]xxx//xx23xx/ /xxx[/INSERTED$$$$]xxx/ + * JCB Add Replaced Code = /xxx[REPLACED$$$$]xxx//xx25xx/ /xxx[/REPLACED$$$$]xxx/ + * + * /////////////////////////////// changeing existing custom code ///////////////////////// + * Update Inserted Code = /xxx[INSERTED>$$$$]xxx//xx23xx/ /xxx[/INSERTED>$$$$]xxx/ + * Update Replaced Code = /xxx[REPLACED>$$$$]xxx//xx25xx/ /xxx[/REPLACED>$$$$]xxx/ + * + * The custom script placeholders - we use the (==) to avoid detection it should be (--) + * ###################################---> HTML ---##################################### + * + * New Insert Code = !==[INSERT>$$$$]==> !==[/INSERT>$$$$]==> + * New Replace Code = !==[REPLACE>$$$$]==> !==[/REPLACE>$$$$]==> + * + * ///////////////////////////////// when JCB adds it back /////////////////////////////// + * JCB Add Inserted Code = + * JCB Add Replaced Code = + * + * //////////////////////////// changeing existing custom code /////////////////////////// + * Update Inserted Code = !==[INSERTED>$$$$]==> !==[/INSERTED>$$$$]==> + * Update Replaced Code = !==[REPLACED>$$$$]==> !==[/REPLACED>$$$$]==> + * + * ////////23 is the ID of the code in the system don't change it!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * More info read: https://git.vdm.dev/joomla/Component-Builder/wiki/TIPS:-Custom-Code + * + * @since 3.2.0 + */ +class Extractor implements ExtractorInterface +{ + /** + * The placeholder keys + * + * @var array + * @since 3.2.0 + */ + protected array $PKeys + = [ + 1 => 'REPLACE<>$$$$]', + 2 => 'INSERT<>$$$$]', + 3 => 'REPLACED<>$$$$]', + 4 => 'INSERTED<>$$$$]' + ]; + + /** + * The custom code in local files that already exist in system + * + * @var array + * @since 3.2.0 + */ + protected array $existing = []; + + /** + * The custom code in local files that are new + * + * @var array + * @since 3.2.0 + */ + protected array $new = []; + + /** + * The index of code already loaded + * + * @var array + * @since 3.2.0 + */ + protected array $done = []; + + /** + * The search counter + * + * @var array + * @since 3.2.0 + */ + protected array $counter = [1 => 0, 2 => 0]; + + /** + * The file types to search + * + * @var array + * @since 3.2.0 + */ + protected array $fileTypes = ['\.php', '\.js', '\.xml']; + + /** + * The local placeholders + * + * @var array + * @since 3.2.0 + */ + protected array $placeholders; + + /** + * Today's date in SQL format + * + * @var string + * @since 3.2.0 + */ + protected string $today; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Compiler Customcode Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Customcode Extractor Paths + * + * @var Paths + * @since 3.2.0 + **/ + protected Paths $paths; + + /** + * Compiler Placeholder Reverse + * + * @var Reverse + * @since 3.2.0 + **/ + protected Reverse $reverse; + + /** + * Compiler Component Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $componentPlaceholder; + + /** + * Compiler Component Pathfix + * + * @var Pathfix + * @since 3.2.0 + **/ + protected Pathfix $pathfix; + + /** + * Current User Object + * + * @var User + * @since 3.2.0 + **/ + protected User $user; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Database object to query local DB + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param Config|null $config The compiler config object. + * @param Gui|null $gui The compiler customcode gui object. + * @param Paths|null $paths The compiler customcode extractor paths object. + * @param Reverse|null $reverse The compiler placeholder reverse object. + * @param Placeholder|null $placeholder The compiler component placeholder object. + * @param Pathfix|null $pathfix The compiler path fixing object. + * @param User|null $user The current User object. + * @param \JDatabaseDriver|null $db The Database Driver object. + * @param CMSApplication|null $app The CMS Application object. + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Gui $gui = null, ?Paths $paths = null, + ?Reverse $reverse = null, ?Placeholder $placeholder = null, ?Pathfix $pathfix = null, + ?User $user = null, ?\JDatabaseDriver $db = null, ?CMSApplication $app = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->paths = $paths ?: Compiler::_('Customcode.Extractor.Paths'); + $this->reverse = $reverse ?: Compiler::_('Placeholder.Reverse'); + $this->componentPlaceholder = $placeholder ?: Compiler::_('Component.Placeholder'); + $this->pathfix = $pathfix ?: Compiler::_('Utilities.Pathfix'); + $this->user = $user ?: Factory::getUser(); + $this->db = $db ?: Factory::getDbo(); + $this->app = $app ?: Factory::getApplication(); + + // set today's date + $this->today = Factory::getDate()->toSql(); + + // set some local placeholders + $placeholders = array_flip( + $this->componentPlaceholder->get() + ); + + $placeholders[StringHelper::safe( + $this->config->component_code_name, 'F' + ) . 'Helper::'] = Placefix::_('Component') . 'Helper::'; + + $placeholders['COM_' . StringHelper::safe( + $this->config->component_code_name, 'U' + )] = 'COM_' . Placefix::_('COMPONENT'); + + $placeholders['com_' . $this->config->component_code_name] = 'com_' . Placefix::_('component'); + + // set the local placeholders + $this->placeholders = array_reverse($placeholders, true); + } + + /** + * get the custom code from the local files + * + * @return void + * @since 3.2.0 + */ + public function run() + { + // we must first store the current working directory + $joomla = getcwd(); + + foreach ($this->paths->active as $target => $path) + { + // we are changing the working directory to the component path + chdir($path); + foreach ($this->fileTypes as $type) + { + // get a list of files in the current directory tree (only PHP, JS and XML for now) + $files = Folder::files('.', $type, true, true); + + // check if files found + if (ArrayHelper::check($files)) + { + foreach ($files as $file) + { + // search the file + $this->searchFileContent($file, $target); + + // insert new code + $this->insert(100); + + // update existing custom code + $this->update(30); + } + } + } + } + + // change back to Joomla working directory + chdir($joomla); + + // make sure all code is stored + $this->insert(); + // update existing custom code + $this->update(); + } + + /** + * search a file for placeholders and store result + * + * @param string $file The file path to search + * + * @return array on success + * @since 3.2.0 + */ + protected function searchFileContent(&$file, &$target) + { + // we add a new search for the GUI CODE Blocks + $this->gui->search($file, $this->placeholders, $this->today, $target); + + // reset each time per file + $loadEndFingerPrint = false; + $endFingerPrint = []; + $fingerPrint = []; + $codeBucket = []; + $pointer = []; + $reading = []; + $reader = 0; + + // reset found Start type + $commentType = 0; + + // make sure we have the path correct (the script file is not in admin path for example) + // there may be more... will nead to keep our eye on this... since files could be moved during install + $file = str_replace('./', '', (string) $file); # TODO (windows path issues) + $path = $file !== 'script.php' ? $target . '/' . $file : $file; + + // now we go line by line + foreach (new \SplFileObject($file) as $lineNumber => $lineContent) + { + // we must keep last few lines to dynamic find target entry later + $fingerPrint[$lineNumber] = trim($lineContent); + + // load the end fingerprint + if ($loadEndFingerPrint) + { + $endFingerPrint[$lineNumber] = trim($lineContent); + } + + foreach ($this->PKeys as $type => $search) + { + $i = (int) ($type == 3 || $type == 4) ? 2 : 1; + $_type = (int) ($type == 1 || $type == 3) ? 1 : 2; + + if ($reader === 0 || $reader === $i) + { + $targetKey = $type; + + $start = '/***[' . $search . '***/'; + $end = '/***[/' . $search . '***/'; + $startHTML = ''; + $endHTML = ''; + + // check if the ending placeholder was found + if (isset($reading[$targetKey]) && $reading[$targetKey] + && ((trim((string) $lineContent) === $end + || strpos((string) $lineContent, $end) !== false) + || (trim((string) $lineContent) === $endHTML + || strpos((string) $lineContent, $endHTML) !== false))) + { + // trim the placeholder and if there is still data then load it + if (isset($endReplace) + && ($_line = $this->addLineChecker($endReplace, 2, $lineContent)) !== false) + { + $codeBucket[$pointer[$targetKey]][] = $_line; + } + + // deactivate the reader + $reading[$targetKey] = false; + + if ($_type == 2) + { + // deactivate search + $reader = 0; + } + else + { + // activate fingerPrint for replacement end target + $loadEndFingerPrint = true; + $backupTargetKey = $targetKey; + $backupI = $i; + } + + // all new records we can do a bulk insert + if ($i === 1) + { + // end the bucket info for this code block + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + (int) $lineNumber + ); // 'toline' + + // first reverse engineer this code block + $c0de = $this->reverse->engine( + implode('', $codeBucket[$pointer[$targetKey]]), + $this->placeholders, $target + ); + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + base64_encode((string) $c0de) + ); // 'code' + + if ($_type == 2) + { + // load the last value + $this->new[$pointer[$targetKey]][] + = $this->db->quote(0); // 'hashendtarget' + } + } + // the record already exist so we must update instead + elseif ($i === 2) + { + // end the bucket info for this code block + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('to_line') . ' = ' + . $this->db->quote($lineNumber); + + // first reverse engineer this code block + $c0de = $this->reverse->engine( + implode('', $codeBucket[$pointer[$targetKey]]), + $this->placeholders, $target, + $this->existing[$pointer[$targetKey]]['id'] + ); + + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('code') . ' = ' + . $this->db->quote(base64_encode((string) $c0de)); + + if ($_type == 2) + { + // load the last value + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('hashendtarget') + . ' = ' . $this->db->quote(0); + } + } + } + + // check if the endfingerprint is ready to save + if (count((array) $endFingerPrint) === 3) + { + $hashendtarget = '3__' . md5( + implode('', $endFingerPrint) + ); + + // all new records we can do a bulk insert + if ($i === 1) + { + // load the last value + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + $hashendtarget + ); // 'hashendtarget' + } + // the record already exist so we must update + elseif ($i === 2) + { + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('hashendtarget') . ' = ' + . $this->db->quote($hashendtarget); + } + + // reset the needed values + $endFingerPrint = []; + $loadEndFingerPrint = false; + + // deactivate reader (to allow other search) + $reader = 0; + } + + // then read in the code + if (isset($reading[$targetKey]) && $reading[$targetKey]) + { + $codeBucket[$pointer[$targetKey]][] = $lineContent; + } + + // see if the custom code line starts now with PHP/JS comment type + if ((!isset($reading[$targetKey]) || !$reading[$targetKey]) + && (($i === 1 && trim((string) $lineContent) === $start) + || strpos((string) $lineContent, $start) !== false)) + { + $commentType = 1; // PHP/JS type + $startReplace = $start; + $endReplace = $end; + } + // see if the custom code line starts now with HTML comment type + elseif ((!isset($reading[$targetKey]) + || !$reading[$targetKey]) + && (($i === 1 && trim((string) $lineContent) === $startHTML) + || strpos((string) $lineContent, $startHTML) !== false)) + { + $commentType = 2; // HTML type + $startReplace = $startHTML; + $endReplace = $endHTML; + } + + // check if the starting place holder was found + if ($commentType > 0) + { + // if we have all on one line we have a problem (don't load it TODO) + if (strpos((string) $lineContent, (string) $endReplace) !== false) + { + // reset found comment type + $commentType = 0; + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREECUSTOM_CODES_WARNINGHTHREE'), + 'Warning' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_WE_FOUND_DYNAMIC_CODE_BALL_IN_ONE_LINEB_AND_IGNORED_IT_PLEASE_REVIEW_S_FOR_MORE_DETAILS', + $path + ), 'Warning' + ); + continue; + } + + // do a quick check to insure we have an id + $id = false; + if ($i === 2) + { + $id = $this->getSystemID( + $lineContent, + array(1 => $start, 2 => $startHTML), + $commentType + ); + } + + if ($i === 2 && $id > 0) + { + // make sure we update it only once even if found again. + if (isset($this->done[$id])) + { + // reset found comment type + $commentType = 0; + continue; + } + // store the id to avoid duplication + $this->done[$id] = (int) $id; + } + + // start replace + $startReplace = $this->setStartReplace( + $id, $commentType, $startReplace + ); + + // set active reader (to lock out other search) + $reader = $i; + + // set pointer + $pointer[$targetKey] = $this->counter[$i]; + + // activate the reader + $reading[$targetKey] = true; + + // start code bucket + $codeBucket[$pointer[$targetKey]] = []; + + // trim the placeholder and if there is still data then load it + if ($_line = $this->addLineChecker( + $startReplace, 1, $lineContent + )) + { + $codeBucket[$pointer[$targetKey]][] = $_line; + } + + // get the finger print around the custom code + $inFinger = count($fingerPrint); + $getFinger = $inFinger - 1; + $hasharray = array_slice( + $fingerPrint, -$inFinger, $getFinger, true + ); + $hasleng = count($hasharray); + $hashtarget = $hasleng . '__' . md5( + implode('', $hasharray) + ); + + // for good practice + $this->pathfix->set($path); + + // all new records we can do a bulk insert + if ($i === 1 || !$id) + { + // start the bucket for this code + $this->new[$pointer[$targetKey]] = []; + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + $path + ); // 'path' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + (int) $_type + ); // 'type' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + 1 + ); // 'target' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + $commentType + ); // 'comment_type' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + (int) $this->config->component_id + ); // 'component' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + 1 + ); // 'published' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + $this->today + ); // 'created' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + (int) $this->user->id + ); // 'created_by' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + 1 + ); // 'version' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + 1 + ); // 'access' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + $hashtarget + ); // 'hashtarget' + + $this->new[$pointer[$targetKey]][] + = $this->db->quote( + (int) $lineNumber + ); // 'fromline' + + } + // the record already exist so we must update instead + elseif ($i === 2 && $id > 0) + { + // start the bucket for this code + $this->existing[$pointer[$targetKey]] = []; + $this->existing[$pointer[$targetKey]]['id'] + = (int) $id; + $this->existing[$pointer[$targetKey]]['conditions'] = []; + $this->existing[$pointer[$targetKey]]['conditions'][] + = $this->db->quoteName('id') . ' = ' + . $this->db->quote($id); + $this->existing[$pointer[$targetKey]]['fields'] = []; + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('path') . ' = ' + . $this->db->quote($path); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('type') . ' = ' + . $this->db->quote($_type); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('comment_type') . ' = ' + . $this->db->quote($commentType); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('component') . ' = ' + . $this->db->quote($this->config->component_id); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('from_line') . ' = ' + . $this->db->quote($lineNumber); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('modified') . ' = ' + . $this->db->quote($this->today); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('modified_by') . ' = ' + . $this->db->quote($this->user->id); + $this->existing[$pointer[$targetKey]]['fields'][] + = $this->db->quoteName('hashtarget') . ' = ' + . $this->db->quote($hashtarget); + } + else // this should actualy never happen + { + // de activate the reader + $reading[$targetKey] = false; + $reader = 0; + } + + // reset found comment type + $commentType = 0; + // update the counter + $this->counter[$i]++; + } + } + } + + // make sure only a few lines is kept at a time + if (count((array) $fingerPrint) > 10) + { + $fingerPrint = array_slice($fingerPrint, -6, 6, true); + } + } + + // if the code is at the end of the page and there were not three more lines + if (count((array) $endFingerPrint) > 0 || $loadEndFingerPrint) + { + if (count((array) $endFingerPrint) > 0) + { + $leng = count($endFingerPrint); + $hashendtarget = $leng . '__' . md5( + implode('', $endFingerPrint) + ); + } + else + { + $hashendtarget = 0; + } + + // all new records we can do a buldk insert + if ($backupI === 1) + { + // load the last value + $this->new[$pointer[$backupTargetKey]][] + = $this->db->quote($hashendtarget); // 'hashendtarget' + } + // the record already exist so we must use module to update + elseif ($backupI === 2) + { + $this->existing[$pointer[$backupTargetKey]]['fields'][] + = $this->db->quoteName('hashendtarget') . ' = ' + . $this->db->quote($hashendtarget); + } + } + } + + /** + * Insert the code + * + * @param int $when To set when to update + * + * @return void + * @since 3.2.0 + */ + protected function insert(int $when = 1) + { + if (ArrayHelper::check($this->new) >= $when) + { + // Create a new query object. + $query = $this->db->getQuery(true); + $continue = false; + // Insert columns. + $columns = array('path', 'type', 'target', 'comment_type', + 'component', 'published', 'created', 'created_by', + 'version', 'access', 'hashtarget', 'from_line', + 'to_line', 'code', 'hashendtarget'); + // Prepare the insert query. + $query->insert( + $this->db->quoteName('#__componentbuilder_custom_code') + ); + $query->columns($this->db->quoteName($columns)); + foreach ($this->new as $values) + { + if (count((array) $values) == 15) + { + $query->values(implode(',', $values)); + $continue = true; + } + else + { + // TODO line mismatch... should not happen + } + } + // clear the values array + $this->new = []; + if (!$continue) + { + return; // insure we don't continue if no values were loaded + } + // Set the query using our newly populated query object and execute it. + $this->db->setQuery($query); + $this->db->execute(); + } + } + + /** + * Update the code + * + * @param int $when To set when to update + * + * @return void + * @since 3.2.0 + */ + protected function update(int $when = 1) + { + if (ArrayHelper::check($this->existing) >= $when) + { + foreach ($this->existing as $code) + { + // Create a new query object. + $query = $this->db->getQuery(true); + // Prepare the update query. + $query->update( + $this->db->quoteName('#__componentbuilder_custom_code') + )->set($code['fields'])->where($code['conditions']); + // Set the query using our newly populated query object and execute it. + $this->db->setQuery($query); + $this->db->execute(); + } + // clear the values array + $this->existing = []; + } + } + + /** + * set the start replace placeholder + * + * @param int $id The comment id + * @param int $commentType The comment type + * @param string $startReplace The main replace string + * + * @return string on success + * @since 3.2.0 + */ + protected function setStartReplace(int $id, int $commentType, string $startReplace): string + { + if ($id > 0) + { + switch ($commentType) + { + case 1: // the PHP & JS type + $startReplace .= '/*' . $id . '*/'; + break; + case 2: // the HTML type + $startReplace .= ''; + break; + } + } + + return $startReplace; + } + + /** + * Check if this line should be added + * + * @param string $replaceKey The key to remove from line + * @param int $type The line type + * @param string $lineContent The line to check + * + * @return bool|int true on success + * @since 3.2.0 + */ + protected function addLineChecker(string $replaceKey, int $type, string $lineContent) + { + $check = explode($replaceKey, $lineContent); + switch ($type) + { + case 1: + // beginning of code + if (isset($check[1]) && StringHelper::check($check[1])) + { + return trim($check[1]); + } + break; + case 2: + // end of code + if (isset($check[0]) && StringHelper::check($check[0])) + { + return trim($check[0]); + } + break; + } + + return false; + } + + /** + * search for the system id in the line given + * + * @param string $lineContent The file path to search + * @param array $placeholders The values to search for + * @param int $commentType The comment type + * + * @return mixed on success + * @since 3.2.0 + */ + protected function getSystemID(string &$lineContent, array $placeholders, int $commentType) + { + $trim = '/'; + if ($commentType == 2) + { + $trim = '' . PHP_EOL; + $back = '' + ); + + if (($guiCode = ArrayHelper::merge($guiCode)) !== false + && ArrayHelper::check($guiCode, true)) + { + foreach ($guiCode as $code) + { + $first_line = strtok($code, PHP_EOL); + // get the GUI target details + $query = explode('.', trim($first_line, '.')); + // only continue if we have 3 values in the query + if (is_array($query) && count($query) >= 3) + { + // cleanup the newlines around the code + $code = trim(str_replace($first_line, '', (string) $code), PHP_EOL) + . PHP_EOL; + // set the ID + $id = (int) $query[2]; + // make the field name save + $field = FieldHelper::safe($query[1]); + // make the table name save + $table = StringHelper::safe($query[0]); + // reverse placeholder as much as we can + $code = $this->reverse->engine( + $code, $placeholders, $target, $id, $field, $table, $use_statements + ); + // update the GUI/Tables/Database + $object = new \stdClass(); + $object->id = $id; + $object->{$field} = base64_encode( + (string) $code + ); // (TODO) this may not always work... + // update the value in GUI + $this->db->updateObject( + '#__componentbuilder_' . (string) $table, $object, 'id' + ); + } + } + } + } + + /** + * search a code to see if there is already any custom + * code or other reasons not to add the GUI code placeholders + * + * @param string $code The code to check + * + * @return bool true if GUI code placeholders can be added + * @since 3.2.0 + */ + protected function check(string &$code): bool + { + // check for customcode placeholders + // we do not add GUI wrapper placeholder to code + // that already has any customcode placeholders + return strpos($code, '$$$$') === false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Hash.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Hash.php new file mode 100644 index 000000000..e8a835c83 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Hash.php @@ -0,0 +1,111 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Customcode; + + +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; + + +/** + * Compiler Custom Code MD5 + * + * @since 3.2.0 + */ +class Hash +{ + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Constructor. + * + * @param Placeholder|null $placeholder The compiler placeholder object. + * + * @since 3.2.0 + */ + public function __construct(?Placeholder $placeholder = null) + { + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + } + + /** + * Set the MD5 hashed string or file or string + * + * @param string $script The code string + * + * @return string + * @since 3.2.0 + */ + public function set(string $script): string + { + // check if we should hash a string + if (strpos($script, 'HASH' . 'STRING((((') !== false) + { + // get the strings + $values = GetHelper::allBetween( + $script, 'HASH' . 'STRING((((', '))))' + ); + $locker = []; + // convert them + foreach ($values as $value) + { + $locker['HASH' . 'STRING((((' . $value . '))))'] + = md5((string) $value); + } + + // update the script + return $this->placeholder->update($script, $locker); + } + + // check if we should hash a file + if (strpos($script, 'HASH' . 'FILE((((') !== false) + { + // get the strings + $values = GetHelper::allBetween( + $script, 'HASH' . 'FILE((((', '))))' + ); + $locker = []; + // convert them + foreach ($values as $path) + { + // we first get the file if it exists + if (FileHelper::exists($path) && $value = FileHelper::getContent($path)) + { + // now we hash the file content + $locker['HASH' . 'FILE((((' . $path . '))))'] + = md5((string) $value); + } + else + { + // could not retrieve the file so we show error + $locker['HASH' . 'FILE((((' . $path . '))))'] + = 'ERROR'; + } + } + + // update the script + return $this->placeholder->update($script, $locker); + } + + return $script; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/LockBase.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/LockBase.php new file mode 100644 index 000000000..7f490dfb8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/LockBase.php @@ -0,0 +1,85 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Customcode; + + +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode\LockBaseInterface; + + +/** + * Compiler Custom Code Base64 + * + * @since 3.2.0 + */ +class LockBase implements LockBaseInterface +{ + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Constructor. + * + * @param Placeholder|null $placeholder The compiler placeholder object. + * + * @since 3.2.0 + */ + public function __construct(?Placeholder $placeholder = null) + { + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + } + + /** + * Set a string as bsae64 (basic) + * + * @param string $script The code string + * + * @return string + * @since 3.2.0 + */ + public function set(string $script): string + { + if (\strpos($script, 'LOCK'.'BASE64((((') !== false) + { + // get the strings + $values = GetHelper::allBetween( + $script, 'LOCK'.'BASE64((((', '))))' + ); + $locker = []; + // convert them + foreach ($values as $value) + { + $locker['LOCK'.'BASE64((((' . $value . '))))'] + = "base64_decode( preg_replace('/\s+/', ''," . + PHP_EOL . Indent::_(2) . "'" . + wordwrap( + base64_encode((string) $value), 64, PHP_EOL . Indent::_(2), true + ) . + "'))"; + } + + // update the script + return $this->placeholder->update($script, $locker); + } + + return $script; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php new file mode 100644 index 000000000..709581696 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customview/Data.php @@ -0,0 +1,341 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Customview; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Model\Libraries; +use VDM\Joomla\Componentbuilder\Compiler\Templatelayout\Data as Templatelayout; +use VDM\Joomla\Componentbuilder\Compiler\Dynamicget\Data as Dynamicget; +use VDM\Joomla\Componentbuilder\Compiler\Model\Loader; +use VDM\Joomla\Componentbuilder\Compiler\Model\Javascriptcustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Csscustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Phpcustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Ajaxcustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Custombuttons; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Unique; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Admin Custom View Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * Admin views + * + * @var array + * @since 3.2.0 + */ + protected array $data; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Compiler Event + * + * @var EventInterface + * @since 3.2.0 + */ + protected EventInterface $event; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Libraries Model + * + * @var Libraries + * @since 3.2.0 + */ + protected Libraries $libraries; + + /** + * Compiler Template Layout + * + * @var Templatelayout + * @since 3.2.0 + */ + protected Templatelayout $templateLayout; + + /** + * Compiler Dynamic Get Data + * + * @var Dynamicget + * @since 3.2.0 + */ + protected Dynamicget $dynamic; + + /** + * Compiler Auto Loader + * + * @var Loader + * @since 3.2.0 + */ + protected Loader $loader; + + /** + * The modelling javascript + * + * @var Javascriptcustomview + * @since 3.2.0 + */ + protected Javascriptcustomview $javascript; + + /** + * The modelling css + * + * @var Csscustomview + * @since 3.2.0 + */ + protected Csscustomview $css; + + /** + * The modelling php admin view + * + * @var Phpcustomview + * @since 3.2.0 + */ + protected Phpcustomview $php; + + /** + * The modelling custom buttons + * + * @var Custombuttons + * @since 3.2.0 + */ + protected Custombuttons $custombuttons; + + /** + * The modelling ajax + * + * @var Ajaxcustomview + * @since 3.2.0 + */ + protected Ajaxcustomview $ajax; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param EventInterface|null $event The compiler event api object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param Libraries|null $libraries The compiler libraries model object. + * @param Templatelayout|null $templateLayout The compiler template layout object. + * @param Dynamicget|null $dynamic The compiler dynamic get data object. + * @param Loader|null $loader The compiler loader object. + * @param Javascriptcustomview|null $javascript The modelling javascript object. + * @param Csscustomview|null $css The modelling css object. + * @param Phpcustomview|null $php The modelling php admin view object. + * @param Ajaxcustomview|null $ajax The modelling ajax object. + * @param Custombuttons|null $custombuttons The modelling custombuttons object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?EventInterface $event = null, + ?Customcode $customcode = null, ?Gui $gui = null, ?Libraries $libraries = null, + ?Templatelayout $templateLayout = null, ?Dynamicget $dynamic = null, ?Loader $loader = null, + ?Javascriptcustomview $javascript = null, ?Csscustomview $css = null, ?Phpcustomview $php = null, + ?Ajaxcustomview $ajax = null, ?Custombuttons $custombuttons = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->event = $event ?: Compiler::_('Event'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->libraries = $libraries ?: Compiler::_('Model.Libraries'); + $this->templateLayout = $templateLayout ?: Compiler::_('Templatelayout.Data'); + $this->dynamic = $dynamic ?: Compiler::_('Dynamicget.Data'); + $this->loader = $loader ?: Compiler::_('Model.Loader'); + $this->javascript = $javascript ?: Compiler::_('Model.Javascriptcustomview'); + $this->css = $css ?: Compiler::_('Model.Csscustomview'); + $this->php = $php ?: Compiler::_('Model.Phpcustomview'); + $this->ajax = $ajax ?: Compiler::_('Model.Ajaxcustomview'); + $this->custombuttons = $custombuttons ?: Compiler::_('Model.Custombuttons'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get all Custom View Data + * + * @param int $id The view ID + * @param string $table The view table + * + * @return object|null The view data + * @since 3.2.0 + */ + public function get(int $id, string $table = 'site_view'): ?object + { + if (!isset($this->data[$id . $table])) + { + // Create a new query object. + $query = $this->db->getQuery(true); + + $query->select('a.*'); + $query->from('#__componentbuilder_' . $table . ' AS a'); + $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); + + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + + // Trigger Event: jcb_ce_onBeforeQueryCustomViewData + $this->event->trigger( + 'jcb_ce_onBeforeQueryCustomViewData', + array(&$component_context, &$id, &$table, &$query, &$this->db) + ); + + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + + // Load the results as a list of stdClass objects (see later for more options on retrieving data). + $item = $this->db->loadObject(); + + // fix alias to use in code + $item->code = Unique::code( + StringHelper::safe($item->codename), $this->config->build_target + ); + $item->Code = StringHelper::safe($item->code, 'F'); + $item->CODE = StringHelper::safe($item->code, 'U'); + + // Trigger Event: jcb_ce_onBeforeModelCustomViewData + $this->event->trigger( + 'jcb_ce_onBeforeModelCustomViewData', + array(&$component_context, &$item, &$id, &$table) + ); + + // set GUI mapper + $guiMapper = [ + 'table' => $table, + 'id' => (int) $id, + 'field' => 'default', + 'type' => 'html' + ]; + + // set the default data + $item->default = $this->gui->set( + $this->customcode->update(base64_decode((string) $item->default)), + $guiMapper + ); + + // load context if not set + if (!isset($item->context) + || !StringHelper::check( + $item->context + )) + { + $item->context = $item->code; + } + else + { + // always make sure context is a safe string + $item->context = StringHelper::safe($item->context); + } + + // set the libraries + $this->libraries->set($item->code, $item); + + // setup template and layout data + $this->templateLayout->set($item->default, $item->code); + + // set uikit version 2 + $this->loader->uikit($item->code, $item->default); + + // auto loaders + $this->loader->set($item->code, $item->default); + + // set the main get data + $main_get = $this->dynamic->get( + array($item->main_get), $item->code, $item->context + ); + $item->main_get = ArrayHelper::check($main_get) ? $main_get[0] : null; + + // set the custom_get data + $item->custom_get = (isset($item->custom_get) + && JsonHelper::check($item->custom_get)) + ? json_decode((string) $item->custom_get, true) : null; + + if (ArrayHelper::check($item->custom_get)) + { + $item->custom_get = $this->dynamic->get( + $item->custom_get, $item->code, $item->context + ); + } + + // set php scripts + $this->php->set($item, $table); + + // set javascript scripts + $this->javascript->set($item, $table); + + // set css scripts + $this->css->set($item); + + // set Ajax for this view + $this->ajax->set($item, $table); + + // set the custom buttons + $this->custombuttons->set($item, $table); + + // Trigger Event: jcb_ce_onAfterModelCustomViewData + $this->event->trigger( + 'jcb_ce_onAfterModelCustomViewData', + array(&$component_context, &$item) + ); + + // set the found data + $this->data[$id . $table] = $item; + } + + // return the found data + return $this->data[$id . $table]; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customview/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customview/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customview/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/Data.php new file mode 100644 index 000000000..1d269f767 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/Data.php @@ -0,0 +1,324 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Dynamicget; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Model\Dynamicget; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Dynamic Get Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'dynamic_get', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Event + * + * @var EventInterface + * @since 3.2.0 + */ + protected EventInterface $event; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Dynamicget Model + * + * @var Dynamicget + * @since 3.2.0 + */ + protected Dynamicget $dynamic; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param EventInterface|null $event The compiler event api object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Dispenser|null $dispenser The compiler customcode dispenser object. + * @param Gui|null $gui The compiler customcode gui. + * @param Dynamicget|null $dynamic The compiler dynamicget modeller object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Registry $registry = null, + ?EventInterface $event = null, ?Customcode $customcode = null, + ?Dispenser $dispenser = null, ?Gui $gui = null, + ?Dynamicget $dynamic = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->event = $event ?: Compiler::_('Event'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->dynamic = $dynamic ?: Compiler::_('Model.Dynamicget'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Dynamic Get Data + * + * @param array $ids The ids of the dynamic get + * @param string $view_code The view code name + * @param string $context The context for events + * + * @return array|null array of object/s on success + * @since 3.2.0 + */ + public function get(array $ids, string $view_code, string $context): ?array + { + if ($ids === []) + { + return null; + } + + $ids = implode(',', $ids); + + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + + // Create a new query object. + $query = $this->db->getQuery(true); + $query->select('a.*'); + $query->from('#__componentbuilder_dynamic_get AS a'); + $query->where('a.id IN (' . $ids . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + if ($this->db->getNumRows()) + { + $results = $this->db->loadObjectList(); + + foreach ($results as $_nr => &$result) + { + // Trigger Event: jcb_ce_onBeforeModelDynamicGetData + $this->event->trigger( + 'jcb_ce_onBeforeModelDynamicGetData', + array(&$component_context, &$result, &$result->id, &$view_code, &$context) + ); + + // set GUI mapper id + $this->guiMapper['id'] = (int) $result->id; + + // add calculations if set + if ($result->addcalculation == 1 + && StringHelper::check( + $result->php_calculation + )) + { + // set GUI mapper field + $guiMapper['field'] = 'php_calculation'; + $result->php_calculation = $this->gui->set( + $this->customcode->update( + base64_decode((string) $result->php_calculation) + ), + $this->guiMapper + ); + } + + // setup the router parse + if (isset($result->add_php_router_parse) + && $result->add_php_router_parse == 1 + && isset($result->php_router_parse) + && StringHelper::check( + $result->php_router_parse + )) + { + // set GUI mapper field + $this->guiMapper['field'] = 'php_router_parse'; + $result->php_router_parse = $this->gui->set( + $this->customcode->update( + base64_decode((string) $result->php_router_parse) + ), + $this->guiMapper + ); + } + else + { + $result->add_php_router_parse = 0; + } + + // The array of the php scripts that should be added to the script builder + $phpSripts = [ + 'php_before_getitem', + 'php_after_getitem', + 'php_before_getitems', + 'php_after_getitems', + 'php_getlistquery' + ]; + + // load the php scripts + foreach ($phpSripts as $script) + { + // add php script to the script builder + if (isset($result->{'add_' . $script}) + && $result->{'add_' . $script} == 1 + && isset($result->{$script}) + && StringHelper::check( + $result->{$script} + )) + { + // move all main gets out to the custom script builder + if ($result->gettype <= 2) + { + // set GUI mapper field + $this->guiMapper['field'] = $script; + $this->guiMapper['prefix'] = PHP_EOL . PHP_EOL; + $this->dispenser->set( + $result->{$script}, + $this->config->build_target . '_' . $script, + $view_code, + null, + $this->guiMapper, + true, + true, + true + ); + unset($this->guiMapper['prefix']); + // remove from local item + unset($result->{$script}); + unset($result->{'add_' . $script}); + } + else + { + // set GUI mapper field + $this->guiMapper['field'] = $script; + $this->guiMapper['prefix'] = PHP_EOL; + // only for custom gets + $result->{$script} = $this->gui->set( + $this->customcode->update( + base64_decode((string) $result->{$script}) + ), + $this->guiMapper + ); + unset($this->guiMapper['prefix']); + } + } + else + { + // remove from local item + unset($result->{$script}); + unset($result->{'add_' . $script}); + } + } + + // set the getmethod code name + $result->key = StringHelper::safe( + $view_code . ' ' . $result->name . ' ' . $result->id + ); + + // set the dynamic get + $this->dynamic->set($result, $view_code, $context); + + // load the events if any is set + if ($result->gettype == 1 + && JsonHelper::check( + $result->plugin_events + )) + { + $result->plugin_events = json_decode( + (string) $result->plugin_events, true + ); + } + else + { + $result->plugin_events = ''; + } + + // Trigger Event: jcb_ce_onAfterModelDynamicGetData + $this->event->trigger( + 'jcb_ce_onAfterModelDynamicGetData', + array(&$component_context, &$result, &$result->id, &$view_code, &$context) + ); + } + + return $results; + } + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/Selection.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/Selection.php new file mode 100644 index 000000000..f2153ec0d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/Selection.php @@ -0,0 +1,288 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Dynamicget; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\GetAsLookup; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFields; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\Component\Helper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Dynamic Get Selection Class + * + * @since 3.2.0 + */ +class Selection +{ + /** + * Admin view table names + * + * @var array + * @since 3.2.0 + */ + protected array $name; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The GetAsLookup Class. + * + * @var GetAsLookup + * @since 3.2.0 + */ + protected GetAsLookup $getaslookup; + + /** + * The SiteFields Class. + * + * @var SiteFields + * @since 3.2.0 + */ + protected SiteFields $sitefields; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param GetAsLookup $getaslookup The GetAsLookup Class. + * @param SiteFields $sitefields The SiteFields Class. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(Config $config, GetAsLookup $getaslookup, SiteFields $sitefields, + ?\JDatabaseDriver $db = null) + { + $this->config = $config; + $this->getaslookup = $getaslookup; + $this->sitefields = $sitefields; + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Data Selection of the dynamic get + * + * @param string $methodKey The method unique key + * @param string $viewCode The code name of the view + * @param string $string The data string + * @param string $asset The asset in question + * @param string $as The as string + * @param string $type The target type (db||view) + * @param int|null $rowType The row type + * + * @return array|null the select query + * @since 3.2.0 + */ + public function get(string $methodKey, string $viewCode, + string $string, string $asset, string $as, string $type, ?int $rowType = null): ?array + { + if (StringHelper::check($string)) + { + if ('db' === $type) + { + $table = '#__' . $asset; + $queryName = $asset; + $view = ''; + } + elseif ('view' === $type) + { + $view = $this->name($asset); + $table = '#__' . $this->config->component_code_name . '_' . $view; + $queryName = $view; + } + else + { + return null; + } + + // just get all values from table if * is found + if ($string === '*' || strpos($string, '*') !== false) + { + if ($type == 'view') + { + // TODO move getViewTableColumns to its own class + $_string = Helper::_('getViewTableColumns', + [$asset, $as, $rowType] + ); + } + else + { + // TODO move getDbTableColumns to its own class + $_string = Helper::_('getDbTableColumns', + [$asset, $as, $rowType] + ); + } + + // get only selected values + $lines = explode(PHP_EOL, (string) $_string); + + // make sure to set the string to * + $string = '*'; + } + else + { + // get only selected values + $lines = explode(PHP_EOL, $string); + } + + // only continue if lines are available + if (ArrayHelper::check($lines)) + { + $gets = []; + $keys = []; + + // first load all options + foreach ($lines as $line) + { + if (strpos($line, 'AS') !== false) + { + $lineArray = explode("AS", $line); + } + elseif (strpos($line, 'as') !== false) + { + $lineArray = explode("as", $line); + } + else + { + $lineArray = array($line, null); + } + + // set the get and key + $get = trim($lineArray[0]); + $key = trim($lineArray[1]); + + // only add the view (we must adapt this) + if ($this->getaslookup->exists($methodKey . '.' . $get) + && 'a' != $as + && is_numeric($rowType) && 1 == $rowType + && 'view' === $type + && strpos('#' . $key, '#' . $view . '_') === false) + { + // this is a problem (TODO) since we may want to not add the view name. + $key = $view . '_' . trim($key); + } + + // continue only if we have get + if (StringHelper::check($get)) + { + $gets[] = $this->db->quote($get); + if (StringHelper::check($key)) + { + $this->getaslookup->set($methodKey . '.' . $get, $key); + } + else + { + $key = str_replace( + $as . '.', '', $get + ); + + $this->getaslookup->set($methodKey . '.' . $get, $key); + } + + // set the keys + $keys[] = $this->db->quote( + $key + ); + + // make sure we have the view name + if (StringHelper::check($view)) + { + // prep the field name + $field = str_replace($as . '.', '', $get); + // load to the site fields memory bucket + $this->sitefields->set($view . '.' . $field . '.' . $methodKey . '___' . $as, + ['site' => $viewCode, 'get' => $get, 'as' => $as, 'key' => $key] + ); + } + } + } + + if (ArrayHelper::check($gets) + && ArrayHelper::check($keys)) + { + // single joined selection needs the prefix to the values to avoid conflict in the names + // so we must still add then AS + if ($string == '*' && (is_null($rowType) || 1 != $rowType)) + { + $querySelect = "\$query->select('" . $as . ".*');"; + } + else + { + $querySelect = '$query->select($db->quoteName(' + . PHP_EOL . Indent::_(3) . 'array(' . implode( + ',', $gets + ) . '),' . PHP_EOL . Indent::_(3) . 'array(' + . implode(',', $keys) . ')));'; + } + $queryFrom = '$db->quoteName(' . $this->db->quote($table) + . ', ' . $this->db->quote($as) . ')'; + + // return the select query + return [ + 'select' => $querySelect, + 'from' => $queryFrom, + 'name' => $queryName, + 'table' => $table, + 'type' => $type, + 'select_gets' => $gets, + 'select_keys' => $keys + ]; + } + } + } + + return null; + } + + /** + * Get the Admin view table name + * + * @param int $id The item id to add + * + * @return string the admin view code name + * @since 3.2.0 + */ + protected function name(int $id): string + { + // get name if not set + if (!isset($this->name[$id])) + { + $this->name[$id] = StringHelper::safe( + GetHelper::var('admin_view', $id, 'id', 'name_single') + ); + } + + return $this->name[$id] ?? 'error'; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Dynamicget/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Extension/JoomlaThree/InstallScript.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Extension/JoomlaThree/InstallScript.php new file mode 100644 index 000000000..3e34d4130 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Extension/JoomlaThree/InstallScript.php @@ -0,0 +1,371 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Extension\JoomlaThree; + + +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Extension\InstallInterface; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\GetScriptInterface; + + +/** + * Loading the Extension Installation Script Class + * + * @since 3.2.0 + */ +class InstallScript implements GetScriptInterface +{ + /** + * The extension + * + * @var InstallInterface|Object + * @since 3.2.0 + */ + protected object $extension; + + /** + * The methods + * + * @var array + * @since 3.2.0 + */ + protected array $methods = ['php_script', 'php_preflight', 'php_postflight', 'php_method']; + + /** + * The types + * + * @var array + * @since 3.2.0 + */ + protected array $types = ['construct', 'install', 'update', 'uninstall', 'discover_install']; + + /** + * The construct bucket + * + * @var array + * @since 3.2.0 + */ + protected array $construct = []; + + /** + * The install bucket + * + * @var array + * @since 3.2.0 + */ + protected array $install = []; + + /** + * The update bucket + * + * @var array + * @since 3.2.0 + */ + protected array $update = []; + + /** + * The uninstall bucket + * + * @var array + * @since 3.2.0 + */ + protected array $uninstall = []; + + /** + * The preflight switch + * + * @var bool + * @since 3.2.0 + */ + protected bool $preflightActive = false; + + /** + * The preflight bucket + * + * @var array + * @since 3.2.0 + */ + protected array $preflightBucket = ['install' => [], 'uninstall' => [], 'discover_install' => [], 'update' => []]; + + /** + * The postflight switch + * + * @var bool + * @since 3.2.0 + */ + protected bool $postflightActive = false; + + /** + * The postflight bucket + * + * @var array + * @since 3.2.0 + */ + protected array $postflightBucket = ['install' => [], 'uninstall' => [], 'discover_install' => [], 'update' => []]; + + /** + * get install script + * + * @param Object $extension The extension object + * + * @return string + * @since 3.2.0 + */ + public function get(object $extension): string + { + // loop over methods and types + foreach ($this->methods as $method) + { + foreach ($this->types as $type) + { + if (isset($extension->{'add_' . $method . '_' . $type}) + && $extension->{'add_' . $method . '_' . $type} == 1 + && StringHelper::check( + $extension->{$method . '_' . $type} + )) + { + // add to the main methods + if ('php_method' === $method || 'php_script' === $method) + { + $this->{$type}[] = $extension->{$method . '_' . $type}; + } + else + { + // get the flight key + $flight = str_replace('php_', '', (string) $method); + // load the script to our bucket + $this->{$flight . 'Bucket'}[$type][] = $extension->{$method . '_' . $type}; + // show that the method is active + $this->{$flight . 'Active'} = true; + } + } + } + } + + $this->extension = $extension; + + // return the class + return $this->build(); + } + + /** + * build the install class + * + * @return string + * @since 3.2.0 + */ + protected function build(): string + { + // start build + $script = $this->head(); + + // load constructor if set + $script .= $this->construct(); + + // load install method if set + $script .= $this->main('install'); + + // load update method if set + $script .= $this->main('update'); + + // load uninstall method if set + $script .= $this->main('uninstall'); + + // load preflight method if set + $script .= $this->flight('preflight'); + + // load postflight method if set + $script .= $this->flight('postflight'); + + // close the class + $script .= PHP_EOL . '}' . PHP_EOL; + + return $script; + } + + /** + * get install script head + * + * @return string + * @since 3.2.0 + */ + protected function head(): string + { + // get the extension + $extension = $this->extension; + + // start build + $script = PHP_EOL . '/**'; + $script .= PHP_EOL . ' * ' . $extension->official_name + . ' script file.'; + $script .= PHP_EOL . ' *'; + $script .= PHP_EOL . ' * @package ' . $extension->class_name; + $script .= PHP_EOL . ' */'; + $script .= PHP_EOL . 'class ' . $extension->installer_class_name; + $script .= PHP_EOL . '{'; + + return $script; + } + + /** + * get constructor + * + * @return string + * @since 3.2.0 + */ + protected function construct(): string + { + // return empty string if not set + if (!ArrayHelper::check($this->construct)) + { + return ''; + } + + // the __construct script + $script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**'; + $script .= PHP_EOL . Indent::_(1) . ' * Constructor'; + $script .= PHP_EOL . Indent::_(1) . ' *'; + $script .= PHP_EOL . Indent::_(1) + . ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script'; + $script .= PHP_EOL . Indent::_(1) . ' */'; + $script .= PHP_EOL . Indent::_(1) + . 'public function __construct($adapter)'; + $script .= PHP_EOL . Indent::_(1) . '{'; + $script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct); + // close the function + $script .= PHP_EOL . Indent::_(1) . '}'; + + return $script; + } + + /** + * build main methods + * + * @param string $name the method being called + * + * @return string + * @since 3.2.0 + */ + protected function main(string $name): string + { + // return empty string if not set + if (!ArrayHelper::check($this->{$name})) + { + return ''; + } + // load the install method + $script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**'; + $script .= PHP_EOL . Indent::_(1) . " * Called on $name"; + $script .= PHP_EOL . Indent::_(1) . ' *'; + $script .= PHP_EOL . Indent::_(1) + . ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script'; + $script .= PHP_EOL . Indent::_(1) . ' *'; + $script .= PHP_EOL . Indent::_(1) + . ' * @return boolean True on success'; + $script .= PHP_EOL . Indent::_(1) . ' */'; + $script .= PHP_EOL . Indent::_(1) . 'public function ' + . $name . '($adapter)'; + $script .= PHP_EOL . Indent::_(1) . '{'; + $script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->{$name}); + // return true + if ('uninstall' !== $name) + { + $script .= PHP_EOL . Indent::_(2) . 'return true;'; + } + // close the function + $script .= PHP_EOL . Indent::_(1) . '}'; + + return $script; + } + + /** + * build flight methods + * + * @param string $name the method being called + * + * @return string + * @since 3.2.0 + */ + protected function flight(string $name): string + { + // return empty string if not set + if (empty($this->{$name . 'Active'})) + { + return ''; + } + + // the pre/post function types + $script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**'; + $script .= PHP_EOL . Indent::_(1) + . ' * Called before any type of action'; + $script .= PHP_EOL . Indent::_(1) . ' *'; + $script .= PHP_EOL . Indent::_(1) + . ' * @param string $route Which action is happening (install|uninstall|discover_install|update)'; + $script .= PHP_EOL . Indent::_(1) + . ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script'; + $script .= PHP_EOL . Indent::_(1) . ' *'; + $script .= PHP_EOL . Indent::_(1) + . ' * @return boolean True on success'; + $script .= PHP_EOL . Indent::_(1) . ' */'; + $script .= PHP_EOL . Indent::_(1) . 'public function ' + . $name . '($route, $adapter)'; + $script .= PHP_EOL . Indent::_(1) . '{'; + $script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__) + . ' get application'; + $script .= PHP_EOL . Indent::_(2) + . '$app = JFactory::getApplication();' . PHP_EOL; + + // add the default version check (TODO) must make this dynamic + if ('preflight' === $name) + { + $script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__) + .' the default for both install and update'; + $script .= PHP_EOL . Indent::_(2) + . '$jversion = new JVersion();'; + $script .= PHP_EOL . Indent::_(2) + . "if (!\$jversion->isCompatible('3.8.0'))"; + $script .= PHP_EOL . Indent::_(2) . '{'; + $script .= PHP_EOL . Indent::_(3) + . "\$app->enqueueMessage('Please upgrade to at least Joomla! 3.8.0 before continuing!', 'error');"; + $script .= PHP_EOL . Indent::_(3) . 'return false;'; + $script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL; + } + + // now add the scripts + foreach ($this->{$name . 'Bucket'} as $route => $_script) + { + if (ArrayHelper::check($_script)) + { + // set the if and script + $script .= PHP_EOL . Indent::_(2) . "if ('" . $route + . "' === \$route)"; + $script .= PHP_EOL . Indent::_(2) . '{'; + $script .= PHP_EOL . implode( + PHP_EOL . PHP_EOL, $_script + ); + $script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL; + } + } + + // return true + $script .= PHP_EOL . Indent::_(2) . 'return true;'; + // close the function + $script .= PHP_EOL . Indent::_(1) . '}'; + + return $script; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Extension/JoomlaThree/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Extension/JoomlaThree/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Extension/JoomlaThree/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php new file mode 100644 index 000000000..8126e09b6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php @@ -0,0 +1,179 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use Joomla\DI\Container; +use VDM\Joomla\Componentbuilder\Service\Crypt; +use VDM\Joomla\Componentbuilder\Service\Server; +use VDM\Joomla\Componentbuilder\Service\Database; +use VDM\Joomla\Componentbuilder\Compiler\Service\Model; +use VDM\Joomla\Componentbuilder\Compiler\Service\Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Service\Event; +use VDM\Joomla\Componentbuilder\Compiler\Service\History; +use VDM\Joomla\Componentbuilder\Compiler\Service\Language; +use VDM\Joomla\Componentbuilder\Compiler\Service\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Service\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Service\Power; +use VDM\Joomla\Componentbuilder\Compiler\Service\Component; +use VDM\Joomla\Componentbuilder\Compiler\Service\Adminview; +use VDM\Joomla\Componentbuilder\Compiler\Service\Library; +use VDM\Joomla\Componentbuilder\Compiler\Service\Customview; +use VDM\Joomla\Componentbuilder\Compiler\Service\Templatelayout; +use VDM\Joomla\Componentbuilder\Compiler\Service\Extension; +use VDM\Joomla\Componentbuilder\Compiler\Service\Field; +use VDM\Joomla\Componentbuilder\Compiler\Service\Joomlamodule; +use VDM\Joomla\Componentbuilder\Compiler\Service\Joomlaplugin; +use VDM\Joomla\Componentbuilder\Compiler\Service\Utilities; +use VDM\Joomla\Componentbuilder\Compiler\Service\Builder; +use VDM\Joomla\Componentbuilder\Compiler\Service\Creator; +use VDM\Joomla\Componentbuilder\Service\Gitea; +use VDM\Joomla\Gitea\Service\Utilities as GiteaUtilities; +use VDM\Joomla\Gitea\Service\Settings as GiteaSettings; +use VDM\Joomla\Gitea\Service\Organization as GiteaOrg; +use VDM\Joomla\Gitea\Service\User as GiteaUser; +use VDM\Joomla\Gitea\Service\Repository as GiteaRepo; +use VDM\Joomla\Gitea\Service\Package as GiteaPackage; +use VDM\Joomla\Gitea\Service\Issue as GiteaIssue; +use VDM\Joomla\Gitea\Service\Notifications as GiteNotifi; +use VDM\Joomla\Gitea\Service\Miscellaneous as GiteaMisc; +use VDM\Joomla\Gitea\Service\Admin as GiteaAdmin; +use VDM\Joomla\Interfaces\FactoryInterface; + + +/** + * Compiler Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Compiler Container + * + * @var Container + * @since 3.2.0 + **/ + protected static ?Container $container = null; + + /** + * Current Joomla Version Being Build + * + * @var int + * @since 3.2.0 + **/ + protected static int $JoomlaVersion; + + /** + * Get any class from the compiler container + * + * @param string $key The container class key + * + * @return mixed + * @since 3.2.0 + */ + public static function _($key) + { + return self::getContainer()->get($key); + } + + /** + * Get array of all keys in container + * + * @return array + * @since 3.2.0 + */ + public static function getKeys(): array + { + return self::getContainer()->getKeys(); + } + + /** + * Get version specific class from the compiler container + * + * @param string $key The container class key + * + * @return mixed + * @since 3.2.0 + */ + public static function _J($key) + { + if (empty(self::$JoomlaVersion)) + { + self::$JoomlaVersion = self::getContainer()->get('Config')->joomla_version; + } + + return self::getContainer()->get('J' . self::$JoomlaVersion . '.' . $key); + } + + /** + * Get the global compiler container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Crypt()) + ->registerServiceProvider(new Server()) + ->registerServiceProvider(new Database()) + ->registerServiceProvider(new Model()) + ->registerServiceProvider(new Compiler()) + ->registerServiceProvider(new Event()) + ->registerServiceProvider(new History()) + ->registerServiceProvider(new Language()) + ->registerServiceProvider(new Placeholder()) + ->registerServiceProvider(new Customcode()) + ->registerServiceProvider(new Power()) + ->registerServiceProvider(new Component()) + ->registerServiceProvider(new Adminview()) + ->registerServiceProvider(new Library()) + ->registerServiceProvider(new Customview()) + ->registerServiceProvider(new Templatelayout()) + ->registerServiceProvider(new Extension()) + ->registerServiceProvider(new Field()) + ->registerServiceProvider(new Joomlamodule()) + ->registerServiceProvider(new Joomlaplugin()) + ->registerServiceProvider(new Utilities()) + ->registerServiceProvider(new Builder()) + ->registerServiceProvider(new Creator()) + ->registerServiceProvider(new Gitea()) + ->registerServiceProvider(new GiteaUtilities()) + ->registerServiceProvider(new GiteaSettings()) + ->registerServiceProvider(new GiteaOrg()) + ->registerServiceProvider(new GiteaUser()) + ->registerServiceProvider(new GiteaRepo()) + ->registerServiceProvider(new GiteaPackage()) + ->registerServiceProvider(new GiteaIssue()) + ->registerServiceProvider(new GiteNotifi()) + ->registerServiceProvider(new GiteaMisc()) + ->registerServiceProvider(new GiteaAdmin()); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field.php new file mode 100644 index 000000000..313372995 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field.php @@ -0,0 +1,142 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Field\Data; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name; +use VDM\Joomla\Componentbuilder\Compiler\Field\TypeName; +use VDM\Joomla\Componentbuilder\Compiler\Field\UniqueName; + + +/** + * Compiler Field + * + * @since 3.2.0 + */ +class Field +{ + /** + * Compiler Field Data + * + * @var Data + * @since 3.2.0 + **/ + protected Data $data; + + /** + * Compiler Field Name + * + * @var Name + * @since 3.2.0 + **/ + protected Name $name; + + /** + * Compiler Field Type Name + * + * @var TypeName + * @since 3.2.0 + **/ + protected TypeName $typeName; + + /** + * Compiler Field Unique Name + * + * @var UniqueName + * @since 3.2.0 + **/ + protected UniqueName $uniqueName; + + /** + * Constructor + * + * @param Data|null $data The compiler field data object. + * @param Name|null $name The compiler field name object. + * @param TypeName|null $typeName The compiler field type name object. + * @param UniqueName|null $uniqueName The compiler field unique name object. + * + * @since 3.2.0 + */ + public function __construct(?Data $data = null, ?Name $name = null, ?TypeName $typeName = null, ?UniqueName $uniqueName = null) + { + $this->data = $data ?: Compiler::_('Field.Data'); + $this->name = $name ?: Compiler::_('Field.Name'); + $this->typeName = $typeName ?: Compiler::_('Field.Type.Name'); + $this->uniqueName = $uniqueName ?: Compiler::_('Field.Unique.Name'); + } + + /** + * set Field details + * + * @param array $field The field array. + * @param string|null $singleViewName The single view name. + * @param string|null $listViewName The list view name. + * @param string $amicably The peaceful resolve. + * + * @return void + * @since 3.2.0 + */ + public function set(array &$field, ?string $singleViewName = null, ?string $listViewName = null, string $amicably = '') + { + // set hash + static $hash = 123467890; + + // load hash if not found + if (!isset($field['hash'])) + { + $field['hash'] = \md5($field['field'] . $hash); + // increment hash + $hash++; + } + + // set the settings + if (!isset($field['settings'])) + { + $field['settings'] = $this->data->get( + $field['field'], $singleViewName, $listViewName + ); + } + + // set real field name + if (!isset($field['base_name'])) + { + $field['base_name'] = $this->name->get($field); + } + + // set code name for field type + if (!isset($field['type_name'])) + { + $field['type_name'] = $this->typeName->get($field); + } + + // check if value is array + if (isset($field['permission']) + && !ArrayHelper::check($field['permission']) + && is_numeric($field['permission']) && $field['permission'] > 0) + { + $field['permission'] = array($field['permission']); + } + + // set unique name keeper + if ($listViewName) + { + $this->uniqueName->set( + $field['base_name'], $listViewName . $amicably + ); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Attributes.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Attributes.php new file mode 100644 index 000000000..f0df3f1a0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Attributes.php @@ -0,0 +1,1160 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListFieldClass; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DoNotEscape; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups as FieldGroups; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\Base64Helper; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\FieldHelper as UtilitiesFieldHelper; + + +/** + * Compiler Field Attributes + * + * @since 3.2.0 + */ +final class Attributes +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Registry Class. + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * The ListFieldClass Class. + * + * @var ListFieldClass + * @since 3.2.0 + */ + protected ListFieldClass $listfieldclass; + + /** + * The DoNotEscape Class. + * + * @var DoNotEscape + * @since 3.2.0 + */ + protected DoNotEscape $donotescape; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Customcode Class. + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Groups Class. + * + * @var FieldGroups + * @since 3.2.0 + */ + protected FieldGroups $fieldgroups; + + /** + * Title Switch + * + * @var int + * @since 3.2.0 + */ + private int $title; + + /** + * Alias Switch + * + * @var int + * @since 3.2.0 + */ + private int $alias; + + /** + * Field Properties + * + * @var array + * @since 3.2.0 + */ + private array $properties; + + /** + * PHP Tracking + * + * @var array + * @since 3.2.0 + */ + private array $php; + + /** + * Field attributes + * + * @var array + * @since 3.2.0 + */ + private array $attributes; + + /** + * Field custom switch + * + * @var bool + * @since 3.2.0 + */ + private bool $custom; + + /** + * Field Custom Label + * + * @var string + * @since 3.2.0 + */ + private string $customLabel; + + /** + * Field readonly switch + * + * @var bool + * @since 3.2.0 + */ + private bool $readonly; + + /** + * Field View Type + * + * @var int + * @since 3.2.0 + */ + private int $viewType; + + /** + * Field Name + * + * @var string + * @since 3.2.0 + */ + private string $name; + + /** + * Field Type Name + * + * @var string + * @since 3.2.0 + */ + private string $typeName; + + /** + * Field Multiple Switch + * + * @var bool + * @since 3.2.0 + */ + private bool $multiple; + + /** + * Field Name Language Label + * + * @var string + * @since 3.2.0 + */ + private string $langLabel; + + /** + * View Language String + * + * @var string + * @since 3.2.0 + */ + private string $langView; + + /** + * View List Code + * + * @var string + * @since 3.2.0 + */ + private string $nameListCode; + + /** + * View Single Code + * + * @var string + * @since 3.2.0 + */ + private string $nameSingleCode; + + /** + * Field Placeholders + * + * @var array + * @since 3.2.0 + */ + private array $placeholders; + + /** + * Repeatable Switch + * + * @var bool + * @since 3.2.0 + */ + private bool $repeatable; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Registry $registry The Registry Class. + * @param ListFieldClass $listfieldclass The ListFieldClass Class. + * @param DoNotEscape $donotescape The DoNotEscape Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Customcode $customcode The Customcode Class. + * @param Language $language The Language Class. + * @param FieldGroups $fieldgroups The Groups Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Registry $registry, ListFieldClass $listfieldclass, DoNotEscape $donotescape, Placeholder $placeholder, + Customcode $customcode, Language $language, FieldGroups $fieldgroups) + { + $this->config = $config; + $this->registry = $registry; + $this->listfieldclass = $listfieldclass; + $this->donotescape = $donotescape; + $this->placeholder = $placeholder; + $this->customcode = $customcode; + $this->language = $language; + $this->fieldgroups = $fieldgroups; + } + + /** + * set field attributes + * + * @param array $field The field data + * @param int $viewType The view type + * @param string $name The field name + * @param string $typeName The field type + * @param bool $multiple The switch to set multiple selection option + * @param string $langLabel The language string for field label + * @param string $langView The language string of the view + * @param string $nameListCode The list view name + * @param string $nameSingleCode The single view name + * @param array $placeholders The place holder and replace values + * @param bool $repeatable The repeatable field switch + * + * @return array The field attributes + * @since 3.2.0 + */ + public function set( + array $field, int $viewType, string $name, string $typeName, + bool &$multiple, string &$langLabel, string $langView, string $nameListCode, + string $nameSingleCode, array $placeholders, bool $repeatable = false + ): array + { + if (!$this->setSettings($field)) + { + return []; + } + + // initialise the empty attributes and other global values + $this->initialise($viewType, $name, $typeName, $multiple, $langLabel, + $langView, $nameListCode, $nameSingleCode, $placeholders, $repeatable); + + if (!$this->setProperties()) + { + return $this->attributes; + } + + // set the attributes + $this->setAttributes(); + + // update global ref passed value + $multiple = $this->multiple; + $langLabel = $this->langLabel; + + return $this->attributes; + } + + /** + * set field settings + * + * @param array $field The field data + * + * @return bool true if settings was set + * @since 3.2.0 + */ + private function setSettings(array $field): bool + { + if (isset($field['settings'])) + { + $this->settings = $field['settings']; + $this->alias = $field['alias'] ?? 0; + $this->title = $field['title'] ?? 0; + + return true; + } + + return false; + } + + /** + * set field properties + * + * @return bool true if settings was set + * @since 3.2.0 + */ + private function setProperties(): bool + { + if (isset($this->settings->properties) && ArrayHelper::check($this->settings->properties)) + { + $this->properties = $this->settings->properties; + + return true; + } + + return false; + } + + /** + * Set the attributes with properties + * + * @return void + * @since 3.2.0 + */ + private function setAttributes(): void + { + foreach ($this->properties as $property) + { + $name = $property['name'] ?? 'error'; + $example = $property['example'] ?? 'error'; + $translatable = $property['translatable'] ?? 0; + $mandatory = $property['mandatory'] ?? 0; + + $this->setValue( + $this->modelValue( + $this->getValue($name), + $name, + (int) $translatable + ), + $name, + $example, + (int) $mandatory + ); + } + + $this->setPHP(); + + $this->extraAttributes(); + } + + /** + * Set the extra attributes + * + * @return void + * @since 3.2.0 + */ + private function extraAttributes(): void + { + // do some nice twigs beyond the default + if (isset($this->attributes['name'])) + { + // check if we have class value for the list view of this field + $listclass = GetHelper::between( + $this->settings->xml, 'listclass="', '"' + ); + if (StringHelper::check($listclass)) + { + $this->listfieldclass->set($this->nameListCode . '.' . $this->attributes['name'], $listclass); + } + + // check if we find reason to remove this field from being escaped + $escaped = GetHelper::between( + $this->settings->xml, 'escape="', '"' + ); + if (StringHelper::check($escaped)) + { + $this->donotescape->set($this->nameListCode . '.' . + $this->attributes['name'], true); + } + + // check if we have display switch for dynamic placement + $display = GetHelper::between( + $this->settings->xml, 'display="', '"' + ); + if (StringHelper::check($display)) + { + $this->attributes['display'] = $display; + } + + // make sure validation is set if found (even it not part of field properties) + if (!isset($this->attributes['validate'])) + { + // check if we have validate (validation rule set) + $validationRule = GetHelper::between( + $this->settings->xml, 'validate="', '"' + ); + if (StringHelper::check($validationRule)) + { + $this->attributes['validate'] + = StringHelper::safe( + $validationRule + ); + } + } + + // make sure ID is always readonly + if ($this->attributes['name'] === 'id' && !$this->readonly) + { + $this->attributes['readonly'] = 'true'; + } + } + } + + /** + * Get XML value + * + * @param string $name The property name + * + * @return string|null The property value + * @since 3.2.0 + */ + private function getValue(string $name): ?string + { + if ($name === 'type') + { + return $this->getType(); + } + + if ($name === 'name') + { + return $this->getName(); + } + + if ($name === 'validate') + { + return $this->getValidation(); + } + + if (in_array($name, ['extension', 'directory', 'formsource'])) + { + return $this->getXmlValue($name); + } + + if (strpos((string) $name, 'type_php') !== false && $this->custom) + { + return $this->getTypePHP($name); + } + + if ($name === 'prime_php' && $this->custom) + { + return $this->getPrimePHP($name); + } + + if ($name === 'extends' && $this->custom) + { + return $this->getExtends(); + } + + if ($name === 'view' && $this->custom) + { + return $this->getView(); + } + + if ($name === 'views' && $this->custom) + { + return $this->getViews(); + } + + if ($name === 'component' && $this->custom) + { + return $this->getComponent(); + } + + if ($name === 'table' && $this->custom) + { + return $this->getTable(); + } + + if ($name === 'value_field' && $this->custom) + { + return $this->getValueField(); + } + + if ($name === 'key_field' && $this->custom) + { + return $this->getKeyField(); + } + + if ($name === 'button' && $this->repeatable && $this->custom) + { + return $this->removeButtonRepeatable(); + } + + if ($name === 'button' && $this->custom) + { + return $this->getButton(); + } + + if ($name === 'required' && 'repeatable' === $this->typeName) + { + return $this->removeRequired(); + } + + if ($this->viewType == 2 && in_array($name, ['readonly', 'disabled'])) + { + return $this->setReadonly($name); + } + + if ($name === 'multiple') + { + return $this->getMultiple($name); + } + + if ($name === 'class' && in_array($this->typeName, ['note', 'spacer'])) + { + return $this->getClass(); + } + + // Default action if no condition is met + return $this->getXmlValue($name); + } + + /** + * Model the found value + * + * @param string|null $value The property value + * @param string $name The property name + * @param int $translatable Switch to set translation + * + * @return string|null The property value + * @since 3.2.0 + */ + private function modelValue(?string $value, string $name, int $translatable): ?string + { + // check if translatable + if ($value !== null && StringHelper::check($value) + && $translatable == 1) + { + // update label if field use multiple times + if ($name === 'label') + { + if (isset($this->attributes['name']) + && $this->registry->get("unique.names." . $this->nameListCode . ".names." . $this->attributes['name']) !== null) + { + $value .= ' (' + . StringHelper::safe( + $this->registry->get("unique.names." . $this->nameListCode . ".names." . $this->attributes['name']) + ) . ')'; + } + } + + // replace placeholders + $value = $this->placeholder->update( + $value, $this->placeholders + ); + + // insure custom labels don't get messed up + if ($this->custom) + { + $this->customLabel = $value; + } + + // set lang key + $lang_value = $this->langView . '_' + . FieldHelper::safe( + $this->name . ' ' . $name, true + ); + + // add to lang array + $this->language->set($this->config->lang_target, $lang_value, $value); + + // use lang value + $value = $lang_value; + } + elseif ($this->alias && $translatable == 1) + { + if ($name === 'label') + { + $value = 'JFIELD_ALIAS_LABEL'; + } + elseif ($name === 'description') + { + $value = 'JFIELD_ALIAS_DESC'; + } + elseif ($name === 'hint') + { + $value = 'JFIELD_ALIAS_PLACEHOLDER'; + } + } + elseif ($this->title && $translatable == 1) + { + if ($name === 'label') + { + $value = 'JGLOBAL_TITLE'; + } + } + + return $value; + } + + /** + * set the found value + * + * @param string|null $value The property value + * @param string $name The property name + * @param string $example The example value + * @param int $mandatory The mandatory switch + * + * @return void + * @since 3.2.0 + */ + private function setValue(?string $value, string $name, string $example, int $mandatory): void + { + // only load value if found or is mandatory + if (($value !== null && StringHelper::check($value)) + || ($mandatory == 1 && !$this->custom)) + { + // make sure mandatory fields are added + if ($value === null || !StringHelper::check($value)) + { + $value = $example; + } + + // load to langBuilder down the line + if ($name === 'label') + { + if ($this->custom) + { + $this->attributes['custom']['label'] = $this->customLabel ?? 'error'; + } + + $this->langLabel = $value; + } + + // now set the value + $this->attributes[$name] = $value; + } + // validate that the default field is set + elseif ($name === 'default' + && ($xmlValidateValue = GetHelper::between( + $this->settings->xml, 'default="', '"', 'none-set' + )) !== 'none-set') + { + // we must allow empty defaults + $this->attributes['default'] = $value; + } + } + + /** + * Set PHP if needed + * + * @return void + * @since 3.2.0 + */ + private function setPHP(): void + { + // check if all php is loaded using the tracker + if (ArrayHelper::check($this->php)) + { + // little search validation + $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; + foreach ($this->php as $search_key => $php_key) + { + // we must search for more code in the xml just encase + foreach (range(2, 30) as $php_line) + { + $get_ = $search_key . '_' . $php_line; + if (!isset($this->attributes['custom'][$php_key][$php_line]) + && ($value = UtilitiesFieldHelper::getValue( + $this->settings->xml, $get_, $confirmation + )) !== $confirmation) + { + $this->attributes['custom'][$php_key][$php_line] + = $this->customcode->update( + Base64Helper::open($value) + ); + } + } + } + } + } + + /** + * get an xml value (default) + * + * @param string $name The property name + * + * @return string|null + * @since 3.2.0 + */ + private function getXmlValue(string $name): ?string + { + // get value & replace the placeholders + return $this->placeholder->update( + GetHelper::between( + $this->settings->xml, $name . '="', '"' + ), $this->placeholders + ); + } + + /** + * get type value + * + * @return string + * @since 3.2.0 + */ + private function getType(): string + { + // add to custom if it is custom + if ($this->custom) + { + // set the type just to make sure. + $this->attributes['custom']['type'] = $this->typeName; + } + + return $this->typeName; + } + + /** + * get name value + * + * @return string + * @since 3.2.0 + */ + private function getName(): string + { + // get the actual field name + return $this->placeholder->update($this->name, $this->placeholders); + } + + /** + * get validation value + * + * @return string|null + * @since 3.2.0 + */ + private function getValidation(): ?string + { + // check if we have validate (validation rule set) + $value = GetHelper::between( + $this->settings->xml, 'validate="', '"' + ); + + if (StringHelper::check($value)) + { + $value = StringHelper::safe( + $value + ); + } + + return $value; + } + + /** + * get type PHP code + * + * @param string $name The property name + * + * @return string|null + * @since 3.2.0 + */ + private function getTypePHP(string $name): ?string + { + // set the line number + $line = (int) preg_replace( + '/[^0-9]/', '', (string) $name + ); + + // set the type key + $key = (string) trim( + str_replace( + 'type_', '', + preg_replace('/[0-9]+/', '', (string) $name) + ), '_' + ); + + // load the php for the custom field file + $this->attributes['custom'][$key][$line] + = $this->customcode->update( + Base64Helper::open( + GetHelper::between( + $this->settings->xml, + $name . '="', '"' + ) + ) + ); + + // load tracker + $this->php['type_' . $key] = $key; + + return null; + } + + /** + * get prime PHP code + * + * @param string $name The property name + * + * @return string|null + * @since 3.2.0 + */ + private function getPrimePHP(string $name): ?string + { + // load the php for the custom field file + $this->attributes['custom']['prime_php'] + = (int) GetHelper::between( + $this->settings->xml, $name . '="', '"' + ); + + return null; + } + + /** + * get extends value + * + * @return string|null + * @since 3.2.0 + */ + private function getExtends(): ?string + { + // load the class that is being extended + $this->attributes['custom']['extends'] + = GetHelper::between( + $this->settings->xml, 'extends="', '"' + ); + + return null; + } + + /** + * get view value + * + * @return string|null + * @since 3.2.0 + */ + private function getView(): ?string + { + // load the view name & replace the placeholders + $this->attributes['custom']['view'] + = StringHelper::safe( + $this->placeholder->update( + GetHelper::between( + $this->settings->xml, 'view="', '"' + ), $this->placeholders + ) + ); + + return null; + } + + /** + * get views value + * + * @return string|null + * @since 3.2.0 + */ + private function getViews(): ?string + { + // load the views name & replace the placeholders + $this->attributes['custom']['views'] + = StringHelper::safe( + $this->placeholder->update( + GetHelper::between( + $this->settings->xml, 'views="', '"' + ), $this->placeholders + ) + ); + + return null; + } + + /** + * get component value + * + * @return string|null + * @since 3.2.0 + */ + private function getComponent(): ?string + { + // load the component name & replace the placeholders + $this->attributes['custom']['component'] + = $this->placeholder->update( + GetHelper::between( + $this->settings->xml, 'component="', '"' + ), $this->placeholders + ); + + return null; + } + + /** + * get table value + * + * @return string|null + * @since 3.2.0 + */ + private function getTable(): ?string + { + // load the main table that is queried & replace the placeholders + $this->attributes['custom']['table'] + = $this->placeholder->update( + GetHelper::between( + $this->settings->xml, 'table="', '"' + ), $this->placeholders + ); + + return null; + } + + /** + * get value field + * + * @return string|null + * @since 3.2.0 + */ + private function getValueField(): ?string + { + // load the text key + $this->attributes['custom']['text'] + = StringHelper::safe( + GetHelper::between( + $this->settings->xml, 'value_field="', '"' + ) + ); + + return null; + } + + /** + * get key field value + * + * @return string|null + * @since 3.2.0 + */ + private function getKeyField(): ?string + { + // load the id key + $this->attributes['custom']['id'] + = StringHelper::safe( + GetHelper::between( + $this->settings->xml, 'key_field="', '"' + ) + ); + + return null; + } + + /** + * remove the button on repeatable + * + * @return string + * @since 3.2.0 + */ + private function removeButtonRepeatable(): string + { + // do not add button + $this->attributes['custom']['add_button'] = 'false'; + + // don't load the button to repeatable + return 'false'; + } + + /** + * get button value + * + * @return string|null + * @since 3.2.0 + */ + private function getButton(): ?string + { + // load the button string value if found + $value = (string) StringHelper::safe( + GetHelper::between( + $this->settings->xml, 'button="', '"' + ) + ); + + // add to custom values + $this->attributes['custom']['add_button'] + = (StringHelper::check($value) + || 1 == $value) ? $value : 'false'; + + return $value; + } + + /** + * remove the required value + * + * @return string + * @since 3.2.0 + */ + private function removeRequired(): string + { + // don't load the required to repeatable field type + return 'false'; + } + + /** + * set the readonly switch + * + * @param string $name The property name + * + * @return string + * @since 3.2.0 + */ + private function setReadonly(string $name): string + { + // trip the switch for readonly + if ($name === 'readonly') + { + $this->readonly = true; + } + + // set read only + return 'true'; + } + + /** + * set the multiple switch + * + * @param string $name The property name + * + * @return string + * @since 3.2.0 + */ + private function getMultiple(string $name): string + { + $value = (string) GetHelper::between( + $this->settings->xml, $name . '="', '"' + ); + + // add the multiple + if ('true' === $value) + { + $this->multiple = true; + } + + return $value; + } + + /** + * get class value + * + * @return string + * @since 3.2.0 + */ + private function getClass(): string + { + $value = GetHelper::between( + $this->settings->xml, 'class="', '"' + ); + + // add the type class + if (StringHelper::check($value)) + { + if (strpos($value, $this->name) === false) + { + $value = $value . ' ' . $this->name; + } + + return $value; + } + + return $this->name; + } + + /** + * Initialise the attributes and other global values + * + * @param int $viewType The view type + * @param string $name The field name + * @param string $typeName The field type + * @param bool $multiple The switch to set multiple selection option + * @param string $langLabel The language string for field label + * @param string $langView The language string of the view + * @param string $nameListCode The list view name + * @param string $nameSingleCode The single view name + * @param array $placeholders The place holder and replace values + * @param bool $repeatable The repeatable field switch + * + * @return void + * @since 3.2.0 + */ + private function initialise(int $viewType, string $name, string $typeName, + bool $multiple, string $langLabel, string $langView, string $nameListCode, + string $nameSingleCode, array $placeholders, bool $repeatable): void + { + $this->attributes = []; + $this->php = []; + $this->custom = false; + $this->readonly = false; + $this->viewType = $viewType; + $this->name = $name; + $this->typeName = $typeName; + $this->multiple = $multiple; + $this->langLabel = $langLabel; + $this->langView = $langView; + $this->nameListCode = $nameListCode; + $this->nameSingleCode = $nameSingleCode; + $this->placeholders = $placeholders; + $this->repeatable = $repeatable; + + // setup Joomla default fields + if (!$this->fieldgroups->check($typeName)) + { + $this->attributes['custom'] = []; + + // is this an own custom field + if (isset($this->settings->own_custom)) + { + $this->attributes['custom']['own_custom'] + = $this->settings->own_custom; + } + $this->custom = true; + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Customcode.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Customcode.php new file mode 100644 index 000000000..b5dc015e1 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Customcode.php @@ -0,0 +1,232 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; + + +/** + * Compiler Field Customcode + * + * @since 3.2.0 + */ +class Customcode +{ + /** + * Tracking the update of fields per/view + * + * @var array + * @since 3.2.0 + */ + protected array $views; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Constructor + * + * @param Dispenser|null $dispenser The compiler customcode dispenser object. + * + * @since 3.2.0 + */ + public function __construct(?Dispenser $dispenser = null) + { + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + } + + /** + * Update field customcode + * + * @param int $id The field id + * @param object $field The field object + * @param string|null $singleViewName The view edit or single name + * @param string|null $listViewName The view list name + * + * @return void + * @since 3.2.0 + */ + public function update(int $id, object &$field, $singleViewName = null, $listViewName = null) + { + // check if we should load scripts for single view + if ($singleViewName && StringHelper::check($singleViewName) + && !isset($this->views[$singleViewName][$id])) + { + // add_javascript_view_footer + if ($field->add_javascript_view_footer == 1 + && StringHelper::check( + $field->javascript_view_footer + )) + { + $convert__ = true; + if (isset($field->javascript_view_footer_decoded) + && $field->javascript_view_footer_decoded) + { + $convert__ = false; + } + $this->dispenser->set( + $field->javascript_view_footer, + 'view_footer', + $singleViewName, + null, + array( + 'table' => 'field', + 'id' => (int) $id, + 'field' => 'javascript_view_footer', + 'type' => 'js', + 'prefix' => PHP_EOL), + $convert__, + $convert__, + true + ); + if (!isset($field->javascript_view_footer_decoded)) + { + $field->javascript_view_footer_decoded + = true; + } + + if (strpos((string) $field->javascript_view_footer, "token") !== false + || strpos((string) $field->javascript_view_footer, "task=ajax") !== false) + { + if (!isset($this->dispenser->hub['token'])) + { + $this->dispenser->hub['token'] = []; + } + if (!isset($this->dispenser->hub['token'][$singleViewName]) + || !$this->dispenser->hub['token'][$singleViewName]) + { + $this->dispenser->hub['token'][$singleViewName] + = true; + } + } + } + + // add_css_view + if ($field->add_css_view == 1) + { + $convert__ = true; + if (isset($field->css_view_decoded) + && $field->css_view_decoded) + { + $convert__ = false; + } + $this->dispenser->set( + $field->css_view, + 'css_view', + $singleViewName, + null, + array('prefix' => PHP_EOL), + $convert__, + $convert__, + true + ); + if (!isset($field->css_view_decoded)) + { + $field->css_view_decoded = true; + } + } + + // add this only once to single view. + $this->views[$singleViewName][$id] = true; + } + + // check if we should load scripts for list views + if ($listViewName && StringHelper::check($listViewName) + && !isset($this->views[$listViewName][$id])) + { + // add_javascript_views_footer + if ($field->add_javascript_views_footer == 1 + && StringHelper::check( + $field->javascript_views_footer + )) + { + $convert__ = true; + if (isset($field->javascript_views_footer_decoded) + && $field->javascript_views_footer_decoded) + { + $convert__ = false; + } + $this->dispenser->set( + $field->javascript_views_footer, + 'views_footer', + $singleViewName, + null, + array( + 'table' => 'field', + 'id' => (int) $id, + 'field' => 'javascript_views_footer', + 'type' => 'js', + 'prefix' => PHP_EOL), + $convert__, + $convert__, + true + ); + if (!isset($field->javascript_views_footer_decoded)) + { + $field->javascript_views_footer_decoded = true; + } + if (strpos((string) $field->javascript_views_footer, "token") !== false + || strpos((string) $field->javascript_views_footer, "task=ajax") !== false) + { + if (!isset($this->dispenser->hub['token'])) + { + $this->dispenser->hub['token'] = []; + } + if (!isset($this->dispenser->hub['token'][$listViewName]) + || !$this->dispenser->hub['token'][$listViewName]) + { + $this->dispenser->hub['token'][$listViewName] + = true; + } + } + } + + // add_css_views + if ($field->add_css_views == 1) + { + $convert__ = true; + if (isset($field->css_views_decoded) + && $field->css_views_decoded) + { + $convert__ = false; + } + $this->dispenser->set( + $field->css_views, + 'css_views', + $singleViewName, + null, + array('prefix' => PHP_EOL), + $convert__, + $convert__, + true + ); + if (!isset($field->css_views_decoded)) + { + $field->css_views_decoded = true; + } + } + + // add this only once to list view. + $this->views[$listViewName][$id] = true; + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Data.php new file mode 100644 index 000000000..bc52a6379 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Data.php @@ -0,0 +1,329 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HistoryInterface; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Field\Customcode as FieldCustomcode; +use VDM\Joomla\Componentbuilder\Compiler\Field\Validation; + + +/** + * Compiler Field Data + * + * @since 3.2.0 + */ +class Data +{ + /** + * Compiler Fields + * + * @var array + * @since 3.2.0 + */ + protected array $fields; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Compiler Event + * + * @var EventInterface + * @since 3.2.0 + */ + protected EventInterface $event; + + /** + * Compiler History + * + * @var HistoryInterface + * @since 3.2.0 + */ + protected HistoryInterface $history; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Field Customcode + * + * @var FieldCustomcode + * @since 3.2.0 + */ + protected FieldCustomcode $fieldCustomcode; + + /** + * Compiler Field Validation + * + * @var Validation + * @since 3.2.0 + */ + protected Validation $validation; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param EventInterface|null $event The compiler event api object. + * @param HistoryInterface|null $history The compiler history object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Customcode|null $customcode The compiler customcode object. + * @param FieldCustomcode|null $fieldCustomcode The field customcode object. + * @param Validation|null $validation The field validation rule object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?EventInterface $event = null, ?HistoryInterface $history = null, + ?Placeholder $placeholder = null, ?Customcode $customcode = null, ?FieldCustomcode $fieldCustomcode = null, + ?Validation $validation = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->event = $event ?: Compiler::_('Event'); + $this->history = $history ?: Compiler::_('History'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->fieldCustomcode = $fieldCustomcode ?: Compiler::_('Field.Customcode'); + $this->validation = $validation ?: Compiler::_('Field.Validation'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get all Field Data + * + * @param int $id The field ID + * @param string|null $singleViewName The view edit or single name + * @param string|null $listViewName The view list name + * + * @return object|null The field data + * @since 3.2.0 + */ + public function get(int $id, ?string $singleViewName = null, ?string $listViewName = null): ?object + { + if ($id > 0 && !isset($this->fields[$id])) + { + // Create a new query object. + $query = $this->db->getQuery(true); + + // Select all the values in the field + $query->select('a.*'); + $query->select( + $this->db->quoteName( + array('c.name', 'c.properties'), + array('type_name', 'properties') + ) + ); + $query->from('#__componentbuilder_field AS a'); + $query->join( + 'LEFT', + $this->db->quoteName('#__componentbuilder_fieldtype', 'c') + . ' ON (' . $this->db->quoteName('a.fieldtype') . ' = ' + . $this->db->quoteName('c.id') . ')' + ); + $query->where( + $this->db->quoteName('a.id') . ' = ' . $this->db->quote($id) + ); + + // TODO we need to update the event signatures + $context = $this->config->component_context; + + // Trigger Event: jcb_ce_onBeforeQueryFieldData + $this->event->trigger( + 'jcb_ce_onBeforeQueryFieldData', + array(&$context, &$id, &$query, &$this->db) + ); + + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // Load the results as a list of stdClass objects (see later for more options on retrieving data). + $field = $this->db->loadObject(); + + // Trigger Event: jcb_ce_onBeforeModelFieldData + $this->event->trigger( + 'jcb_ce_onBeforeModelFieldData', + array(&$context, &$field) + ); + + // adding a fix for the changed name of type to fieldtype + $field->type = $field->fieldtype; + + // load the values form params + $field->xml = $this->customcode->update(json_decode((string) $field->xml)); + + // check if we have validate (validation rule and set it if found) + $this->validation->set($id, $field->xml); + + // load the type values form type params + $field->properties = (isset($field->properties) + && JsonHelper::check($field->properties)) + ? json_decode((string) $field->properties, true) : null; + if (ArrayHelper::check($field->properties)) + { + $field->properties = array_values($field->properties); + } + + // check if we have WHMCS encryption + if (4 == $field->store + && !$this->config->whmcs_encryption) + { + $this->config->whmcs_encryption = true; + } + // check if we have basic encryption + elseif (3 == $field->store + && !$this->config->basic_encryption) + { + $this->config->basic_encryption = true; + } + // check if we have better encryption + elseif (5 == $field->store + && $this->config->medium_encryption) + { + $this->config->medium_encryption = true; + } + // check if we have better encryption + elseif (6 == $field->store + && StringHelper::check( + $field->on_get_model_field + ) + && StringHelper::check( + $field->on_save_model_field + )) + { + // add only if string lenght found + if (StringHelper::check( + $field->initiator_on_save_model + )) + { + $field->initiator_save_key = md5( + (string) $field->initiator_on_save_model + ); + $field->initiator_save = explode( + PHP_EOL, $this->placeholder->update_( + $this->customcode->update( + base64_decode( + (string) $field->initiator_on_save_model + ) + ) + ) + ); + } + if (StringHelper::check( + $field->initiator_on_save_model + )) + { + $field->initiator_get_key = md5( + (string) $field->initiator_on_get_model + ); + $field->initiator_get = explode( + PHP_EOL, $this->placeholder->update_( + $this->customcode->update( + base64_decode( + (string) $field->initiator_on_get_model + ) + ) + ) + ); + } + // set the field modelling + $field->model_field['save'] = explode( + PHP_EOL, $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $field->on_save_model_field) + ) + ) + ); + $field->model_field['get'] = explode( + PHP_EOL, $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $field->on_get_model_field) + ) + ) + ); + // remove the original values + unset( + $field->on_save_model_field, + $field->on_get_model_field, + $field->initiator_on_save_model, + $field->initiator_on_get_model + ); + } + + // get the last used version + $field->history = $this->history->get('field', $id); + + // Trigger Event: jcb_ce_onAfterModelFieldData + $this->event->trigger( + 'jcb_ce_onAfterModelFieldData', + array(&$context, &$field) + ); + + $this->fields[$id] = $field; + } + else + { + return null; + } + } + + if ($id > 0 && isset($this->fields[$id])) + { + // update the customcode of the field + $this->fieldCustomcode->update($id, $this->fields[$id], $singleViewName, $listViewName); + + // return the field + return $this->fields[$id]; + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/DatabaseName.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/DatabaseName.php new file mode 100644 index 000000000..24acdd48e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/DatabaseName.php @@ -0,0 +1,121 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Componentbuilder\Compiler\Builder\Lists; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Compiler Field Database Name + * + * @since 3.2.0 + */ +class DatabaseName +{ + /** + * The Lists Class. + * + * @var Lists + * @since 3.2.0 + */ + protected Lists $lists; + + /** + * The Registry Class. + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Constructor. + * + * @param Lists $lists The Lists Class. + * @param Registry $registry The Registry Class. + * + * @since 3.2.0 + */ + public function __construct(Lists $lists, Registry $registry) + { + $this->lists = $lists; + $this->registry = $registry; + } + + /** + * get the field database name and AS prefix + * + * @param string $nameListCode The list view name + * @param int $fieldId The field ID + * @param string $targetArea The area being targeted + * + * @return string|null + * @since 3.2.0 + */ + public function get(string $nameListCode, int $fieldId, string $targetArea = 'builder.list'): ?string + { + if ($targetArea === 'builder.list') + { + if (($fields = $this->lists->get($nameListCode)) === null) + { + return null; + } + } + elseif (($fields = $this->registry->get("${targetArea}.${nameListCode}")) === null) + { + return null; + } + + if ($fieldId < 0) + { + switch ($fieldId) + { + case -1: + return 'a.id'; + case -2: + return 'a.ordering'; + case -3: + return 'a.published'; + } + } + + foreach ($fields as $field) + { + if ($field['id'] == $fieldId) + { + // now check if this is a category + if ($field['type'] === 'category') + { + return 'c.title'; + } + // set the custom code + elseif (ArrayHelper::check( + $field['custom'] + )) + { + return $field['custom']['db'] . "." + . $field['custom']['text']; + } + else + { + return 'a.' . $field['code']; + } + } + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Groups.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Groups.php new file mode 100644 index 000000000..76e661e7a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Groups.php @@ -0,0 +1,194 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Compiler Field Groups + * + * @since 3.2.0 + */ +final class Groups +{ + /** + * Field Grouping https://docs.joomla.org/Form_field + * + * @var array + * @since 3.2.0 + **/ + protected array $groups = [ + 'default' => [ + 'accesslevel', 'cachehandler', 'calendar', 'captcha', 'category', 'checkbox', 'checkboxes', 'chromestyle', + 'color', 'combo', 'componentlayout', 'contentlanguage', 'contenttype', 'databaseconnection', 'components', + 'editor', 'editors', 'email', 'file', 'file', 'filelist', 'folderlist', 'groupedlist', 'headertag', 'helpsite', 'hidden', 'imagelist', + 'integer', 'language', 'list', 'media', 'menu', 'modal_menu', 'menuitem', 'meter', 'modulelayout', 'moduleorder', 'moduleposition', + 'moduletag', 'note', 'number', 'password', 'plugins', 'predefinedlist', 'radio', 'range', 'repeatable', 'rules', + 'sessionhandler', 'spacer', 'sql', 'subform', 'tag', 'tel', 'templatestyle', 'text', 'textarea', 'timezone', 'url', 'user', 'usergroup' + ], + 'plain' => [ + 'cachehandler', 'calendar', 'checkbox', 'chromestyle', 'color', 'componentlayout', 'contenttype', 'editor', 'editors', 'captcha', + 'email', 'file', 'headertag', 'helpsite', 'hidden', 'integer', 'language', 'media', 'menu', 'modal_menu', 'menuitem', 'meter', 'modulelayout', 'templatestyle', + 'moduleorder', 'moduletag', 'number', 'password', 'range', 'rules', 'tag', 'tel', 'text', 'textarea', 'timezone', 'url', 'user', 'usergroup' + ], + 'option' => [ + 'accesslevel', 'category', 'checkboxes', 'combo', 'contentlanguage', 'databaseconnection', 'components', + 'filelist', 'folderlist', 'imagelist', 'list', 'plugins', 'predefinedlist', 'radio', 'sessionhandler', 'sql', 'groupedlist' + ], + 'text' => [ + 'calendar', 'color', 'editor', 'email', 'number', 'password', 'range', 'tel', 'text', 'textarea', 'url' + ], + 'list' => [ + 'checkbox', 'checkboxes', 'list', 'radio', 'groupedlist', 'combo' + ], + 'dynamic' => [ + 'category', 'file', 'filelist', 'folderlist', 'headertag', 'imagelist', 'integer', 'media', 'meter', 'rules', 'tag', 'timezone', 'user' + ], + 'spacer' => [ + 'note', 'spacer' + ], + 'special' => [ + 'contentlanguage', 'moduleposition', 'plugin', 'repeatable', 'subform' + ], + 'search' => [ + 'editor', 'email', 'tel', 'text', 'textarea', 'url', 'subform' + ] + ]; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + */ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param \JDatabaseDriver|null $db The Database Driver object. + * + * @since 3.2.0 + */ + public function __construct(?\JDatabaseDriver $db = null) + { + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Field Checker + * + * @param string $type The field type + * @param string $option The field grouping + * + * @return bool if the field was found + * @since 3.2.0 + */ + public function check(string $type, string $option = 'default'): bool + { + // now check + if (isset($this->groups[$option]) && in_array($type, $this->groups[$option])) + { + return true; + } + return false; + } + + /** + * get the field types id -> name of a group or groups + * + * @param array $groups The groups + * + * @return array|null ids of the spacer field types + * @since 3.2.0 + */ + public function types(array $groups = []): ?array + { + // make sure we have a group + if (($ids = $this->typesIds($groups)) !== null) + { + // Create a new query object. + $query = $this->db->getQuery(true); + $query->select($this->db->quoteName(array('id', 'name'))); + $query->from($this->db->quoteName('#__componentbuilder_fieldtype')); + $query->where($this->db->quoteName('published') . ' = 1'); + $query->where($this->db->quoteName('id') . ' IN (' . implode(',',$ids) . ')'); + + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + $this->db->execute(); + + if ($this->db->getNumRows()) + { + return $this->db->loadAssocList('id', 'name'); + } + } + + return null; + } + + /** + * get the field types IDs of a group or groups + * + * @param array $groups The groups + * + * @return array|null ids of the spacer field types + * @since 3.2.0 + */ + public function typesIds(array $groups = []): ?array + { + // make sure we have a group + if (ArrayHelper::check($groups)) + { + $merge_groups = []; + foreach ($groups as $group) + { + if (isset($this->groups[$group])) + { + $merge_groups[] = $this->groups[$group]; + } + } + + // make sure we have these types of groups + if (ArrayHelper::check($merge_groups)) + { + // get the database object to use quote + return GetHelper::vars( + 'fieldtype', + (array) array_map(function($name) { + return $this->db->quote(ucfirst($name)); + }, ArrayHelper::merge($merge_groups)), + 'name', + 'id' + ); + } + } + + return null; + } + + /** + * get the spacer IDs + * + * @return array|null ids of the spacer field types + * @since 3.2.0 + */ + public function spacerIds(): ?array + { + return $this->typesIds(['spacer']); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/InputButton.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/InputButton.php new file mode 100644 index 000000000..d8754d2b6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/InputButton.php @@ -0,0 +1,338 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Permission; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; + + +/** + * Compiler Field Input Button + * + * @since 3.2.0 + */ +final class InputButton +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Permission Class. + * + * @var Permission + * @since 3.2.0 + */ + protected Permission $permission; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Permission $permission The Permission Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Placeholder $placeholder, + Permission $permission) + { + $this->config = $config; + $this->placeholder = $placeholder; + $this->permission = $permission; + } + + /** + * get Add Button To List Field Input (getInput tweak) + * + * @param array $fieldData The field custom data + * + * @return string of getInput class on success empty string otherwise + * @since 3.2.0 + */ + public function get(array $fieldData): string + { + // make sure hte view values are set + if (isset($fieldData['add_button']) + && ($fieldData['add_button'] === 'true' + || 1 == $fieldData['add_button']) + && isset($fieldData['view']) + && isset($fieldData['views']) + && StringHelper::check($fieldData['view']) + && StringHelper::check($fieldData['views'])) + { + // set local component + $local_component = "com_" . $this->config->component_code_name; + // check that the component value is set + if (!isset($fieldData['component']) + || !StringHelper::check( + $fieldData['component'] + )) + { + $fieldData['component'] = $local_component; + } + // check that the component has the com_ value in it + if (strpos((string) $fieldData['component'], 'com_') === false + || strpos((string) $fieldData['component'], '=') !== false) + { + $fieldData['component'] = "com_" . $fieldData['component']; + } + // make sure the component is update if # # # or [ [ [ component placeholder is used + if (strpos((string) $fieldData['component'], (string) Placefix::h()) !== false + || strpos((string) $fieldData['component'], (string) Placefix::b()) !== false) // should not be needed... but + { + $fieldData['component'] = $this->placeholder->update_( + $fieldData['component'] + ); + } + // get core permissions + $coreLoad = false; + // add ref tags + $refLoad = true; + // fall back on the field component + $component = $fieldData['component']; + // check if we should add ref tags (since it only works well on local views) + if ($local_component !== $component) + { + // do not add ref tags + $refLoad = false; + } + // start building the add buttons/s + $addButton = array(); + $addButton[] = PHP_EOL . PHP_EOL . Indent::_(1) . "/**"; + $addButton[] = Indent::_(1) . " * Override to add new button"; + $addButton[] = Indent::_(1) . " *"; + $addButton[] = Indent::_(1) + . " * @return string The field input markup."; + $addButton[] = Indent::_(1) . " *"; + $addButton[] = Indent::_(1) . " * @since 3.2"; + $addButton[] = Indent::_(1) . " */"; + $addButton[] = Indent::_(1) . "protected function getInput()"; + $addButton[] = Indent::_(1) . "{"; + $addButton[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " see if we should add buttons"; + $addButton[] = Indent::_(2) + . "\$set_button = \$this->getAttribute('button');"; + $addButton[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " get html"; + $addButton[] = Indent::_(2) . "\$html = parent::getInput();"; + $addButton[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " if true set button"; + $addButton[] = Indent::_(2) . "if (\$set_button === 'true')"; + $addButton[] = Indent::_(2) . "{"; + $addButton[] = Indent::_(3) . "\$button = array();"; + $addButton[] = Indent::_(3) . "\$script = array();"; + $addButton[] = Indent::_(3) + . "\$button_code_name = \$this->getAttribute('name');"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " get the input from url"; + $addButton[] = Indent::_(3) . "\$app = JFactory::getApplication();"; + $addButton[] = Indent::_(3) . "\$jinput = \$app->input;"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " get the view name & id"; + $addButton[] = Indent::_(3) + . "\$values = \$jinput->getArray(array("; + $addButton[] = Indent::_(4) . "'id' => 'int',"; + $addButton[] = Indent::_(4) . "'view' => 'word'"; + $addButton[] = Indent::_(3) . "));"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " check if new item"; + $addButton[] = Indent::_(3) . "\$ref = '';"; + $addButton[] = Indent::_(3) . "\$refJ = '';"; + if ($refLoad) + { + $addButton[] = Indent::_(3) + . "if (!is_null(\$values['id']) && strlen(\$values['view']))"; + $addButton[] = Indent::_(3) . "{"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " only load referral if not new item."; + $addButton[] = Indent::_(4) + . "\$ref = '&ref=' . \$values['view'] . '&refid=' . \$values['id'];"; + $addButton[] = Indent::_(4) + . "\$refJ = '&ref=' . \$values['view'] . '&refid=' . \$values['id'];"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " get the return value."; + $addButton[] = Indent::_(4) + . "\$_uri = (string) JUri::getInstance();"; + $addButton[] = Indent::_(4) + . "\$_return = urlencode(base64_encode(\$_uri));"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " load return value."; + $addButton[] = Indent::_(4) + . "\$ref .= '&return=' . \$_return;"; + $addButton[] = Indent::_(4) + . "\$refJ .= '&return=' . \$_return;"; + $addButton[] = Indent::_(3) . "}"; + } + else + { + $addButton[] = Indent::_(3) + . "if (!is_null(\$values['id']) && strlen(\$values['view']))"; + $addButton[] = Indent::_(3) . "{"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " only load field details if not new item."; + $addButton[] = Indent::_(4) + . "\$ref = '&field=' . \$values['view'] . '&field_id=' . \$values['id'];"; + $addButton[] = Indent::_(4) + . "\$refJ = '&field=' . \$values['view'] . '&field_id=' . \$values['id'];"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " get the return value."; + $addButton[] = Indent::_(4) + . "\$_uri = (string) JUri::getInstance();"; + $addButton[] = Indent::_(4) + . "\$_return = urlencode(base64_encode(\$_uri));"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " load return value."; + $addButton[] = Indent::_(4) + . "\$ref = '&return=' . \$_return;"; + $addButton[] = Indent::_(4) + . "\$refJ = '&return=' . \$_return;"; + $addButton[] = Indent::_(3) . "}"; + } + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " get button label"; + $addButton[] = Indent::_(3) + . "\$button_label = trim(\$button_code_name);"; + $addButton[] = Indent::_(3) + . "\$button_label = preg_replace('/_+/', ' ', \$button_label);"; + $addButton[] = Indent::_(3) + . "\$button_label = preg_replace('/\s+/', ' ', \$button_label);"; + $addButton[] = Indent::_(3) + . "\$button_label = preg_replace(\"/[^A-Za-z ]/\", '', \$button_label);"; + $addButton[] = Indent::_(3) + . "\$button_label = ucfirst(strtolower(\$button_label));"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " get user object"; + $addButton[] = Indent::_(3) . "\$user = JFactory::getUser();"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " only add if user allowed to create " . $fieldData['view']; + // check if the item has permissions. + $addButton[] = Indent::_(3) . "if (\$user->authorise('" + . $this->permission->getGlobal($fieldData['view'], 'core.create') + . "', '" . $component . "') && \$app->isAdmin()) // TODO for now only in admin area."; + $addButton[] = Indent::_(3) . "{"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " build Create button"; + $addButton[] = Indent::_(4) + . "\$button[] = 'config->lang_prefix + . "_CREATE_NEW_S', \$button_label).'\" style=\"border-radius: 0px 4px 4px 0px; padding: 4px 4px 4px 7px;\""; + $addButton[] = Indent::_(5) . "href=\"index.php?option=" + . $fieldData['component'] . "&view=" . $fieldData['view'] + . "&layout=edit'.\$ref.'\" >"; + $addButton[] = Indent::_(5) + . "';"; + $addButton[] = Indent::_(3) . "}"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " only add if user allowed to edit " . $fieldData['view']; + // check if the item has permissions. + $addButton[] = Indent::_(3) . "if (\$user->authorise('" + . $this->permission->getGlobal($fieldData['view'], 'core.edit') + . "', '" . $component . "') && \$app->isAdmin()) // TODO for now only in admin area."; + $addButton[] = Indent::_(3) . "{"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " build edit button"; + $addButton[] = Indent::_(4) + . "\$button[] = 'config->lang_prefix + . "_EDIT_S', \$button_label).'\" style=\"display: none; padding: 4px 4px 4px 7px;\" href=\"#\" >"; + $addButton[] = Indent::_(5) + . "';"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " build script"; + $addButton[] = Indent::_(4) . "\$script[] = \""; + $addButton[] = Indent::_(5) . "jQuery(document).ready(function() {"; + $addButton[] = Indent::_(6) + . "jQuery('#adminForm').on('change', '#jform_\".\$button_code_name.\"',function (e) {"; + $addButton[] = Indent::_(7) . "e.preventDefault();"; + $addButton[] = Indent::_(7) + . "var \".\$button_code_name.\"Value = jQuery('#jform_\".\$button_code_name.\"').val();"; + $addButton[] = Indent::_(7) + . "\".\$button_code_name.\"Button(\".\$button_code_name.\"Value);"; + $addButton[] = Indent::_(6) . "});"; + $addButton[] = Indent::_(6) + . "var \".\$button_code_name.\"Value = jQuery('#jform_\".\$button_code_name.\"').val();"; + $addButton[] = Indent::_(6) + . "\".\$button_code_name.\"Button(\".\$button_code_name.\"Value);"; + $addButton[] = Indent::_(5) . "});"; + $addButton[] = Indent::_(5) + . "function \".\$button_code_name.\"Button(value) {"; + $addButton[] = Indent::_(6) + . "if (value > 0) {"; // TODO not ideal since value may not be an (int) + $addButton[] = Indent::_(7) . "// hide the create button"; + $addButton[] = Indent::_(7) + . "jQuery('#\".\$button_code_name.\"Create').hide();"; + $addButton[] = Indent::_(7) . "// show edit button"; + $addButton[] = Indent::_(7) + . "jQuery('#\".\$button_code_name.\"Edit').show();"; + $addButton[] = Indent::_(7) . "var url = 'index.php?option=" + . $fieldData['component'] . "&view=" . $fieldData['views'] + . "&task=" . $fieldData['view'] + . ".edit&id='+value+'\".\$refJ.\"';"; // TODO this value may not be the ID + $addButton[] = Indent::_(7) + . "jQuery('#\".\$button_code_name.\"Edit').attr('href', url);"; + $addButton[] = Indent::_(6) . "} else {"; + $addButton[] = Indent::_(7) . "// show the create button"; + $addButton[] = Indent::_(7) + . "jQuery('#\".\$button_code_name.\"Create').show();"; + $addButton[] = Indent::_(7) . "// hide edit button"; + $addButton[] = Indent::_(7) + . "jQuery('#\".\$button_code_name.\"Edit').hide();"; + $addButton[] = Indent::_(6) . "}"; + $addButton[] = Indent::_(5) . "}\";"; + $addButton[] = Indent::_(3) . "}"; + $addButton[] = Indent::_(3) . "//" . Line::_(__Line__, __Class__) + . " check if button was created for " . $fieldData['view'] + . " field."; + $addButton[] = Indent::_(3) + . "if (is_array(\$button) && count(\$button) > 0)"; + $addButton[] = Indent::_(3) . "{"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " Load the needed script."; + $addButton[] = Indent::_(4) + . "\$document = JFactory::getDocument();"; + $addButton[] = Indent::_(4) + . "\$document->addScriptDeclaration(implode(' ',\$script));"; + $addButton[] = Indent::_(4) . "//" . Line::_(__Line__, __Class__) + . " return the button attached to input field."; + $addButton[] = Indent::_(4) + . "return '
' .\$html . implode('',\$button).'
';"; + $addButton[] = Indent::_(3) . "}"; + $addButton[] = Indent::_(2) . "}"; + $addButton[] = Indent::_(2) . "return \$html;"; + $addButton[] = Indent::_(1) . "}"; + + return implode(PHP_EOL, $addButton); + } + + return ''; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/JoomlaThree/CoreValidation.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/JoomlaThree/CoreValidation.php new file mode 100644 index 000000000..7583cd684 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/JoomlaThree/CoreValidation.php @@ -0,0 +1,116 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field\JoomlaThree; + + +use Joomla\CMS\Filesystem\Folder; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Field\CoreValidationInterface; + + +/** + * Core Joomla Field Validation Rules + * + * @since 3.2.0 + */ +class CoreValidation implements CoreValidationInterface +{ + /** + * Local Core Joomla Rules + * + * @var array|null + * @since 3.2.0 + **/ + protected ?array $rules = null; + + /** + * Local Core Joomla Rules Path + * + * @var string + * @since 3.2.0 + **/ + protected string $path; + + /** + * Constructor + * + * @since 3.2.0 + */ + public function __construct() + { + // set the path to the form validation rules + $this->path = JPATH_LIBRARIES . '/src/Form/Rule'; + } + + /** + * Get the Array of Existing Validation Rule Names + * + * @param bool $lowercase Switch to set rules lowercase + * + * @return array + * @since 3.2.0 + */ + public function get(bool $lowercase = false): array + { + if (!$this->rules) + { + // check if the path exist + if (!Folder::exists($this->path)) + { + return []; + } + + // we must first store the current working directory + $joomla = getcwd(); + + // go to that folder + chdir($this->path); + + // load all the files in this path + $rules = Folder::files('.', '\.php', true, true); + + // change back to Joomla working directory + chdir($joomla); + + // make sure we have an array + if (!ArrayHelper::check($rules)) + { + return false; + } + + // remove the Rule.php from the name + $this->rules = array_map( + fn($name): string => str_replace(array('./','Rule.php'), '', (string) $name), + $rules + ); + } + + // return rules if found + if (is_array($this->rules)) + { + // check if the names should be all lowercase + if ($lowercase) + { + return array_map( + fn($item): string => strtolower((string) $item), + $this->rules + ); + } + return $this->rules; + } + + // return empty array + return []; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/JoomlaThree/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/JoomlaThree/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/JoomlaThree/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Name.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Name.php new file mode 100644 index 000000000..09e7f9fc8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Name.php @@ -0,0 +1,228 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\String\TypeHelper; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Field\UniqueName; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CategoryOtherName; + + +/** + * Compiler Field Name + * + * @since 3.2.0 + */ +class Name +{ + /** + * Unique Field Names + * + * @var array + * @since 3.2.0 + */ + protected array $unique; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The UniqueName Class. + * + * @var UniqueName + * @since 3.2.0 + */ + protected UniqueName $uniquename; + + /** + * The CategoryOtherName Class. + * + * @var CategoryOtherName + * @since 3.2.0 + */ + protected CategoryOtherName $categoryothername; + + /** + * Constructor. + * + * @param Placeholder $placeholder The Placeholder Class. + * @param UniqueName $uniquename The UniqueName Class. + * @param CategoryOtherName $categoryothername The CategoryOtherName Class. + * + * @since 3.2.0 + */ + public function __construct(Placeholder $placeholder, UniqueName $uniquename, + CategoryOtherName $categoryothername) + { + $this->placeholder = $placeholder; + $this->uniquename = $uniquename; + $this->categoryothername = $categoryothername; + } + + /** + * Get the field's actual name + * + * @param array $field The field array + * @param string|null $listViewName The list view name + * @param string $amicably The peaceful resolve (for fields in subforms in same view :) + * + * @return string Success returns field name + * @since 3.2.0 + */ + public function get(array &$field, ?string $listViewName = null, string $amicably = ''): string + { + // return the unique name if already set + if ($listViewName && StringHelper::check($listViewName) && isset($field['hash']) + && isset($this->unique[$listViewName . $amicably . $field['hash']])) + { + return $this->unique[$listViewName . $amicably . $field['hash']]; + } + + // always make sure we have a field name and type + if (!isset($field['settings']) || !isset($field['settings']->type_name) + || !isset($field['settings']->name)) + { + return 'error'; + } + + // set the type name + $type_name = TypeHelper::safe( + $field['settings']->type_name + ); + + // set the name of the field + $name = FieldHelper::safe($field['settings']->name); + + // check that we have the properties + if (ArrayHelper::check($field['settings']->properties)) + { + foreach ($field['settings']->properties as $property) + { + if ($property['name'] === 'name') + { + // if category then name must be catid (only one per view) + if ($type_name === 'category') + { + // quick check if this is a category linked to view page + $requeSt_id = GetHelper::between( + $field['settings']->xml, 'name="', '"' + ); + if (strpos($requeSt_id, '_request_id') !== false + || strpos($requeSt_id, '_request_catid') !== false) + { + // keep it then, don't change + $name = $this->placeholder->update_( + $requeSt_id + ); + } + else + { + $name = 'catid'; + } + + // if list view name is set + if (StringHelper::check($listViewName)) + { + // check if we should use another Text Name as this views name + $otherName = $this->placeholder->update_( + GetHelper::between( + $field['settings']->xml, 'othername="', '"' + ) + ); + $otherViews = $this->placeholder->update_( + GetHelper::between( + $field['settings']->xml, 'views="', '"' + ) + ); + $otherView = $this->placeholder->update_( + GetHelper::between( + $field['settings']->xml, 'view="', '"' + ) + ); + + // This is to link other view category + if (StringHelper::check($otherName) + && StringHelper::check($otherViews) + && StringHelper::check($otherView)) + { + // set other category details + $this->categoryothername->set($listViewName, [ + 'name' => FieldHelper::safe( + $otherName + ), + 'views' => StringHelper::safe( + $otherViews + ), + 'view' => StringHelper::safe( + $otherView + ) + ]); + } + } + } + // if tag is set then enable all tag options for this view (only one per view) + elseif ($type_name === 'tag') + { + $name = 'tags'; + } + // if the field is set as alias it must be called alias + elseif (isset($field['alias']) && $field['alias']) + { + $name = 'alias'; + } + else + { + // get value from xml + $xml = FieldHelper::safe( + $this->placeholder->update_( + GetHelper::between( + $field['settings']->xml, 'name="', '"' + ) + ) + ); + // check if a value was found + if (StringHelper::check($xml)) + { + $name = $xml; + } + } + // exit foreach loop + break; + } + } + } + + // return the value unique + if (StringHelper::check($listViewName) && isset($field['hash'])) + { + $this->unique[$listViewName . $amicably . $field['hash']] + = $this->uniquename->get($name, $listViewName . $amicably); + + // now return the unique name + return $this->unique[$listViewName . $amicably . $field['hash']]; + } + + // fall back to global + return $name; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/TypeName.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/TypeName.php new file mode 100644 index 000000000..4f6555af4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/TypeName.php @@ -0,0 +1,123 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\String\TypeHelper; + + +/** + * Compiler Field Type Name + * + * @since 3.2.0 + */ +class TypeName +{ + /** + * Get the field's actual type + * + * @param array $field The field object + * + * @return string Success returns field type + * @since 3.2.0 + */ + public function get(array &$field): string + { + // check if we have done this already + if (isset($field['type_name'])) + { + return $field['type_name']; + } + + // check that we have the properties + if (isset($field['settings']) + && ObjectHelper::check($field['settings']) + && isset($field['settings']->properties) + && ArrayHelper::check($field['settings']->properties)) + { + // search for own custom fields + if (strpos((string) $field['settings']->type_name, '@') !== false) + { + // set own custom field + $field['settings']->own_custom = $field['settings']->type_name; + $field['settings']->type_name = 'Custom'; + } + + // set the type name + $type_name = TypeHelper::safe( + $field['settings']->type_name + ); + + // if custom (we must use the xml value) + if (strtolower((string) $type_name) === 'custom' + || strtolower((string) $type_name) === 'customuser') + { + $type = TypeHelper::safe( + GetHelper::between( + $field['settings']->xml, 'type="', '"' + ) + ); + } + else + { + // loop over properties looking for the type value + foreach ($field['settings']->properties as $property) + { + if ($property['name'] + === 'type') // type field is never adjustable (unless custom) + { + // force the default value + if (isset($property['example']) + && StringHelper::check( + $property['example'] + )) + { + $type = TypeHelper::safe( + $property['example'] + ); + } + // fall back on the xml settings (not ideal) + else + { + $type = TypeHelper::safe( + GetHelper::between( + $field['settings']->xml, 'type="', '"' + ) + ); + } + // exit foreach loop + break; + } + } + } + // check if the value is set + if (isset($type) && StringHelper::check($type)) + { + return $type; + } + // fallback on type name set in name field (not ideal) + else + { + return $type_name; + } + } + + // fall back to text + return 'text'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/UniqueName.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/UniqueName.php new file mode 100644 index 000000000..affe4c299 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/UniqueName.php @@ -0,0 +1,112 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Utilities\String\FieldHelper; +use VDM\Joomla\Componentbuilder\Compiler\Registry; + + +/** + * Compiler Field Unique Name + * + * @since 3.2.0 + */ +class UniqueName +{ + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + } + + /** + * Count how many times the same field is used per view + * + * @param string $name The name of the field + * @param string $view The name of the view + * + * @return void + * @since 3.2.0 + */ + public function set(string $name, string $view) + { + if (($number = $this->registry->get("unique.names.${view}.counter.${name}")) === null) + { + $this->registry->set("unique.names.${view}.counter.${name}", 1); + + return; + } + + // count how many times the field is used + $this->registry->set("unique.names.${view}.counter.${name}", ++$number); + + return; + } + + /** + * Naming each field with an unique name + * + * @param string $name The name of the field + * @param string $view The name of the view + * + * @return string the name + * @since 3.2.0 + */ + public function get(string $name, string $view): string + { + // only increment if the field name is used multiple times + if ($this->registry->get("unique.names.${view}.counter.${name}") > 1) + { + $counter = 1; + // set the unique name + $unique_name = FieldHelper::safe( + $name . '_' . $counter + ); + + while ($this->registry->get("unique.names.${view}.names.${unique_name}") !== null) + { + // increment the number + $counter++; + // try again + $unique_name = FieldHelper::safe( + $name . '_' . $counter + ); + } + + // set the new name number + $this->registry->set("unique.names.${view}.names.${unique_name}", $counter); + + // return the unique name + return $unique_name; + } + + return $name; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Validation.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Validation.php new file mode 100644 index 000000000..afe05dca4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/Validation.php @@ -0,0 +1,168 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Field; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Field\CoreValidationInterface; + + +/** + * Compiler Field Validation Rules + * + * @since 3.2.0 + */ +class Validation +{ + /** + * Compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Gui + * + * @var Gui + * @since 3.2.0 + */ + protected Gui $gui; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Field Core Validation + * + * @var CoreValidationInterface + * @since 3.2.0 + */ + protected CoreValidationInterface $validation; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * @param Gui|null $gui The compiler customcode gui object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Customcode|null $customcode The compiler customcode object. + * @param CoreValidationInterface|null $validation The core validation rule object. + * + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null, ?Gui $gui = null, ?Placeholder $placeholder = null, + ?Customcode $customcode = null, ?CoreValidationInterface $validation = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->validation = $validation ?: Compiler::_('Field.Core.Validation'); + } + + /** + * Set the validation rule + * + * @param int $id The field id + * @param string $field The field string + * + * @return void + * @since 3.2.0 + */ + public function set(int $id, string $field) + { + // check if we have validate (validation rule set) + $validation_rule = GetHelper::between( + $field, 'validate="', '"' + ); + + if (StringHelper::check($validation_rule)) + { + // make sure it is lowercase + $validation_rule = StringHelper::safe( + $validation_rule + ); + + // link this field to this validation (don't move this down) + $this->registry->set("validation.linked.${id}", $validation_rule); + + // make sure it is not already set + if ($this->registry->get("validation.rules.${validation_rule}") === null) + { + // get joomla core validation names and make sure this rule is not a core validation rule + if (!in_array($validation_rule, (array) $this->validation->get(true))) + { + // get the class methods for this rule if it exists + if (($php_code = GetHelper::var( + 'validation_rule', $validation_rule, 'name', 'php' + )) !== false) + { + // open and set the validation rule + $this->registry->set("validation.rules.${validation_rule}", + $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode( + (string) $php_code + ) + ) + ), + array( + 'table' => 'validation_rule', + 'field' => 'php', + 'id' => GetHelper::var( + 'validation_rule', + $validation_rule, 'name', 'id' + ), + 'type' => 'php' + ) + ) + ); + } + else + { + // TODO set the notice that this validation rule is custom and was not found + $this->registry->remove("validation.linked.${id}"); + } + } + else + { + // remove link (we only want custom validations linked) + $this->registry->remove("validation.linked.${id}"); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Field/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Component/PlaceholderInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Component/PlaceholderInterface.php new file mode 100644 index 000000000..74ff3f8aa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Component/PlaceholderInterface.php @@ -0,0 +1,31 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component; + + +/** + * Component Placeholder Interface + * + * @since 3.2.0 + */ +interface PlaceholderInterface +{ + /** + * get all System Placeholders + * + * @return array The global placeholders + * + * @since 3.2.0 + */ + public function get(): array; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Component/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Component/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Component/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fielddynamicinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fielddynamicinterface.php new file mode 100644 index 000000000..9e954a9c6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fielddynamicinterface.php @@ -0,0 +1,41 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator; + + +/** + * Field Creator Interface (needed for the container) + * + * @since 3.2.0 + */ +interface Fielddynamicinterface +{ + /** + * Get the Dynamic field and build all it needs + * + * @param array $field The field data + * @param array $view The view data + * @param int $viewType The view type + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The place holder and replace values + * @param string $dbkey The the custom table key + * @param boolean $build The switch to set the build option + * + * @return mixed The complete field + * @since 3.2.0 + */ + public function get(array &$field, array &$view, int &$viewType, string &$langView, string &$nameSingleCode, + string &$nameListCode, array &$placeholders, string &$dbkey, bool $build); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fieldsetinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fieldsetinterface.php new file mode 100644 index 000000000..7a8c06d64 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fieldsetinterface.php @@ -0,0 +1,35 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator; + + +/** + * Fieldset Creator Interface (needed for the container) + * + * @since 3.2.0 + */ +interface Fieldsetinterface +{ + /** + * Get a fieldset + * + * @param array $view The view data + * @param string $component The component name + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * + * @return string The fields set as a string + * @since 3.2.0 + */ + public function get(array $view, string $component, string $nameSingleCode, string $nameListCode): string; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fieldtypeinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fieldtypeinterface.php new file mode 100644 index 000000000..d6efe1040 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/Fieldtypeinterface.php @@ -0,0 +1,45 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator; + + +/** + * Field (Types) Creator Interface (needed for the container) + * + * @since 3.2.0 + */ +interface Fieldtypeinterface +{ + /** + * Create a field + * + * @param string $setType The set of fields type + * @param array $fieldAttributes The field values + * @param string $name The field name + * @param string $typeName The field type + * @param string $langView The language string of the view + * @param string $nameSingleCode The single view name + * @param string $nameListCode The list view name + * @param array $placeholders The place holder and replace values + * @param array|null $optionArray The option bucket array used to set the field options if needed. + * @param array|null $custom Used when field is from config + * @param array|null $custom Used when field is from config + * @param string $taber The tabs to add in layout + * + * @return mixed The field (two return types based of field_builder_type selected Object->xml or String) + * @since 3.2.0 + */ + public function get(string $setType, array &$fieldAttributes, string &$name, + string &$typeName, string &$langView, string &$nameSingleCode, string &$nameListCode, + array $placeholders, ?array &$optionArray, ?array $custom = null, string $taber = ''); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Creator/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/DispenserInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/DispenserInterface.php new file mode 100644 index 000000000..5336ddae8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/DispenserInterface.php @@ -0,0 +1,62 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode; + + +/** + * Customcode Dispenser Interface + * + * @since 3.2.0 + */ +interface DispenserInterface +{ + /** + * Set the script for the customcode dispenser + * + * @param string $script The script + * @param string $first The first key + * @param string|null $second The second key (if not set we use only first key) + * @param string|null $third The third key (if not set we use only first and second key) + * @param array $config The config options + * @param bool $base64 The switch to decode base64 the script + * default: true + * @param bool $dynamic The switch to dynamic update the script + * default: true + * @param bool $add The switch to add to exiting instead of replace + * default: false + * + * @return bool true on success + * @since 3.2.0 + */ + public function set(&$script, string $first, ?string $second = null, ?string $third = null, + array $config = [], bool $base64 = true, bool $dynamic = true, bool $add = false): bool; + + /** + * Get the script from the customcode dispenser + * + * @param string $first The first key + * @param string $second The second key + * @param string $prefix The prefix to add in front of the script if found + * @param string|null $note The switch/note to add to the script + * @param bool $unset The switch to unset the value if found + * @param mixed|null $default The switch/string to use as default return if script not found + * @param string $suffix The suffix to add after the script if found + * + * @return mixed The string/script if found or the default value if not found + * + * @since 3.2.0 + */ + public function get(string $first, string $second, string $prefix = '', ?string $note = null, + bool $unset = false, $default = null, string $suffix = ''); + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/ExternalInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/ExternalInterface.php new file mode 100644 index 000000000..1a889fe48 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/ExternalInterface.php @@ -0,0 +1,33 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode; + + +/** + * Customcode External Interface + * + * @since 3.2.0 + */ +interface ExternalInterface +{ + /** + * Set the external code string & load it in to string + * + * @param string $string The content to check + * @param int $debug The switch to debug the update + * + * @return string + * @since 3.2.0 + */ + public function set(string $string, int $debug = 0): string; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/ExtractorInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/ExtractorInterface.php new file mode 100644 index 000000000..dcbd15a79 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/ExtractorInterface.php @@ -0,0 +1,30 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode; + + +/** + * Customcode Extractor Interface + * + * @since 3.2.0 + */ +interface ExtractorInterface +{ + /** + * get the custom code from the local files + * + * @return void + * @since 3.2.0 + */ + public function run(); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/GuiInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/GuiInterface.php new file mode 100644 index 000000000..6db8b6b6c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/GuiInterface.php @@ -0,0 +1,46 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode; + + +/** + * Customcode Gui Interface + * + * @since 3.2.0 + */ +interface GuiInterface +{ + /** + * Set the JCB GUI code placeholder + * + * @param string $string The code string + * @param array $config The placeholder config values + * + * @return string + * @since 3.2.0 + */ + public function set(string $string, array $config): string; + + /** + * search a file for gui code blocks that were updated in the IDE + * + * @param string $file The file path to search + * @param array $placeholders The values to replace in the code being stored + * @param string $today The date for today + * @param string $target The target path type + * + * @return void + * @since 3.2.0 + */ + public function search(string &$file, array &$placeholders, string &$today, string &$target); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/LockBaseInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/LockBaseInterface.php new file mode 100644 index 000000000..f892db12d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/LockBaseInterface.php @@ -0,0 +1,32 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode; + + +/** + * Customcode LockBase Interface + * + * @since 3.2.0 + */ +interface LockBaseInterface +{ + /** + * Set a string as bsae64 (basic) + * + * @param string $script The code string + * + * @return string + * @since 3.2.0 + */ + public function set(string $script): string; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Customcode/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/CustomcodeInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/CustomcodeInterface.php new file mode 100644 index 000000000..77f03a74c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/CustomcodeInterface.php @@ -0,0 +1,59 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * Compiler Customcode Interface + * + * @since 3.2.0 + */ +interface CustomcodeInterface +{ + /** + * Update **ALL** dynamic values in a strings here + * + * @param string $string The content to check + * @param int $debug The switch to debug the update + * We can now at any time debug the + * dynamic build values if it gets broken + * + * @return string + * @since 3.2.0 + */ + public function update(string $string, int $debug = 0): string; + + /** + * Set the custom code data & can load it in to string + * + * @param string $string The content to check + * @param int $debug The switch to debug the update + * @param int|null $not The not switch + * + * @return string + * @since 3.2.0 + */ + public function set(string $string, int $debug = 0, ?int $not = null): string; + + /** + * Load the custom code from the system + * + * @param array|null $ids The custom code ides if known + * @param bool $setLang The set lang switch + * @param int $debug The switch to debug the update + * + * @return bool + * @since 3.2.0 + */ + public function get(?array $ids = null, bool $setLang = true, $debug = 0): bool; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/EventInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/EventInterface.php new file mode 100644 index 000000000..0f9b96010 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/EventInterface.php @@ -0,0 +1,33 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * Compiler Events Interface + * + * @since 3.2.0 + */ +interface EventInterface +{ + /** + * Trigger an event + * + * @param string $event The event to trigger + * @param mixed $data The values to pass to the event/plugin + * + * @return void + * @since 3.2.0 + */ + public function trigger(string $event, $data); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Extension/InstallInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Extension/InstallInterface.php new file mode 100644 index 000000000..24baca06e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Extension/InstallInterface.php @@ -0,0 +1,46 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Extension; + + +/** + * The properties an extension should have to be passed to the InstallScript class + * + * @since 3.2.0 + */ +interface InstallInterface +{ + /** + * The extension official name + * + * @return string + * @since 3.2.0 + */ + public function getOfficialName(): string; + + /** + * The extension class name + * + * @return string + * @since 3.2.0 + */ + public function getClassName(): string; + + /** + * The extension installer class name + * + * @return string + * @since 3.2.0 + */ + public function getInstallerClassName(): string; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Extension/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Extension/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Extension/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Field/CoreValidationInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Field/CoreValidationInterface.php new file mode 100644 index 000000000..8bf9641d8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Field/CoreValidationInterface.php @@ -0,0 +1,32 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Field; + + +/** + * Field Joomla Core Validation Interface + * + * @since 3.2.0 + */ +interface CoreValidationInterface +{ + /** + * Get the Array of Existing Validation Rule Names + * + * @param bool $lowercase Switch to set rules lowercase + * + * @return array + * @since 3.2.0 + */ + public function get(bool $lowercase = false): array; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Field/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Field/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/Field/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/GetScriptInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/GetScriptInterface.php new file mode 100644 index 000000000..c4a3530bc --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/GetScriptInterface.php @@ -0,0 +1,32 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * The functions a get script should have + * + * @since 3.2.0 + */ +interface GetScriptInterface +{ + /** + * get code to use + * + * @param Object $code The code object + * + * @return string + * @since 3.2.0 + */ + public function get(object $extension): string; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/HistoryInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/HistoryInterface.php new file mode 100644 index 000000000..7bd07c7c2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/HistoryInterface.php @@ -0,0 +1,34 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * Compiler History Interface + * + * @since 3.2.0 + */ +interface HistoryInterface +{ + /** + * Get Item History object + * + * @param string $type The type of item + * @param int $id The item ID + * + * @return ?object The history item object + * @since 3.2.0 + */ + public function get(string $type, int $id): ?object; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/LanguageInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/LanguageInterface.php new file mode 100644 index 000000000..f7d40d5fa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/LanguageInterface.php @@ -0,0 +1,89 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * Compiler Language Interface + * + * @since 3.2.0 + */ +interface LanguageInterface +{ + /** + * Get the language string key + * + * @param string $string The plan text string (English) + * + * @return string The key language string (all uppercase) + * @since 3.2.0 + */ + public function key($string): string; + + /** + * check if the language string exist + * + * @param string $target The target area for the language string + * @param string|null $language The language key string + * + * @return bool + * @since 3.2.0 + */ + public function exist(string $target, ?string $language = null): bool; + + /** + * get the language string + * + * @param string $target The target area for the language string + * @param string|null $language The language key string + * + * @return Mixed The language string found or empty string if none is found + * @since 3.2.0 + */ + public function get(string $target, string $language): string; + + /** + * get target array + * + * @param string $target The target area for the language string + * + * @return array The target array or empty array if none is found + * @since 3.2.0 + */ + public function getTarget(string $target): array; + + /** + * set target array + * + * @param string $target The target area for the language string + * @param array|null $content The language content string + * + * @return void + * @since 3.2.0 + */ + public function setTarget(string $target, ?array $content); + + /** + * set the language content values to language content array + * + * @param string $target The target area for the language string + * @param string $language The language key string + * @param string $string The language string + * @param bool $addPrefix The switch to add langPrefix + * + * @return void + * @since 3.2.0 + */ + public function set(string $target, string $language, string $string, bool $addPrefix = false); + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/PlaceholderInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/PlaceholderInterface.php new file mode 100644 index 000000000..d0ba2d281 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/PlaceholderInterface.php @@ -0,0 +1,240 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * Compiler Placeholder Interface + * + * @since 3.2.0 + */ +interface PlaceholderInterface +{ + /** + * Set content + * + * @param string $key The main string key + * @param mixed $value The values to set + * @param bool $hash Add the hash around the key + * + * @return void + * @since 3.2.0 + */ + public function set(string $key, $value, bool $hash = true); + + /** + * Get content by key + * + * @param string $key The main string key + * + * @return mixed + * @since 3.2.0 + */ + public function get(string $key); + + /** + * Does key exist at all in any variation + * + * @param string $key The main string key + * + * @return bool + * @since 3.2.0 + */ + public function exist(string $key): bool; + + /** + * Add content + * + * @param string $key The main string key + * @param mixed $value The values to set + * @param bool $hash Add the hash around the key + * + * @return void + * @since 3.2.0 + */ + public function add(string $key, $value, bool $hash = true); + + /** + * Remove content + * + * @param string $key The main string key + * + * @return void + * @since 3.2.0 + */ + public function remove(string $key); + + /** + * Set content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function set_(string $key, $value); + + /** + * Get content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * + * @return mixed + * @since 3.2.0 + */ + public function get_(string $key); + + /** + * Does key exist with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * + * @return bool + * @since 3.2.0 + */ + public function exist_(string $key): bool; + + /** + * Add content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function add_(string $key, $value); + + /** + * Remove content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * + * @return void + * @since 3.2.0 + */ + public function remove_(string $key); + + /** + * Set content with # # # hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function set_h(string $key, $value); + + /** + * Get content with # # # hash + * + * @param string $key The main string key + * + * @return mixed + * @since 3.2.0 + */ + public function get_h(string $key); + + /** + * Does key exist with # # # hash + * + * @param string $key The main string key + * + * @return bool + * @since 3.2.0 + */ + public function exist_h(string $key): bool; + + /** + * Add content with # # # hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function add_h(string $key, $value); + + /** + * Remove content with # # # hash + * + * @param string $key The main string key + * + * @return void + * @since 3.2.0 + */ + public function remove_h(string $key); + + /** + * Set a type of placeholder with set of values + * + * @param string $key The main string for placeholder key + * @param array $values The values to add + * + * @return void + * @since 3.2.0 + */ + public function setType(string $key, array $values); + + /** + * Remove a type of placeholder by main key + * + * @param string $key The main string for placeholder key + * + * @return void + * @since 3.2.0 + */ + public function clearType(string $key); + + /** + * Update the data with the placeholders + * + * @param string $data The actual data + * @param array $placeholder The placeholders + * @param int $action The action to use + * + * THE ACTION OPTIONS ARE + * 1 -> Just replace (default) + * 2 -> Check if data string has placeholders + * 3 -> Remove placeholders not in data string + * + * @return string + * @since 3.2.0 + */ + public function update(string $data, array $placeholder, int $action = 1): string; + + /** + * Update the data with the active placeholders + * + * @param string $data The actual data + * + * @return string + * @since 3.2.0 + */ + public function update_(string $data): string; + + /** + * return the placeholders for inserted and replaced code + * + * @param int $type The type of placement + * @param int|null $id The code id in the system + * + * @return array with start and end keys + * @since 3.2.0 + */ + public function keys(int $type, ?int $id = null): array; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/PowerInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/PowerInterface.php new file mode 100644 index 000000000..88a3ec3fb --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/PowerInterface.php @@ -0,0 +1,43 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces; + + +/** + * Compiler Power Interface + * + * @since 3.2.0 + */ +interface PowerInterface +{ + /** + * load all the powers linked to this component + * + * @param array $guids The global unique ids of the linked powers + * + * @return void + * @since 3.2.0 + */ + public function load(array $guids); + + /** + * Get a power + * + * @param string $guid The global unique id of the power + * @param int $build Force build switch (to override global switch) + * + * @return mixed + * @since 3.2.0 + */ + public function get(string $guid, int $build = 0); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Interfaces/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/Event.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/Event.php new file mode 100644 index 000000000..6dda2dc28 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/Event.php @@ -0,0 +1,100 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\JoomlaThree; + + +use Joomla\Registry\Registry; +use VDM\Joomla\Utilities\Component\Helper; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; + + +/** + * Compiler Events + * + * @since 3.2.0 + */ +class Event implements EventInterface +{ + /** + * event plugin trigger switch + * + * @var boolean + * @since 3.2.0 + */ + protected $activePlugins = false; + + /** + * Constructor + * + * @param Registry|null $params The component parameters + * + * @since 3.2.0 + */ + public function __construct(?Registry $params = null) + { + // Set the params + $params = $params ?: Helper::getParams('com_componentbuilder'); + // get active plugins + if (($plugins = $params->get('compiler_plugin', false)) + !== false) + { + foreach ($plugins as $plugin) + { + // get possible plugins + if (\JPluginHelper::isEnabled('extension', $plugin)) + { + // Import the appropriate plugin group. + \JPluginHelper::importPlugin('extension', $plugin); + // activate events + $this->activePlugins = true; + } + } + } + } + + /** + * Trigger and event + * + * @param string $event The event to trigger + * @param mixed $data The values to pass to the event/plugin + * + * @return void + * @throws \Exception + * @since 3.2.0 + */ + public function trigger(string $event, $data) + { + // only execute if plugins were loaded (active) + if ($this->activePlugins) + { + // Get the dispatcher. + $dispatcher = \JEventDispatcher::getInstance(); + + // Trigger this compiler event. + $results = $dispatcher->trigger($event, $data); + + // Check for errors encountered while trigger the event + if (count((array) $results) && in_array(false, $results, true)) + { + // Get the last error. + $error = $dispatcher->getError(); + + if (!($error instanceof \Exception)) + { + throw new \Exception($error); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/History.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/History.php new file mode 100644 index 000000000..2cfe3f84e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/History.php @@ -0,0 +1,232 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\JoomlaThree; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HistoryInterface; + + +/** + * Compiler History + * + * @since 3.2.0 + */ +class History implements HistoryInterface +{ + /** + * History Item Object + * + * @var object|null + * @since 3.2.0 + */ + protected ?object $tmp; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + */ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param \JDatabaseDriver|null $db The Database Driver object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Item History object + * + * @param string $type The type of item + * @param int $id The item ID + * + * @return ?object The history + * @since 3.2.0 + */ + public function get(string $type, int $id): ?object + { + // quick class object to store old history object + $this->tmp = null; + // Create a new query object. + $query = $this->db->getQuery(true); + + $query->select('h.*'); + $query->from('#__ucm_history AS h'); + $query->where( + $this->db->quoteName('h.ucm_item_id') . ' = ' . (int) $id + ); + // Join over the content type for the type id + $query->join( + 'LEFT', '#__content_types AS ct ON ct.type_id = h.ucm_type_id' + ); + $query->where( + 'ct.type_alias = ' . $this->db->quote( + 'com_componentbuilder.' . $type + ) + ); + $query->order('h.save_date DESC'); + $this->db->setQuery($query, 0, 1); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // new version of this item found + // so we need to mark it as the last compiled version + $newActive = $this->db->loadObject(); + // set the new version watch + $this->set($newActive, 1); + } + // Get last compiled verion + $query = $this->db->getQuery(true); + + $query->select('h.*'); + $query->from('#__ucm_history AS h'); + $query->where( + $this->db->quoteName('h.ucm_item_id') . ' = ' . (int) $id + ); + $query->where('h.keep_forever = 1'); + $query->where('h.version_note LIKE ' . $this->db->quote('%component%')); + // make sure it does not return the active version + if (isset($newActive) && isset($newActive->version_id)) + { + $query->where('h.version_id != ' . (int) $newActive->version_id); + } + // Join over the content type for the type id + $query->join( + 'LEFT', '#__content_types AS ct ON ct.type_id = h.ucm_type_id' + ); + $query->where( + 'ct.type_alias = ' . $this->db->quote( + 'com_componentbuilder.' . $type + ) + ); + $query->order('h.save_date DESC'); + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // the old active version was found + // so we may need to do an SQL update + // and unmark the old compiled version + $oldActives = $this->db->loadObjectList(); + foreach ($oldActives as $oldActive) + { + // remove old version watch + $this->set($oldActive, 0); + } + } + + // return the last used history record or null. + return $this->tmp; + } + + /** + * Set Item History Watch + * + * @param Object $object The history object + * @param int $action The action to take + * 0 = remove watch + * 1 = add watch + * + * @return bool + * @since 3.2.0 + */ + protected function set(object $object, int $action): bool + { + // check the note + if (JsonHelper::check($object->version_note)) + { + $version_note = json_decode((string) $object->version_note, true); + } + else + { + $version_note = array('component' => []); + } + // set watch + switch ($action) + { + case 0: + // remove watch + if (isset($version_note['component']) + && ($key = array_search( + $this->config->component_id, $version_note['component'] + )) !== false) + { + // last version that was used to build/compile + $this->tmp = json_decode((string) $object->version_data); + // remove it from this component + unset($version_note['component'][$key]); + } + else + { + // since it was not found, no need to update anything + return true; + } + break; + case 1: + // add watch + if (!in_array($this->config->component_id, $version_note['component'])) + { + $version_note['component'][] = $this->config->component_id; + } + else + { + // since it is there already, no need to update anything + return true; + } + break; + } + // check if we need to still keep this locked + if (isset($version_note['component']) + && ArrayHelper::check($version_note['component'])) + { + // insure component ids are only added once per item + $version_note['component'] = array_unique( + $version_note['component'] + ); + // we may change this, little risky (but since JCB does not have history notes it should be okay for now) + $object->version_note = json_encode($version_note); + $object->keep_forever = '1'; + } + else + { + $object->version_note = ''; + $object->keep_forever = '0'; + } + + // run the update + return $this->db->updateObject('#__ucm_history', $object, 'version_id'); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/JoomlaThree/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/Data.php new file mode 100644 index 000000000..66e329dd4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/Data.php @@ -0,0 +1,969 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Joomlamodule; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Filter\OutputFilter; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Field; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name as Fieldname; +use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders; +use VDM\Joomla\Componentbuilder\Compiler\Model\Libraries; +use VDM\Joomla\Componentbuilder\Compiler\Dynamicget\Data as Dynamicget; +use VDM\Joomla\Componentbuilder\Compiler\Templatelayout\Data as Templatelayout; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Joomla Module Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * Compiler Joomla Plugins Data + * + * @var array + * @since 3.2.0 + */ + protected array $data = []; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Customcode Class. + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * The Gui Class. + * + * @var Gui + * @since 3.2.0 + */ + protected Gui $gui; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Field Class. + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * The Name Class. + * + * @var Fieldname + * @since 3.2.0 + */ + protected Fieldname $fieldname; + + /** + * The Filesfolders Class. + * + * @var Filesfolders + * @since 3.2.0 + */ + protected Filesfolders $filesfolders; + + /** + * The Libraries Class. + * + * @var Libraries + * @since 3.2.0 + */ + protected Libraries $libraries; + + /** + * The Data Class. + * + * @var Dynamicget + * @since 3.2.0 + */ + protected Dynamicget $dynamicget; + + /** + * The Data Class. + * + * @var Templatelayout + * @since 3.2.0 + */ + protected Templatelayout $templatelayout; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Customcode $customcode The Customcode Class. + * @param Gui $gui The Gui Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Language $language The Language Class. + * @param Field $field The Field Class. + * @param Fieldname $fieldname The Name Class. + * @param Filesfolders $filesfolders The Filesfolders Class. + * @param Libraries $libraries The Libraries Class. + * @param Dynamicget $dynamicget The Data Class. + * @param Templatelayout $templatelayout The Data Class. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Customcode $customcode, Gui $gui, + Placeholder $placeholder, Language $language, + Field $field, Fieldname $fieldname, + Filesfolders $filesfolders, Libraries $libraries, + Dynamicget $dynamicget, Templatelayout $templatelayout, + ?\JDatabaseDriver $db = null) + { + $this->config = $config; + $this->customcode = $customcode; + $this->gui = $gui; + $this->placeholder = $placeholder; + $this->language = $language; + $this->field = $field; + $this->fieldname = $fieldname; + $this->filesfolders = $filesfolders; + $this->libraries = $libraries; + $this->dynamicget = $dynamicget; + $this->templatelayout = $templatelayout; + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get the Joomla Module/s + * + * @param int|null $id the module id + * + * @return object|array|null if ID found it returns object, if no ID given it returns all set + * @since 3.2.0 + */ + public function get(int $id = null) + { + if (is_null($id) && $this->exists()) + { + return $this->data; + } + elseif ($this->exists($id)) + { + return $this->data[$id]; + } + + return null; + } + + /** + * Check if the Joomla Module/s exists + * + * @param int|null $id the module id + * + * @return bool if ID found it returns true, if no ID given it returns true if any are set + * @since 3.2.0 + */ + public function exists(int $id = null): bool + { + if (is_null($id)) + { + return ArrayHelper::check($this->data); + } + elseif (isset($this->data[$id])) + { + return true; + } + + return $this->set($id); + } + + /** + * Set the Joomla Module + * + * @param int $id the module id + * + * @return bool true on success + * @since 3.2.0 + */ + public function set(int $id): bool + { + if (isset($this->data[$id])) + { + return true; + } + else + { + // Create a new query object. + $query = $this->db->getQuery(true); + + $query->select('a.*'); + $query->select( + $this->db->quoteName( + array( + 'f.addfiles', + 'f.addfolders', + 'f.addfilesfullpath', + 'f.addfoldersfullpath', + 'f.addurls', + 'u.version_update', + 'u.id' + ), array( + 'addfiles', + 'addfolders', + 'addfilesfullpath', + 'addfoldersfullpath', + 'addurls', + 'version_update', + 'version_update_id' + ) + ) + ); + // from these tables + $query->from('#__componentbuilder_joomla_module AS a'); + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_joomla_module_updates', 'u' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('u.joomla_module') . ')' + ); + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_joomla_module_files_folders_urls', 'f' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('f.joomla_module') . ')' + ); + $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); + $query->where($this->db->quoteName('a.published') . ' >= 1'); + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // get the module data + $module = $this->db->loadObject(); + + // tweak system to set stuff to the module domain + $_backup_target = $this->config->build_target; + $_backup_lang = $this->config->lang_target; + $_backup_langPrefix = $this->config->lang_prefix; + + // set some keys + $module->target_type = 'M0dUl3'; + $module->key = $module->id . '_' . $module->target_type; + + // update to point to module + $this->config->build_target = $module->key; + $this->config->lang_target = $module->key; + + // set version if not set + if (empty($module->module_version)) + { + $module->module_version = '1.0.0'; + } + + // set target client + if ($module->target == 2) + { + $module->target_client = 'administrator'; + } + else + { + // default is site area + $module->target_client = 'site'; + } + + // set GUI mapper + $guiMapper = array('table' => 'joomla_module', + 'id' => (int) $id, 'type' => 'php'); + // update the name if it has dynamic values + $module->name = $this->placeholder->update_( + $this->customcode->update($module->name) + ); + + // set safe class function name + $module->code_name + = ClassfunctionHelper::safe( + $module->name + ); + + // alias of code name + $module->class_name = $module->code_name; + // set official name + $module->official_name = StringHelper::safe( + $module->name, 'W' + ); + $this->config->set('lang_prefix', 'MOD_' . strtoupper((string) $module->code_name)); + + // set lang prefix + $module->lang_prefix = $this->config->lang_prefix; + + // set module class name + $module->class_helper_name = 'Mod' . ucfirst((string) $module->code_name) + . 'Helper'; + $module->class_data_name = 'Mod' . ucfirst((string) $module->code_name) + . 'Data'; + + // set module install class name + $module->installer_class_name = 'mod_' . ucfirst( + (string) $module->code_name + ) . 'InstallerScript'; + + // set module folder name + $module->folder_name = 'mod_' . strtolower((string) $module->code_name); + + // set the zip name + $module->zip_name = $module->folder_name . '_v' . str_replace( + '.', '_', (string) $module->module_version + ) . '__J' . $this->config->joomla_version; + + // set module file name + $module->file_name = $module->folder_name; + + // set module context + $module->context = $module->file_name . '.' . $module->id; + + // set official_name lang strings + $this->language->set( + $module->key, $this->config->lang_prefix, $module->official_name + ); + + // set some placeholder for this module + $this->placeholder->set('Module_name', $module->official_name); + $this->placeholder->set('Module', ucfirst( + (string) $module->code_name + )); + $this->placeholder->set('module', strtolower( + (string) $module->code_name + )); + $this->placeholder->set('module.version', $module->module_version); + $this->placeholder->set('module_version', str_replace( + '.', '_', (string) $module->module_version + )); + // set description (TODO) add description field to module + if (!isset($module->description) + || !StringHelper::check( + $module->description + )) + { + $module->description = ''; + } + else + { + $module->description = $this->placeholder->update_( + $this->customcode->update($module->description) + ); + $this->language->set( + $module->key, $module->lang_prefix . '_DESCRIPTION', + $module->description + ); + $module->description = '

' . $module->description + . '

'; + } + + // get author name + $project_author = $this->config->project_author; + + // set the description + $module->xml_description = "

" . $module->official_name + . " (v." . $module->module_version + . ")

" + . $module->description . "

Created by " . trim( + (string) OutputFilter::cleanText($project_author) + ) . "
Development started " + . Factory::getDate($module->created)->format("jS F, Y") + . "

"; + + // set xml description + $this->language->set( + $module->key, $module->lang_prefix . '_XML_DESCRIPTION', + $module->xml_description + ); + + // update the readme if set + if ($module->addreadme == 1 && !empty($module->readme)) + { + $module->readme = $this->placeholder->update_( + $this->customcode->update(base64_decode((string) $module->readme)) + ); + } + else + { + $module->addreadme = 0; + unset($module->readme); + } + + // get the custom_get + $module->custom_get = (isset($module->custom_get) + && JsonHelper::check($module->custom_get)) + ? json_decode((string) $module->custom_get, true) : null; + + if (ArrayHelper::check($module->custom_get)) + { + $module->custom_get = $this->dynamic->get( + $module->custom_get, $module->key, $module->key + ); + } + else + { + $module->custom_get = null; + } + + // set helper class details + if ($module->add_class_helper >= 1 + && StringHelper::check( + $module->class_helper_code + )) + { + if ($module->add_class_helper_header == 1 + && StringHelper::check( + $module->class_helper_header + )) + { + // set GUI mapper field + $guiMapper['field'] = 'class_helper_header'; + // base64 Decode code + $module->class_helper_header = PHP_EOL + . $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode( + (string) $module->class_helper_header + ) + ) + ), + $guiMapper + ) . PHP_EOL; + } + else + { + $module->add_class_helper_header = 0; + $module->class_helper_header = ''; + } + // set GUI mapper field + $guiMapper['field'] = 'class_helper_code'; + // base64 Decode code + $module->class_helper_code = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $module->class_helper_code) + ) + ), + $guiMapper + ); + // set class type + if ($module->add_class_helper == 2) + { + $module->class_helper_type = 'abstract class '; + } + else + { + $module->class_helper_type = 'class '; + } + } + else + { + $module->add_class_helper = 0; + $module->class_helper_code = ''; + $module->class_helper_header = ''; + } + + // base64 Decode mod_code + if (isset($module->mod_code) + && StringHelper::check($module->mod_code)) + { + // set GUI mapper field + $guiMapper['field'] = 'mod_code'; + $module->mod_code = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $module->mod_code) + ) + ), + $guiMapper + ); + + // check if we have template or layouts to load + $this->templatelayout->set( + $module->mod_code , $module->code_name + ); + } + else + { + $module->mod_code = "// get the module class sfx"; + $module->mod_code .= PHP_EOL + . "\$moduleclass_sfx = htmlspecialchars(\$params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8');"; + $module->mod_code .= PHP_EOL . "// load the default Tmpl"; + $module->mod_code .= PHP_EOL + . "require JModuleHelper::getLayoutPath('mod_" + . strtolower((string) $module->code_name) + . "', \$params->get('layout', 'default'));"; + } + + // base64 Decode default header + if (isset($module->default_header) + && StringHelper::check( + $module->default_header + )) + { + // set GUI mapper field + $guiMapper['field'] = 'default_header'; + $module->default_header = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $module->default_header) + ) + ), + $guiMapper + ); + } + else + { + $module->default_header = ''; + } + + // base64 Decode default + if (isset($module->default) + && StringHelper::check($module->default)) + { + // set GUI mapper field + $guiMapper['field'] = 'default'; + $guiMapper['type'] = 'html'; + $module->default = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $module->default) + ) + ), + $guiMapper + ); + + // check if we have template or layouts to load + $this->templatelayout->set( + $module->default , $module->code_name + ); + } + else + { + $module->default = '

No Tmpl set

'; + } + + // start the config array + $module->config_fields = []; + // create the form arrays + $module->form_files = []; + $module->fieldsets_label = []; + $module->fieldsets_paths = []; + $module->add_rule_path = []; + $module->add_field_path = []; + // set global fields rule to default component path + $module->fields_rules_paths = 1; + // set the fields data + $module->fields = (isset($module->fields) + && JsonHelper::check($module->fields)) + ? json_decode((string) $module->fields, true) : null; + if (ArrayHelper::check($module->fields)) + { + // ket global key + $key = $module->key; + $dynamic_fields = array('fieldset' => 'basic', + 'fields_name' => 'params', + 'file' => 'config'); + foreach ($module->fields as $n => &$form) + { + if (isset($form['fields']) + && ArrayHelper::check( + $form['fields'] + )) + { + // make sure the dynamic_field is set to dynamic_value by default + foreach ( + $dynamic_fields as $dynamic_field => + $dynamic_value + ) + { + if (!isset($form[$dynamic_field]) + || !StringHelper::check( + $form[$dynamic_field] + )) + { + $form[$dynamic_field] = $dynamic_value; + } + else + { + if ('fields_name' === $dynamic_field + && strpos((string) $form[$dynamic_field], '.') + !== false) + { + $form[$dynamic_field] + = $form[$dynamic_field]; + } + else + { + $form[$dynamic_field] + = StringHelper::safe( + $form[$dynamic_field] + ); + } + } + } + // check if field is external form file + if (!isset($form['module']) || $form['module'] != 1) + { + // now build the form key + $unique = $form['file'] . $form['fields_name'] + . $form['fieldset']; + } + else + { + // now build the form key + $unique = $form['fields_name'] + . $form['fieldset']; + } + // set global fields rule path switches + if ($module->fields_rules_paths == 1 + && isset($form['fields_rules_paths']) + && $form['fields_rules_paths'] == 2) + { + $module->fields_rules_paths = 2; + } + // set where to path is pointing + $module->fieldsets_paths[$unique] + = $form['fields_rules_paths']; + // check for extra rule paths + if (isset($form['addrulepath']) + && ArrayHelper::check($form['addrulepath'])) + { + foreach ($form['addrulepath'] as $add_rule_path) + { + if (StringHelper::check($add_rule_path['path'])) + { + $module->add_rule_path[$unique] = $add_rule_path['path']; + } + } + } + // check for extra field paths + if (isset($form['addfieldpath']) + && ArrayHelper::check($form['addfieldpath'])) + { + foreach ($form['addfieldpath'] as $add_field_path) + { + if (StringHelper::check($add_field_path['path'])) + { + $module->add_field_path[$unique] = $add_field_path['path']; + } + } + } + // add the label if set to lang + if (isset($form['label']) + && StringHelper::check( + $form['label'] + )) + { + $module->fieldsets_label[$unique] + = $this->language->key($form['label']); + } + // build the fields + $form['fields'] = array_map( + function ($field) use ($key, $unique) { + // make sure the alias and title is 0 + $field['alias'] = 0; + $field['title'] = 0; + // set the field details + $this->field->set( + $field, $key, $key, $unique + ); + // update the default if set + if (StringHelper::check( + $field['custom_value'] + ) + && isset($field['settings'])) + { + if (($old_default + = GetHelper::between( + $field['settings']->xml, + 'default="', '"', false + )) !== false) + { + // replace old default + $field['settings']->xml + = str_replace( + 'default="' . $old_default + . '"', 'default="' + . $field['custom_value'] . '"', + (string) $field['settings']->xml + ); + } + else + { + // add the default (hmmm not ideal but okay it should work) + $field['settings']->xml + = 'default="' + . $field['custom_value'] . '" ' + . $field['settings']->xml; + } + } + unset($field['custom_value']); + + // return field + return $field; + }, array_values($form['fields']) + ); + // check if field is external form file + if (!isset($form['module']) || $form['module'] != 1) + { + // load the form file + if (!isset($module->form_files[$form['file']])) + { + $module->form_files[$form['file']] + = []; + } + if (!isset($module->form_files[$form['file']][$form['fields_name']])) + { + $module->form_files[$form['file']][$form['fields_name']] + = []; + } + if (!isset($module->form_files[$form['file']][$form['fields_name']][$form['fieldset']])) + { + $module->form_files[$form['file']][$form['fields_name']][$form['fieldset']] + = []; + } + // do some house cleaning (for fields) + foreach ($form['fields'] as $field) + { + // so first we lock the field name in + $this->fieldname->get( + $field, $module->key, $unique + ); + // add the fields to the global form file builder + $module->form_files[$form['file']][$form['fields_name']][$form['fieldset']][] + = $field; + } + // remove form + unset($module->fields[$n]); + } + else + { + // load the config form + if (!isset($module->config_fields[$form['fields_name']])) + { + $module->config_fields[$form['fields_name']] + = []; + } + if (!isset($module->config_fields[$form['fields_name']][$form['fieldset']])) + { + $module->config_fields[$form['fields_name']][$form['fieldset']] + = []; + } + // do some house cleaning (for fields) + foreach ($form['fields'] as $field) + { + // so first we lock the field name in + $this->fieldname->get( + $field, $module->key, $unique + ); + // add the fields to the config builder + $module->config_fields[$form['fields_name']][$form['fieldset']][] + = $field; + } + // remove form + unset($module->fields[$n]); + } + } + else + { + unset($module->fields[$n]); + } + } + } + unset($module->fields); + + // set files and folders + $this->filesfolders->set($module); + + // set libraries + $this->libraries->set($module->code_name, $module); + + // add PHP in module install + $module->add_install_script = true; + $addScriptMethods = [ + 'php_script', + 'php_preflight', + 'php_postflight', + 'php_method' + ]; + $addScriptTypes = [ + 'install', + 'update', + 'uninstall' + ]; + // the next are php placeholders + $guiMapper['type'] = 'php'; + foreach ($addScriptMethods as $scriptMethod) + { + foreach ($addScriptTypes as $scriptType) + { + if (isset($module->{'add_' . $scriptMethod . '_' . $scriptType}) + && $module->{'add_' . $scriptMethod . '_' . $scriptType} == 1 + && StringHelper::check( + $module->{$scriptMethod . '_' . $scriptType} + )) + { + // set GUI mapper field + $guiMapper['field'] = $scriptMethod . '_' . $scriptType; + $module->{$scriptMethod . '_' . $scriptType} = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode( + (string) $module->{$scriptMethod . '_' . $scriptType} + ) + ) + ), + $guiMapper + ); + } + else + { + unset($module->{$scriptMethod . '_' . $scriptType}); + $module->{'add_' . $scriptMethod . '_' . $scriptType} = 0; + } + } + } + + // add_sql + if ($module->add_sql == 1 + && StringHelper::check($module->sql)) + { + $module->sql = $this->placeholder->update_( + $this->customcode->update(base64_decode((string) $module->sql)) + ); + } + else + { + unset($module->sql); + $module->add_sql = 0; + } + + // add_sql_uninstall + if ($module->add_sql_uninstall == 1 + && StringHelper::check( + $module->sql_uninstall + )) + { + $module->sql_uninstall = $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $module->sql_uninstall) + ) + ); + } + else + { + unset($module->sql_uninstall); + $module->add_sql_uninstall = 0; + } + + // update the URL of the update_server if set + if ($module->add_update_server == 1 + && StringHelper::check( + $module->update_server_url + )) + { + $module->update_server_url = $this->placeholder->update_( + $this->customcode->update($module->update_server_url) + ); + } + + // add the update/sales server FTP details if that is the expected protocol + $serverArray = array('update_server', 'sales_server'); + foreach ($serverArray as $server) + { + if ($module->{'add_' . $server} == 1 + && is_numeric( + $module->{$server} + ) + && $module->{$server} > 0) + { + // get the server protocol + $module->{$server . '_protocol'} + = GetHelper::var( + 'server', (int) $module->{$server}, 'id', 'protocol' + ); + } + else + { + $module->{$server} = 0; + // only change this for sales server (update server can be added locally to the zip file) + if ('sales_server' === $server) + { + $module->{'add_' . $server} = 0; + } + $module->{$server . '_protocol'} = 0; + } + } + + // set the update server stuff (TODO) + // update_server_xml_path + // update_server_xml_file_name + + // rest globals + $this->config->build_target = $_backup_target; + $this->config->lang_target = $_backup_lang; + $this->config->lang_prefix = $_backup_langPrefix; + + $this->placeholder->remove('Module_name'); + $this->placeholder->remove('Module'); + $this->placeholder->remove('module'); + $this->placeholder->remove('module.version'); + $this->placeholder->remove('module_version'); + + $this->data[$id] = $module; + + return true; + } + } + + return false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/Structure.php new file mode 100644 index 000000000..8379e6e32 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/Structure.php @@ -0,0 +1,1151 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Joomlamodule; + + +use VDM\Joomla\Componentbuilder\Compiler\Joomlamodule\Data as Module; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Componentbuilder\Compiler\Builder\TemplateData; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\FileHelper; + + +/** + * Joomla Module Structure Builder Class + * + * @since 3.2.0 + */ +class Structure +{ + /** + * The Data Class. + * + * @var Module + * @since 3.2.0 + */ + protected Module $module; + + /** + * The Component Class. + * + * @var Component + * @since 3.2.0 + */ + protected Component $component; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Registry Class. + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * The Dispenser Class. + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * The Folder Class. + * + * @var Folder + * @since 3.2.0 + */ + protected Folder $folder; + + /** + * The File Class. + * + * @var File + * @since 3.2.0 + */ + protected File $file; + + /** + * The Files Class. + * + * @var Files + * @since 3.2.0 + */ + protected Files $files; + + /** + * The TemplateData Class. + * + * @var TemplateData + * @since 3.2.0 + */ + protected TemplateData $templatedata; + + /** + * Constructor. + * + * @param Module $module The Data Class. + * @param Component $component The Component Class. + * @param Config $config The Config Class. + * @param Registry $registry The Registry Class. + * @param Dispenser $dispenser The Dispenser Class. + * @param Event $event The EventInterface Class. + * @param Counter $counter The Counter Class. + * @param Folder $folder The Folder Class. + * @param File $file The File Class. + * @param Files $files The Files Class. + * @param TemplateData $templatedata The TemplateData Class. + * + * @since 3.2.0 + */ + public function __construct(Module $module, Component $component, Config $config, + Registry $registry, Dispenser $dispenser, Event $event, + Counter $counter, Folder $folder, File $file, + Files $files, TemplateData $templatedata) + { + $this->module = $module; + $this->component = $component; + $this->config = $config; + $this->registry = $registry; + $this->dispenser = $dispenser; + $this->event = $event; + $this->counter = $counter; + $this->folder = $folder; + $this->file = $file; + $this->files = $files; + $this->templatedata = $templatedata; + } + + /** + * Build the Modules files, folders, url's and config + * + * @return void + * @since 3.2.0 + */ + public function build() + { + if ($this->module->exists()) + { + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + $modules = $this->module->get(); + + // Trigger Event: jcb_ce_onBeforeSetModules + $this->event->trigger( + 'jcb_ce_onBeforeBuildModules', + array(&$component_context, &$modules) + ); + + foreach ($modules as $module) + { + if (ObjectHelper::check($module) + && isset($module->folder_name) + && StringHelper::check($module->folder_name)) + { + // module path + $this->modulePath($module); + + // set the module paths + $this->registry->set('dynamic_paths.' . $module->key, $module->folder_path); + + // make sure there is no old build + $this->folder->remove($module->folder_path); + + // create the main module folder + $this->folder->create($module->folder_path); + + // create the main module file + $this->setMainModFile($module); + + // creat the custom get file + $this->setCustomGet($module); + + // set helper file + $this->setHelperFile($module); + + // set main xml file + $this->setMainXmlFile($module); + + // set tmpl folder + $this->folder->create($module->folder_path . '/tmpl'); + + // set default file + $this->setDefaultFile($module); + + // set custom default files + $this->setTemplateFiles($module); + + // set install script if needed + $this->setInstallScript($module); + + // set readme if found + $this->setReadme($module); + + // set the CSS and JavaScript in form + $this->setCssJsForm($module); + + // set rules folders if needed + if (isset($module->fields_rules_paths) + && $module->fields_rules_paths == 2) + { + // create rules folder + $this->folder->create($module->folder_path . '/rules'); + } + + // set forms folder/files if needed + $this->setForms($module); + + // set SQL stuff if needed + $this->setSQL($module); + + // create the language folder + $this->folder->create($module->folder_path . '/language'); + + // also create the lang tag folder + $this->folder->create( + $module->folder_path . '/language/' . $this->config->get('lang_tag', 'en-GB') + ); + + // check if this module has files + $this->setFiles($module); + + // check if this module has folders + $this->setFolders($module); + + // check if this module has urls + $this->setUrls($module); + } + } + } + } + + /** + * get the module xml template + * + * @param object $module The module object + * + * @return string + * @since 3.2.0 + */ + protected function getXML(object &$module): string + { + $xml = ''; + $xml .= PHP_EOL . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . $module->lang_prefix + . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('BUILDDATE') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('AUTHOR') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('AUTHOREMAIL') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('AUTHORWEBSITE') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('COPYRIGHT') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('LICENSE') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . $module->module_version + . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . $module->lang_prefix + . '_XML_DESCRIPTION'; + $xml .= Placefix::_h('MAINXML'); + $xml .= PHP_EOL . ''; + + return $xml; + } + + /** + * get the module admin custom script field + * + * @param array $fieldScriptBucket The field + * + * @return string + * @since 3.2.0 + * + */ + protected function getCustomScriptField(array $fieldScriptBucket): string + { + $form_field_class = []; + $form_field_class[] = Placefix::_h('BOM') . PHP_EOL; + $form_field_class[] = "//" . Line::_(__Line__, __Class__) + . " No direct access to this file"; + $form_field_class[] = "defined('_JEXEC') or die('Restricted access');"; + $form_field_class[] = PHP_EOL . "use Joomla\CMS\Form\FormField;"; + $form_field_class[] = "use Joomla\CMS\Factory;"; + $form_field_class[] = PHP_EOL + . "class JFormFieldModadminvvvvvvvdm extends FormField"; + $form_field_class[] = "{"; + $form_field_class[] = Indent::_(1) + . "protected \$type = 'modadminvvvvvvvdm';"; + $form_field_class[] = PHP_EOL . Indent::_(1) + . "protected function getLabel()"; + $form_field_class[] = Indent::_(1) . "{"; + $form_field_class[] = Indent::_(2) . "return;"; + $form_field_class[] = Indent::_(1) . "}"; + $form_field_class[] = PHP_EOL . Indent::_(1) + . "protected function getInput()"; + $form_field_class[] = Indent::_(1) . "{"; + $form_field_class[] = Indent::_(2) . "//" . Line::_(__Line__, __Class__) + . " Get the document"; + $form_field_class[] = Indent::_(2) + . "\$document = Factory::getDocument();"; + $form_field_class[] = implode(PHP_EOL, $fieldScriptBucket); + $form_field_class[] = Indent::_(2) . "return; // noting for now :)"; + $form_field_class[] = Indent::_(1) . "}"; + $form_field_class[] = "}"; + + return implode(PHP_EOL, $form_field_class); + } + + /** + * Set the module path + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function modulePath(object &$module): void + { + $module->folder_path = $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/' + . $module->folder_name; + } + + /** + * Set the main module file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setMainModFile(object $module): void + { + // set main mod file + $file_details = [ + 'path' => $module->folder_path . '/' . $module->file_name . '.php', + 'name' => $module->file_name . '.php', + 'zip' => $module->file_name . '.php' + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + + /** + * Set the custom get file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setCustomGet(object $module): void + { + if ($module->custom_get) + { + $file_details = [ + 'path' => $module->folder_path . '/data.php', + 'name' => 'data.php', + 'zip' => 'data.php' + ]; + + $this->file->write( + $file_details['path'], + 'official_name . ' Data' + . PHP_EOL . ' */' . PHP_EOL . "class " . $module->class_data_name + . ' extends \JObject' . PHP_EOL . "{" . Placefix::_h('DYNAMICGETS') . "}" + . PHP_EOL + ); + + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + + /** + * Set the helper file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setHelperFile(object $module): void + { + if ($module->add_class_helper >= 1) + { + $file_details = [ + 'path' => $module->folder_path . '/helper.php', + 'name' => 'helper.php', + 'zip' => 'helper.php' + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + + /** + * Set the main XML file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setMainXmlFile(object $module): void + { + $file_details = [ + 'path' => $module->folder_path . '/' . $module->file_name . '.xml', + 'name' => $module->file_name . '.xml', + 'zip' => $module->file_name . '.xml' + ]; + + $this->file->write( + $file_details['path'], + $this->getXML($module) + ); + + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + + /** + * Set the main default template file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setDefaultFile(object $module): void + { + $file_details = [ + 'path' => $module->folder_path . '/tmpl/default.php', + 'name' => 'default.php', + 'zip' => 'tmpl/default.php' + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + + /** + * Set the additional template files + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setTemplateFiles(object $module): void + { + if (($data_ = $this->templatedata-> + get($module->key . '.' . $module->code_name)) !== null) + { + foreach ($data_ as $template => $data) + { + $file_details = [ + 'path' => $module->folder_path . "/tmpl/default_{$template}.php", + 'name' => "default_{$template}.php", + 'zip' => "tmpl/default_{$template}.php" + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + } + + /** + * Set the install script file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setInstallScript(object $module): void + { + if ($module->add_install_script) + { + $file_details = [ + 'path' => $module->folder_path . '/script.php', + 'name' => 'script.php', + 'zip' => 'script.php' + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + + /** + * Set the readme file + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setReadme(object $module): void + { + if ($module->addreadme) + { + $file_details = [ + 'path' => $module->folder_path . '/README.md', + 'name' => 'README.md', + 'zip' => 'README.md' + ]; + + $this->file->write($file_details['path'], $module->readme); + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + + /** + * Set the css and javascript in form + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setCssJsForm(object $module): void + { + // set the folders target path + $target_path = ''; + if ($module->target_client === 'administrator') + { + $target_path = '/administrator'; + } + + // check if we have custom fields needed for scripts + $module->add_scripts_field = false; + $field_script_bucket = []; + + // add any css from the fields + $this->setCssForm($module, $target_path, $field_script_bucket); + + // add any JavaScript from the fields + $this->setJsForm($module, $target_path, $field_script_bucket); + + // set fields folders if needed + if ($module->add_scripts_field + || (isset($module->fields_rules_paths) + && $module->fields_rules_paths == 2)) + { + // create fields folder + $this->folder->create($module->folder_path . '/fields'); + + // add the custom script field + if ($module->add_scripts_field) + { + $file_details = [ + 'path' => $module->folder_path . '/fields/modadminvvvvvvvdm.php', + 'name' => 'modadminvvvvvvvdm.php', + 'zip' => 'modadminvvvvvvvdm.php' + ]; + + $this->file->write( + $file_details['path'], + $this->getCustomScriptField( + $field_script_bucket + ) + ); + + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + } + + /** + * Set the css in form + * + * @param object $module + * @param string $targetPath + * @param array $bucket + * + * @return void + * @since 3.2.0 + */ + protected function setCssForm(object &$module, string $targetPath, array &$bucket): void + { + if (($css = $this->dispenser->get( + 'css_view', $module->key + )) !== null && StringHelper::check($css)) + { + // make sure this script does not have PHP + if (strpos((string) $css, 'add_scripts_field = true; + + // create the css folder + $this->folder->create($module->folder_path . '/css'); + + // add the CSS file + $file_details = [ + 'path' => $module->folder_path . '/css/mod_admin.css', + 'name' => 'mod_admin.css', + 'zip' => 'mod_admin.css' + ]; + + $this->file->write( + $file_details['path'], + Placefix::_h('BOM') . PHP_EOL + . PHP_EOL . $css + ); + + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + + // add the field script + $bucket[] = Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Custom CSS"; + $bucket[] = Indent::_(2) + . "\$document->addStyleSheet('" . $targetPath + . "/modules/" . $module->folder_name + . "/css/mod_admin.css', ['version' => 'auto', 'relative' => true]);"; + } + } + } + + /** + * Set the javascript in form + * + * @param object $module + * @param string $targetPath + * @param array $bucket + * + * @return void + * @since 3.2.0 + */ + protected function setJsForm(object &$module, string $targetPath, array &$bucket): void + { + if (($javascript = $this->dispenser->get( + 'view_footer', $module->key + )) !== null + && StringHelper::check($javascript)) + { + // make sure this script does not have PHP + if (strpos((string) $javascript, 'add_scripts_field = true; + + // add the JavaScript file + $this->folder->create($module->folder_path . '/js'); + + // add the CSS file + $file_details = [ + 'path' => $module->folder_path . '/js/mod_admin.js', + 'name' => 'mod_admin.js', + 'zip' => 'mod_admin.js' + ]; + + $this->file->write( + $file_details['path'], + Placefix::_h('BOM') . PHP_EOL + . PHP_EOL . $javascript + ); + + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + + // add the field script + $bucket[] = Indent::_(2) . "//" + . Line::_(__Line__, __Class__) . " Custom JS"; + $bucket[] = Indent::_(2) + . "\$document->addScript('" . $targetPath + . "/modules/" . $module->folder_name + . "/js/mod_admin.js', ['version' => 'auto', 'relative' => true]);"; + } + } + } + + /** + * Set the form folders and files as needed + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setForms(object &$module): void + { + if (isset($module->form_files) + && ArrayHelper::check( + $module->form_files + )) + { + // create forms folder + $this->folder->create($module->folder_path . '/forms'); + + // set the template files + foreach ($module->form_files as $file => $fields) + { + // set file details + $file_details = [ + 'path' => $module->folder_path . '/forms/' . $file . '.xml', + 'name' => $file . '.xml', + 'zip' => 'forms/' . $file . '.xml' + ]; + + // build basic XML + $xml = ''; + $xml .= PHP_EOL . ''; + + // search if we must add the component path + $add_component_path = false; + foreach ($fields as $field_name => $fieldsets) + { + if (!$add_component_path) + { + foreach ($fieldsets as $fieldset => $field) + { + if (!$add_component_path + && isset( + $module->fieldsets_paths[$file + . $field_name . $fieldset] + ) + && $module->fieldsets_paths[$file + . $field_name . $fieldset] == 1) + { + $add_component_path = true; + } + } + } + } + + // only add if part of the component field types path is required + if ($add_component_path) + { + $xml .= PHP_EOL . ''; + } + else + { + $xml .= PHP_EOL . '
'; + } + + // add the fields + foreach ($fields as $field_name => $fieldsets) + { + // check if we have an double fields naming set + $field_name_inner = ''; + $field_name_outer = $field_name; + if (strpos((string)$field_name, '.') !== false) + { + $field_names = explode('.', (string)$field_name); + if (count((array)$field_names) == 2) + { + $field_name_outer = $field_names[0]; + $field_name_inner = $field_names[1]; + } + } + $xml .= PHP_EOL . Indent::_(1) + . ''; + foreach ($fieldsets as $fieldset => $field) + { + // default to the field set name + $label = $fieldset; + if (isset($module->fieldsets_label[$file . $field_name . $fieldset])) + { + $label = $module->fieldsets_label[$file . $field_name . $fieldset]; + } + + // add path to module rules and custom fields + if (isset($module->fieldsets_paths[$file . $field_name . $fieldset]) + && ($module->fieldsets_paths[$file . $field_name . $fieldset] == 2 + || $module->fieldsets_paths[$file . $field_name . $fieldset] == 3)) + { + if ($module->target == 2) + { + if (!isset($module->add_rule_path[$file . $field_name . $fieldset])) + { + $module->add_rule_path[$file . $field_name . $fieldset] = + '/administrator/modules/' . $module->file_name . '/rules'; + } + + if (!isset($module->add_field_path[$file . $field_name . $fieldset])) + { + $module->add_field_path[$file . $field_name . $fieldset] = + '/administrator/modules/' . $module->file_name . '/fields'; + } + } + else + { + if (!isset($module->add_rule_path[$file . $field_name . $fieldset])) + { + $module->add_rule_path[$file . $field_name . $fieldset] = + '/modules/' . $module->file_name . '/rules'; + } + + if (!isset($module->add_field_path[$file . $field_name . $fieldset])) + { + $module->add_field_path[$file . $field_name . $fieldset] = + '/modules/' . $module->file_name . '/fields'; + } + } + } + + // add path to module rules and custom fields + if (isset($module->add_rule_path[$file . $field_name . $fieldset]) + || isset($module->add_field_path[$file . $field_name . $fieldset])) + { + + $xml .= PHP_EOL . Indent::_(1) . ''; + + $xml .= PHP_EOL . Indent::_(1) . '
add_rule_path[$file . $field_name . $fieldset])) + { + $xml .= PHP_EOL . Indent::_(2) + . 'addrulepath="' . $module->add_rule_path[$file . $field_name . $fieldset] . '"'; + } + + if (isset($module->add_field_path[$file . $field_name . $fieldset])) + { + $xml .= PHP_EOL . Indent::_(2) + . 'addfieldpath="' . $module->add_field_path[$file . $field_name . $fieldset] . '"'; + } + + $xml .= PHP_EOL . Indent::_(1) . '>'; + } + else + { + $xml .= PHP_EOL . Indent::_(1) . '
'; + } + + // check if we have an inner field set + if (StringHelper::check( + $field_name_inner + )) + { + $xml .= PHP_EOL . Indent::_(1) + . ''; + } + + // add the placeholder of the fields + $xml .= Placefix::_h('FIELDSET_' . $file + . $field_name . $fieldset); + + // check if we have an inner field set + if (StringHelper::check( + $field_name_inner + )) + { + $xml .= PHP_EOL . Indent::_(1) + . ''; + } + $xml .= PHP_EOL . Indent::_(1) + . '
'; + } + $xml .= PHP_EOL . Indent::_(1) . ''; + } + $xml .= PHP_EOL . ''; + + // add xml to file + $this->file->write($file_details['path'], $xml); + $this->files->appendArray($module->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + } + + /** + * Set the sql stuff + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setSQL(object $module): void + { + if ($module->add_sql || $module->add_sql_uninstall) + { + // create SQL folder + $this->folder->create($module->folder_path . '/sql'); + + // create mysql folder + $this->folder->create( + $module->folder_path . '/sql/mysql' + ); + + // now set the install file + if ($module->add_sql) + { + $this->file->write( + $module->folder_path . '/sql/mysql/install.sql', + $module->sql + ); + + // count the file created + $this->counter->file++; + } + + // now set the uninstall file + if ($module->add_sql_uninstall) + { + $this->file->write( + $module->folder_path + . '/sql/mysql/uninstall.sql', + $module->sql_uninstall + ); + + // count the file created + $this->counter->file++; + } + } + } + + /** + * Set the files + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setFiles(object $module): void + { + if (isset($module->files) + && ArrayHelper::check($module->files)) + { + // add to component files + foreach ($module->files as $file) + { + // set the pathfinder + $file['target_type'] = $module->target_type; + $file['target_id'] = $module->id; + + $this->component->appendArray('files', $file); + } + } + } + + /** + * Set the folders + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setFolders(object $module): void + { + if (isset($module->folders) + && ArrayHelper::check($module->folders)) + { + // add to component folders + foreach ($module->folders as $folder) + { + // set the pathfinder + $folder['target_type'] = $module->target_type; + $folder['target_id'] = $module->id; + + $this->component->appendArray('folders', $folder); + } + } + } + + /** + * Set the urls + * + * @param object $module + * + * @return void + * @since 3.2.0 + */ + protected function setUrls(object &$module): void + { + if (isset($module->urls) + && ArrayHelper::check($module->urls)) + { + // add to component urls + foreach ($module->urls as &$url) + { + // should we add the local folder + if (isset($url['type']) && $url['type'] > 1 + && isset($url['url']) + && StringHelper::check( + $url['url'] + )) + { + // set file name + $fileName = basename((string)$url['url']); + + // get the file contents + $data = FileHelper::getContent( + $url['url'] + ); + + // build sub path + if (strpos($fileName, '.js') !== false) + { + $path = '/js'; + } + elseif (strpos($fileName, '.css') !== false) + { + $path = '/css'; + } + else + { + $path = ''; + } + + // create sub media path if not set + $this->folder->create( + $module->folder_path . $path + ); + + // set the path to module file + $url['path'] = $module->folder_path . $path + . '/' . $fileName; // we need this for later + + // write data to path + $this->file->write($url['path'], $data); + + // count the file created + $this->counter->file++; + } + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlamodule/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/Data.php new file mode 100644 index 000000000..91e47dba9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/Data.php @@ -0,0 +1,881 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Filter\OutputFilter; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Field; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName; +use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\String\PluginHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Joomla Plugin Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * Compiler Joomla Plugins Data + * + * @var array + * @since 3.2.0 + */ + protected array $data = []; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Compiler Language + * + * @var Language + * @since 3.2.0 + **/ + protected Language $language; + + /** + * Compiler Field + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * Compiler field name + * + * @var FieldName + * @since 3.2.0 + */ + protected FieldName $fieldName; + + /** + * Compiler Files Folders + * + * @var Filesfolders + * @since 3.2.0 + */ + protected Filesfolders $filesFolders; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Language|null $language The compiler Language object. + * @param Field|null $field The compiler field data object. + * @param FieldName|null $fieldName The compiler field name object. + * @param Filesfolders|null $filesFolders The compiler files folders object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Customcode $customcode = null, + ?Gui $gui = null, ?Placeholder $placeholder = null, + ?Language $language = null, ?Field $field = null, ?FieldName $fieldName = null, + ?Filesfolders $filesFolders = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->language = $language ?: Compiler::_('Language'); + $this->field = $field ?: Compiler::_('Field'); + $this->fieldName = $fieldName ?: Compiler::_('Field.Name'); + $this->filesFolders = $filesFolders ?: Compiler::_('Model.Filesfolders'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get the Joomla Plugin/s + * + * @param int|null $id the plugin id + * + * @return object|array|null if ID found it returns object, if no ID given it returns all set + * @since 3.2.0 + */ + public function get(int $id = null) + { + if (is_null($id) && $this->exists()) + { + return $this->data; + } + elseif ($this->exists($id)) + { + return $this->data[$id]; + } + + return null; + } + + /** + * Check if the Joomla Plugin/s exists + * + * @param int|null $id the plugin id + * + * @return bool if ID found it returns true, if no ID given it returns true if any are set + * @since 3.2.0 + */ + public function exists(int $id = null): bool + { + if (is_null($id)) + { + return ArrayHelper::check($this->data); + } + elseif (isset($this->data[$id])) + { + return true; + } + + return $this->set($id); + } + + /** + * Set the Joomla Plugin + * + * @param int $id the plugin id + * + * @return bool true on success + * @since 3.2.0 + */ + public function set(int $id): bool + { + if (isset($this->data[$id])) + { + return true; + } + else + { + // Create a new query object. + $query = $this->db->getQuery(true); + + $query->select('a.*'); + $query->select( + $this->db->quoteName( + array( + 'g.name', + 'e.name', + 'e.head', + 'e.comment', + 'e.id', + 'f.addfiles', + 'f.addfolders', + 'f.addfilesfullpath', + 'f.addfoldersfullpath', + 'f.addurls', + 'u.version_update', + 'u.id' + ), array( + 'group', + 'extends', + 'class_head', + 'comment', + 'class_id', + 'addfiles', + 'addfolders', + 'addfilesfullpath', + 'addfoldersfullpath', + 'addurls', + 'version_update', + 'version_update_id' + ) + ) + ); + // from these tables + $query->from('#__componentbuilder_joomla_plugin AS a'); + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_joomla_plugin_group', 'g' + ) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group') + . ' = ' . $this->db->quoteName('g.id') . ')' + ); + $query->join( + 'LEFT', + $this->db->quoteName('#__componentbuilder_class_extends', 'e') + . ' ON (' . $this->db->quoteName('a.class_extends') . ' = ' + . $this->db->quoteName('e.id') . ')' + ); + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_joomla_plugin_updates', 'u' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('u.joomla_plugin') . ')' + ); + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_joomla_plugin_files_folders_urls', 'f' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('f.joomla_plugin') . ')' + ); + $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); + $query->where($this->db->quoteName('a.published') . ' >= 1'); + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // get the plugin data + $plugin = $this->db->loadObject(); + + // tweak system to set stuff to the plugin domain + $_backup_target = $this->config->build_target; + $_backup_lang = $this->config->lang_target; + $_backup_langPrefix = $this->config->lang_prefix; + + // set some keys + $plugin->target_type = 'pLuG!n'; + $plugin->key = $plugin->id . '_' . $plugin->target_type; + + // update to point to plugin + $this->config->build_target = $plugin->key; + $this->config->lang_target = $plugin->key; + + // set version if not set + if (empty($plugin->plugin_version)) + { + $plugin->plugin_version = '1.0.0'; + } + + // set GUI mapper + $guiMapper = array('table' => 'joomla_plugin', + 'id' => (int) $id, 'type' => 'php'); + + // update the name if it has dynamic values + $plugin->name = $this->placeholder->update_( + $this->customcode->update($plugin->name) + ); + + // update the name if it has dynamic values + $plugin->code_name + = ClassfunctionHelper::safe( + $plugin->name + ); + + // set official name + $plugin->official_name = ucwords( + $plugin->group . ' - ' . $plugin->name + ); + + // set lang prefix + $plugin->lang_prefix = PluginHelper::safeLangPrefix( + $plugin->code_name, + $plugin->group + ); + + // set langPrefix + $this->config->lang_prefix = $plugin->lang_prefix; + + // set plugin class name + $plugin->class_name + = PluginHelper::safeClassName( + $plugin->code_name, + $plugin->group + ); + + // set plugin install class name + $plugin->installer_class_name + = PluginHelper::safeInstallClassName( + $plugin->code_name, + $plugin->group + ); + + // set plugin folder name + $plugin->folder_name + = PluginHelper::safeFolderName( + $plugin->code_name, + $plugin->group + ); + + // set the zip name + $plugin->zip_name = $plugin->folder_name . '_v' . str_replace( + '.', '_', (string) $plugin->plugin_version + ) . '__J' . $this->config->joomla_version; + + // set plugin file name + $plugin->file_name = strtolower((string) $plugin->code_name); + + // set plugin context + $plugin->context = $plugin->folder_name . '.' . $plugin->id; + + // set official_name lang strings + $this->language->set( + $plugin->key, $this->config->lang_prefix, $plugin->official_name + ); + + // set some placeholder for this plugin + $this->placeholder->set('Plugin_name', $plugin->official_name); + $this->placeholder->set('PLUGIN_NAME', $plugin->official_name); + $this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name)); + $this->placeholder->set('plugin', strtolower((string) $plugin->code_name)); + $this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group)); + $this->placeholder->set('plugin_group', strtolower((string) $plugin->group)); + $this->placeholder->set('plugin.version', $plugin->plugin_version); + $this->placeholder->set('VERSION', $plugin->plugin_version); + $this->placeholder->set('plugin_version', str_replace( + '.', '_', (string) $plugin->plugin_version + )); + + // set description + $this->placeholder->set('DESCRIPTION', ''); + if (!isset($plugin->description) + || !StringHelper::check( + $plugin->description + )) + { + $plugin->description = ''; + } + else + { + $plugin->description = $this->placeholder->update_( + $this->customcode->update($plugin->description) + ); + $this->language->set( + $plugin->key, $plugin->lang_prefix . '_DESCRIPTION', + $plugin->description + ); + // set description + $this->placeholder->set('DESCRIPTION', $plugin->description); + $plugin->description = '

' . $plugin->description . '

'; + } + + // get author name + $project_author = $this->config->project_author; + + // we can only set these if the component was passed + $plugin->xml_description = "

" . $plugin->official_name + . " (v." . $plugin->plugin_version + . ")

" + . $plugin->description . "

Created by " . trim( + (string) OutputFilter::cleanText($project_author) + ) . "
Development started " + . Factory::getDate($plugin->created)->format("jS F, Y") + . "

"; + + // set xml discription + $this->language->set( + $plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION', + $plugin->xml_description + ); + + // update the readme if set + if ($plugin->addreadme == 1 && !empty($plugin->readme)) + { + $plugin->readme = $this->placeholder->update_( + $this->customcode->update(base64_decode((string) $plugin->readme)) + ); + } + else + { + $plugin->addreadme = 0; + unset($plugin->readme); + } + + // open some base64 strings + if (!empty($plugin->main_class_code)) + { + // set GUI mapper field + $guiMapper['field'] = 'main_class_code'; + // base64 Decode main_class_code. + $plugin->main_class_code = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $plugin->main_class_code) + ) + ), + $guiMapper + ); + } + + // set the head :) + if ($plugin->add_head == 1 && !empty($plugin->head)) + { + // set GUI mapper field + $guiMapper['field'] = 'head'; + // base64 Decode head. + $plugin->head = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $plugin->head) + ) + ), + $guiMapper + ); + } + elseif (!empty($plugin->class_head)) + { + // base64 Decode head. + $plugin->head = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $plugin->class_head) + ) + ), + array( + 'table' => 'class_extends', + 'field' => 'head', + 'id' => (int) $plugin->class_id, + 'type' => 'php') + ); + } + unset($plugin->class_head); + + // set the comment + if (!empty($plugin->comment)) + { + // base64 Decode comment. + $plugin->comment = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $plugin->comment) + ) + ), + array( + 'table' => 'class_extends', + 'field' => 'comment', + 'id' => (int) $plugin->class_id, + 'type' => 'php') + ); + } + + // start the config array + $plugin->config_fields = []; + // create the form arrays + $plugin->form_files = []; + $plugin->fieldsets_label = []; + $plugin->fieldsets_paths = []; + $plugin->add_rule_path = []; + $plugin->add_field_path = []; + // set global fields rule to default component path + $plugin->fields_rules_paths = 1; + // set the fields data + $plugin->fields = (isset($plugin->fields) + && JsonHelper::check($plugin->fields)) + ? json_decode((string) $plugin->fields, true) : null; + if (ArrayHelper::check($plugin->fields)) + { + // ket global key + $key = $plugin->key; + $dynamic_fields = array('fieldset' => 'basic', + 'fields_name' => 'params', + 'file' => 'config'); + foreach ($plugin->fields as $n => &$form) + { + if (isset($form['fields']) + && ArrayHelper::check( + $form['fields'] + )) + { + // make sure the dynamic_field is set to dynamic_value by default + foreach ( + $dynamic_fields as $dynamic_field => + $dynamic_value + ) + { + if (!isset($form[$dynamic_field]) + || !StringHelper::check( + $form[$dynamic_field] + )) + { + $form[$dynamic_field] = $dynamic_value; + } + else + { + if ('fields_name' === $dynamic_field + && strpos((string) $form[$dynamic_field], '.') + !== false) + { + $form[$dynamic_field] + = $form[$dynamic_field]; + } + else + { + $form[$dynamic_field] + = StringHelper::safe( + $form[$dynamic_field] + ); + } + } + } + // check if field is external form file + if (!isset($form['plugin']) || $form['plugin'] != 1) + { + // now build the form key + $unique = $form['file'] . $form['fields_name'] + . $form['fieldset']; + } + else + { + // now build the form key + $unique = $form['fields_name'] + . $form['fieldset']; + } + // set global fields rule path switchs + if ($plugin->fields_rules_paths == 1 + && isset($form['fields_rules_paths']) + && $form['fields_rules_paths'] == 2) + { + $plugin->fields_rules_paths = 2; + } + // set where to path is pointing + $plugin->fieldsets_paths[$unique] + = $form['fields_rules_paths']; + // add the label if set to lang + if (isset($form['label']) + && StringHelper::check( + $form['label'] + )) + { + $plugin->fieldsets_label[$unique] + = $this->language->key($form['label']); + } + // check for extra rule paths + if (isset($form['addrulepath']) + && ArrayHelper::check($form['addrulepath'])) + { + foreach ($form['addrulepath'] as $add_rule_path) + { + if (StringHelper::check($add_rule_path['path'])) + { + $plugin->add_rule_path[$unique] = $add_rule_path['path']; + } + } + } + // check for extra field paths + if (isset($form['addfieldpath']) + && ArrayHelper::check($form['addfieldpath'])) + { + foreach ($form['addfieldpath'] as $add_field_path) + { + if (StringHelper::check($add_field_path['path'])) + { + $plugin->add_field_path[$unique] = $add_field_path['path']; + } + } + } + // build the fields + $form['fields'] = array_map( + function ($field) use ($key, $unique) { + // make sure the alias and title is 0 + $field['alias'] = 0; + $field['title'] = 0; + // set the field details + $this->field->set( + $field, $key, $key, $unique + ); + // update the default if set + if (StringHelper::check( + $field['custom_value'] + ) + && isset($field['settings'])) + { + if (($old_default + = GetHelper::between( + $field['settings']->xml, + 'default="', '"', false + )) !== false) + { + // replace old default + $field['settings']->xml + = str_replace( + 'default="' . $old_default + . '"', 'default="' + . $field['custom_value'] . '"', + (string) $field['settings']->xml + ); + } + else + { + // add the default (hmmm not ideal but okay it should work) + $field['settings']->xml + = 'default="' + . $field['custom_value'] . '" ' + . $field['settings']->xml; + } + } + unset($field['custom_value']); + + // return field + return $field; + }, array_values($form['fields']) + ); + // check if field is external form file + if (!isset($form['plugin']) || $form['plugin'] != 1) + { + // load the form file + if (!isset($plugin->form_files[$form['file']])) + { + $plugin->form_files[$form['file']] + = []; + } + if (!isset($plugin->form_files[$form['file']][$form['fields_name']])) + { + $plugin->form_files[$form['file']][$form['fields_name']] + = []; + } + if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']])) + { + $plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']] + = []; + } + // do some house cleaning (for fields) + foreach ($form['fields'] as $field) + { + // so first we lock the field name in + $this->fieldName->get( + $field, $plugin->key, $unique + ); + // add the fields to the global form file builder + $plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][] + = $field; + } + // remove form + unset($plugin->fields[$n]); + } + else + { + // load the config form + if (!isset($plugin->config_fields[$form['fields_name']])) + { + $plugin->config_fields[$form['fields_name']] + = []; + } + if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']])) + { + $plugin->config_fields[$form['fields_name']][$form['fieldset']] + = []; + } + // do some house cleaning (for fields) + foreach ($form['fields'] as $field) + { + // so first we lock the field name in + $this->fieldName->get( + $field, $plugin->key, $unique + ); + // add the fields to the config builder + $plugin->config_fields[$form['fields_name']][$form['fieldset']][] + = $field; + } + // remove form + unset($plugin->fields[$n]); + } + } + else + { + unset($plugin->fields[$n]); + } + } + } + unset($plugin->fields); + + // set files and folders + $this->filesFolders->set($plugin); + + // add PHP in plugin install + $plugin->add_install_script = true; + $addScriptMethods = [ + 'php_preflight', + 'php_postflight', + 'php_method' + ]; + $addScriptTypes = [ + 'install', + 'update', + 'uninstall' + ]; + foreach ($addScriptMethods as $scriptMethod) + { + foreach ($addScriptTypes as $scriptType) + { + if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType}) + && $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1 + && StringHelper::check( + $plugin->{$scriptMethod . '_' . $scriptType} + )) + { + // set GUI mapper field + $guiMapper['field'] = $scriptMethod . '_' . $scriptType; + $plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + base64_decode( + (string) $plugin->{$scriptMethod . '_' . $scriptType} + ) + ) + ), + $guiMapper + ); + } + else + { + unset($plugin->{$scriptMethod . '_' . $scriptType}); + $plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0; + } + } + } + + // add_sql + if ($plugin->add_sql == 1 + && StringHelper::check($plugin->sql)) + { + $plugin->sql = $this->placeholder->update_( + $this->customcode->update(base64_decode((string) $plugin->sql)) + ); + } + else + { + unset($plugin->sql); + $plugin->add_sql = 0; + } + + // add_sql_uninstall + if ($plugin->add_sql_uninstall == 1 + && StringHelper::check( + $plugin->sql_uninstall + )) + { + $plugin->sql_uninstall = $this->placeholder->update_( + $this->customcode->update( + base64_decode((string) $plugin->sql_uninstall) + ) + ); + } + else + { + unset($plugin->sql_uninstall); + $plugin->add_sql_uninstall = 0; + } + + // update the URL of the update_server if set + if ($plugin->add_update_server == 1 + && StringHelper::check( + $plugin->update_server_url + )) + { + $plugin->update_server_url = $this->placeholder->update_( + $this->customcode->update($plugin->update_server_url) + ); + } + + // add the update/sales server FTP details if that is the expected protocol + $serverArray = array('update_server', 'sales_server'); + foreach ($serverArray as $server) + { + if ($plugin->{'add_' . $server} == 1 + && is_numeric( + $plugin->{$server} + ) + && $plugin->{$server} > 0) + { + // get the server protocol + $plugin->{$server . '_protocol'} + = GetHelper::var( + 'server', (int) $plugin->{$server}, 'id', 'protocol' + ); + } + else + { + $plugin->{$server} = 0; + // only change this for sales server (update server can be added locally to the zip file) + if ('sales_server' === $server) + { + $plugin->{'add_' . $server} = 0; + } + $plugin->{$server . '_protocol'} = 0; + } + } + + // set the update server stuff (TODO) + // update_server_xml_path + // update_server_xml_file_name + + // rest globals + $this->config->build_target = $_backup_target; + $this->config->lang_target = $_backup_lang; + $this->config->set('lang_prefix', $_backup_langPrefix); + + $this->placeholder->remove('Plugin_name'); + $this->placeholder->remove('Plugin'); + $this->placeholder->remove('plugin'); + $this->placeholder->remove('Plugin_group'); + $this->placeholder->remove('plugin_group'); + $this->placeholder->remove('plugin.version'); + $this->placeholder->remove('plugin_version'); + $this->placeholder->remove('VERSION'); + $this->placeholder->remove('DESCRIPTION'); + $this->placeholder->remove('PLUGIN_NAME'); + + $this->data[$id] = $plugin; + + return true; + } + } + + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/Structure.php new file mode 100644 index 000000000..0ef09749f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/Structure.php @@ -0,0 +1,747 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin; + + +use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Data as Plugin; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\FileHelper; + + +/** + * Joomla Plugin Builder Class + * + * @since 3.2.0 + */ +class Structure +{ + /** + * The Data Class. + * + * @var Plugin + * @since 3.2.0 + */ + protected Plugin $plugin; + + /** + * The Component Class. + * + * @var Component + * @since 3.2.0 + */ + protected Component $component; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Registry Class. + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * The Dispenser Class. + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * The Folder Class. + * + * @var Folder + * @since 3.2.0 + */ + protected Folder $folder; + + /** + * The File Class. + * + * @var File + * @since 3.2.0 + */ + protected File $file; + + /** + * The Files Class. + * + * @var Files + * @since 3.2.0 + */ + protected Files $files; + + /** + * Constructor. + * + * @param Plugin $plugin The Data Class. + * @param Component $component The Component Class. + * @param Config $config The Config Class. + * @param Registry $registry The Registry Class. + * @param Dispenser $dispenser The Dispenser Class. + * @param Event $event The EventInterface Class. + * @param Counter $counter The Counter Class. + * @param Folder $folder The Folder Class. + * @param File $file The File Class. + * @param Files $files The Files Class. + * + * @since 3.2.0 + */ + public function __construct(Plugin $plugin, Component $component, Config $config, + Registry $registry, Dispenser $dispenser, Event $event, + Counter $counter, Folder $folder, File $file, + Files $files) + { + $this->plugin = $plugin; + $this->component = $component; + $this->config = $config; + $this->registry = $registry; + $this->dispenser = $dispenser; + $this->event = $event; + $this->counter = $counter; + $this->folder = $folder; + $this->file = $file; + $this->files = $files; + } + + /** + * Build the Plugins files, folders, url's and config + * + * @return void + * @since 3.2.0 + */ + public function build() + { + if ($this->plugin->exists()) + { + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + $plugins = $this->plugin->get(); + + // Trigger Event: jcb_ce_onBeforeSetPlugins + $this->event->trigger( + 'jcb_ce_onBeforeBuildPlugins', + array(&$component_context, &$plugins) + ); + + foreach ($plugins as $plugin) + { + if (ObjectHelper::check($plugin) + && isset($plugin->folder_name) + && StringHelper::check($plugin->folder_name)) + { + // plugin path + $this->pluginPath($plugin); + + // set the plugin paths + $this->registry->set('dynamic_paths.' . $plugin->key, $plugin->folder_path); + + // make sure there is no old build + $this->folder->remove($plugin->folder_path); + + // creat the main component folder + $this->folder->create($plugin->folder_path); + + // set main class file + $this->setMainClassFile($plugin); + + // set main xml file + $this->setMainXmlFile($plugin); + + // set install script if needed + $this->setInstallScript($plugin); + + // set readme if found + $this->setReadme($plugin); + + // set fields & rules folders if needed + if (isset($plugin->fields_rules_paths) + && $plugin->fields_rules_paths == 2) + { + // create fields folder + $this->folder->create($plugin->folder_path . '/fields'); + + // create rules folder + $this->folder->create($plugin->folder_path . '/rules'); + } + + // set forms folder if needed + $this->setForms($plugin); + + // set SQL stuff if needed + $this->setSQL($plugin); + + // creat the language folder path + $this->folder->create($plugin->folder_path . '/language'); + + // also creat the lang tag folder path + $this->folder->create( + $plugin->folder_path . '/language/' . $this->config->get('lang_tag', 'en-GB') + ); + + // check if this plugin has files + $this->setFiles($plugin); + + // check if this plugin has folders + $this->setFolders($plugin); + + // check if this plugin has urls + $this->setUrls($plugin); + } + } + } + } + + /** + * get the plugin xml template + * + * @param object $plugin The plugin object + * + * @return string + * @since 3.2.0 + */ + protected function getXML(object $plugin): string + { + $xml = ''; + $xml .= PHP_EOL . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . $plugin->lang_prefix + . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('BUILDDATE') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('AUTHOR') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('AUTHOREMAIL') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('AUTHORWEBSITE') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('COPYRIGHT') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . Placefix::_h('LICENSE') . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . $plugin->plugin_version + . ''; + $xml .= PHP_EOL . Indent::_(1) . '' . $plugin->lang_prefix + . '_XML_DESCRIPTION'; + $xml .= Placefix::_h('MAINXML'); + $xml .= PHP_EOL . ''; + + return $xml; + } + + /** + * set the plugin path + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function pluginPath(object &$plugin): void + { + $plugin->folder_path = $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/' + . $plugin->folder_name; + } + + /** + * set the main class path + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setMainClassFile(object $plugin): void + { + $file_details = [ + 'path' => $plugin->folder_path . '/' . $plugin->file_name . '.php', + 'name' => $plugin->file_name . '.php', + 'zip' => $plugin->file_name . '.php' + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($plugin->key, $file_details); + + // count the file created + $this->counter->file++; + } + + /** + * set the main xml file + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setMainXmlFile(mixed $plugin): void + { + $file_details = [ + 'path' => $plugin->folder_path . '/' . $plugin->file_name . '.xml', + 'name' => $plugin->file_name . '.xml', + 'zip' => $plugin->file_name . '.xml' + ]; + + $this->file->write( + $file_details['path'], + $this->getXML($plugin) + ); + + $this->files->appendArray($plugin->key, $file_details); + + // count the file created + $this->counter->file++; + } + + /** + * set the install script file + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setInstallScript(object $plugin): void + { + if ($plugin->add_install_script) + { + $file_details = [ + 'path' => $plugin->folder_path . '/script.php', + 'name' => 'script.php', + 'zip' => 'script.php' + ]; + + $this->file->write( + $file_details['path'], + 'files->appendArray($plugin->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + + /** + * set the readme file + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setReadme(object $plugin): void + { + if ($plugin->addreadme) + { + $file_details = [ + 'path' => $plugin->folder_path . '/README.md', + 'name' => 'README.md', + 'zip' => 'README.md' + ]; + + $this->file->write($file_details['path'], $plugin->readme); + $this->files->appendArray($plugin->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + + /** + * set the form files and folders + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setForms(object $plugin): void + { + if (isset($plugin->form_files) + && ArrayHelper::check($plugin->form_files)) + { + // create forms folder + $this->folder->create($plugin->folder_path . '/forms'); + + // set the template files + foreach ($plugin->form_files as $file => $fields) + { + // set file details + $file_details = [ + 'path' => $plugin->folder_path . '/forms/' . $file . '.xml', + 'name' => $file . '.xml', + 'zip' => 'forms/' . $file . '.xml' + ]; + + // build basic XML + $xml = ''; + $xml .= PHP_EOL . ''; + + // search if we must add the component path + $add_component_path = false; + foreach ($fields as $field_name => $fieldsets) + { + if (!$add_component_path) + { + foreach ($fieldsets as $fieldset => $field) + { + if (!$add_component_path + && isset($plugin->fieldsets_paths[$file . $field_name . $fieldset]) + && $plugin->fieldsets_paths[$file. $field_name . $fieldset] == 1) + { + $add_component_path = true; + } + } + } + } + + // only add if part of the component field types path is required + if ($add_component_path) + { + $xml .= PHP_EOL . ''; + } + else + { + $xml .= PHP_EOL . '
'; + } + + // add the fields + foreach ($fields as $field_name => $fieldsets) + { + // check if we have an double fields naming set + $field_name_inner = ''; + $field_name_outer = $field_name; + if (strpos((string)$field_name, '.') !== false) + { + $field_names = explode('.', (string)$field_name); + if (count((array)$field_names) == 2) + { + $field_name_outer = $field_names[0]; + $field_name_inner = $field_names[1]; + } + } + $xml .= PHP_EOL . Indent::_(1) + . ''; + foreach ($fieldsets as $fieldset => $field) + { + // default to the field set name + $label = $fieldset; + if (isset($plugin->fieldsets_label[$file . $field_name . $fieldset])) + { + $label = $plugin->fieldsets_label[$file . $field_name . $fieldset]; + } + + // add path to plugin rules and custom fields + if (isset($plugin->fieldsets_paths[$file . $field_name . $fieldset]) + && ($plugin->fieldsets_paths[$file . $field_name . $fieldset] == 2 + || $plugin->fieldsets_paths[$file . $field_name . $fieldset] == 3)) + { + if (!isset($plugin->add_rule_path[$file . $field_name . $fieldset])) + { + $plugin->add_rule_path[$file . $field_name . $fieldset] = + '/plugins/' . strtolower((string)$plugin->group) . '/' + . strtolower((string)$plugin->code_name) . '/rules'; + } + + if (!isset($plugin->add_field_path[$file . $field_name . $fieldset])) + { + $plugin->add_field_path[$file . $field_name . $fieldset] = + '/plugins/' . strtolower((string)$plugin->group + ) . '/' . strtolower((string)$plugin->code_name) + . '/fields'; + } + } + + // add path to plugin rules and custom fields + if (isset($plugin->add_rule_path[$file . $field_name . $fieldset]) + || isset($plugin->add_field_path[$file . $field_name . $fieldset])) + { + $xml .= PHP_EOL . Indent::_(1) . ''; + + $xml .= PHP_EOL . Indent::_(1) . '
add_rule_path[$file . $field_name . $fieldset])) + { + $xml .= PHP_EOL . Indent::_(2) + . 'addrulepath="' . $plugin->add_rule_path[$file . $field_name . $fieldset] . '"'; + } + + if (isset($plugin->add_field_path[$file . $field_name . $fieldset])) + { + $xml .= PHP_EOL . Indent::_(2) + . 'addfieldpath="' . $plugin->add_field_path[$file . $field_name . $fieldset] . '"'; + } + + $xml .= PHP_EOL . Indent::_(1) . '>'; + } + else + { + $xml .= PHP_EOL . Indent::_(1) . '
'; + } + + // check if we have an inner field set + if (StringHelper::check($field_name_inner)) + { + $xml .= PHP_EOL . Indent::_(1) + . ''; + } + + // add the placeholder of the fields + $xml .= Placefix::_h('FIELDSET_' . $file + . $field_name . $fieldset); + + // check if we have an inner field set + if (StringHelper::check($field_name_inner)) + { + $xml .= PHP_EOL . Indent::_(1) + . ''; + } + $xml .= PHP_EOL . Indent::_(1) + . '
'; + } + $xml .= PHP_EOL . Indent::_(1) . ''; + } + $xml .= PHP_EOL . ''; + + // add xml to file + $this->file->write($file_details['path'], $xml); + $this->files->appendArray($plugin->key, $file_details); + + // count the file created + $this->counter->file++; + } + } + } + + /** + * set the sql stuff + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setSQL(object $plugin): void + { + if ($plugin->add_sql || $plugin->add_sql_uninstall) + { + // create SQL folder + $this->folder->create($plugin->folder_path . '/sql'); + + // create mysql folder + $this->folder->create( + $plugin->folder_path . '/sql/mysql' + ); + + // now set the install file + if ($plugin->add_sql) + { + $this->file->write( + $plugin->folder_path . '/sql/mysql/install.sql', + $plugin->sql + ); + + // count the file created + $this->counter->file++; + } + + // now set the uninstall file + if ($plugin->add_sql_uninstall) + { + $this->file->write( + $plugin->folder_path + . '/sql/mysql/uninstall.sql', + $plugin->sql_uninstall + ); + + // count the file created + $this->counter->file++; + } + } + } + + /** + * set the files + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setFiles(object $plugin): void + { + if (isset($plugin->files) && ArrayHelper::check($plugin->files)) + { + // add to component files + foreach ($plugin->files as $file) + { + // set the path finder + $file['target_type'] = $plugin->target_type; + $file['target_id'] = $plugin->id; + + $this->component->appendArray('files', $file); + } + } + } + + /** + * set the folders + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setFolders(object $plugin): void + { + if (isset($plugin->folders) && ArrayHelper::check($plugin->folders)) + { + // add to component folders + foreach ($plugin->folders as $folder) + { + // set the path finder + $folder['target_type'] = $plugin->target_type; + $folder['target_id'] = $plugin->id; + + $this->component->appendArray('folders', $folder); + } + } + } + + /** + * set the urls + * + * @param object $plugin The plugin object + * + * @return void + * @since 3.2.0 + */ + protected function setUrls(object &$plugin): void + { + if (isset($plugin->urls) && ArrayHelper::check($plugin->urls)) + { + // add to component urls + foreach ($plugin->urls as &$url) + { + // should we add the local folder + if (isset($url['type']) && $url['type'] > 1 + && isset($url['url']) + && StringHelper::check($url['url'])) + { + // set file name + $fileName = basename((string)$url['url']); + + // get the file contents + $data = FileHelper::getContent( + $url['url'] + ); + + // build sub path + if (strpos($fileName, '.js') !== false) + { + $path = '/js'; + } + elseif (strpos($fileName, '.css') !== false) + { + $path = '/css'; + } + else + { + $path = ''; + } + + // create sub media folder path if not set + $this->folder->create( + $plugin->folder_path . $path + ); + + // set the path to plugin file + $url['path'] = $plugin->folder_path . $path + . '/' . $fileName; // we need this for later + + // write data to path + $this->file->write($url['path'], $data); + + // count the file created + $this->counter->file++; + } + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Joomlaplugin/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language.php new file mode 100644 index 000000000..8370943a1 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language.php @@ -0,0 +1,202 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\LanguageInterface; + + +/** + * Compiler Language Content + * + * @since 3.2.0 + */ +class Language implements LanguageInterface +{ + /** + * The language content + * + * @var array + * @since 3.2.0 + **/ + protected array $content = []; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Constructor. + * + * @param Config|null $config The compiler config object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null) + { + $this->config = $config ?: Compiler::_('Config'); + } + + /** + * Get the language string key + * + * @param string $string The plan text string (English) + * + * @return string The key language string (all uppercase) + * @since 3.2.0 + */ + public function key($string): string + { + // this is there to insure we don't break already added Language strings + if (StringHelper::safe($string, 'U', '_', false, false) + === $string) + { + return false; + } + + // build language key + $key_lang = $this->config->lang_prefix . '_' . StringHelper::safe( + $string, 'U' + ); + + // set the language string + $this->set($this->config->lang_target, $key_lang, $string); + + return $key_lang; + } + + /** + * check if the language string exist + * + * @param string $target The target area for the language string + * @param string|null $language The language key string + * + * @return bool + * @since 3.2.0 + */ + public function exist(string $target, ?string $language = null): bool + { + if ($language) + { + return isset($this->content[$target][$language]); + } + + return isset($this->content[$target]); + } + + /** + * get the language string + * + * @param string $target The target area for the language string + * @param string|null $language The language key string + * + * @return Mixed The language string found or empty string if none is found + * @since 3.2.0 + */ + public function get(string $target, string $language): string + { + if (isset($this->content[$target][$language])) + { + return $this->content[$target][$language]; + } + + return ''; + } + + /** + * get target array + * + * @param string $target The target area for the language string + * + * @return array The target array or empty array if none is found + * @since 3.2.0 + */ + public function getTarget(string $target): array + { + if (isset($this->content[$target]) && ArrayHelper::check($this->content[$target])) + { + return $this->content[$target]; + } + + return []; + } + + /** + * set target array + * + * @param string $target The target area for the language string + * @param array|null $content The language content string + * + * @return void + * @since 3.2.0 + */ + public function setTarget(string $target, ?array $content) + { + $this->content[$target] = $content; + } + + /** + * set the language content values to language content array + * + * @param string $target The target area for the language string + * @param string $language The language key string + * @param string $string The language string + * @param bool $addPrefix The switch to add langPrefix + * + * @return void + * @since 3.2.0 + */ + public function set(string $target, string $language, string $string, bool $addPrefix = false) + { + if ($addPrefix && empty( + $this->content[$target][$this->config->lang_prefix . '_' . $language] + )) + { + $this->content[$target][$this->config->lang_prefix . '_' . $language] + = $this->fix($string); + } + elseif (empty($this->content[$target][$language])) + { + $this->content[$target][$language] = $this->fix( + $string + ); + } + } + + /** + * We need to remove all text breaks from all language strings + * + * @param string $string The language string + * + * @return string + * @since 3.2.0 + */ + protected function fix(string $string): string + { + if ($this->config->remove_line_breaks) + { + return trim(str_replace(array(PHP_EOL, "\r", "\n"), '', $string)); + } + + return trim($string); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/Extractor.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/Extractor.php new file mode 100644 index 000000000..567e9afb8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/Extractor.php @@ -0,0 +1,246 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Language; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Compiler Language Extractor + * + * @since 3.2.0 + */ +class Extractor +{ + /** + * The lang keys for extensions + * + * @var array + * @since 3.2.0 + **/ + public array $langKeys = []; + + /** + * The Language JS matching check + * + * @var array + * @since 3.2.0 + **/ + public array $langMismatch = []; + + /** + * The Language SC matching check + * + * @var array + * @since 3.2.0 + **/ + public array $langMatch = []; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Language $language The Language Class. + * @param Placeholder $placeholder The Placeholder Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Language $language, + Placeholder $placeholder) + { + $this->config = $config; + $this->language = $language; + $this->placeholder = $placeholder; + } + + /** + * Extract Language Strings + * + * @param string $content The content + * + * @return string The content with the updated Language place holder + * @since 3.2.0 + */ + public function engine(string $content): string + { + // get targets to search for + $lang_string_targets = array_filter( + $this->config->lang_string_targets, fn($get): bool => strpos($content, (string) $get) !== false + ); + // check if we should continue + if (ArrayHelper::check($lang_string_targets)) + { + // insure string is not broken + $content = $this->placeholder->update_($content); + // reset some buckets + $lang_holders = []; + $lang_check = []; + $lang_only = []; + $js_text = []; + $sc_text = []; + // first get the Joomla .JText._() + if (in_array('Joomla' . '.JText._(', $lang_string_targets)) + { + $js_text[] = GetHelper::allBetween( + $content, "Joomla" . ".JText._('", "'" + ); + $js_text[] = GetHelper::allBetween( + $content, 'Joomla' . '.JText._("', '"' + ); + // combine into one array + $js_text = ArrayHelper::merge($js_text); + // we need to add a check to insure these JavaScript lang matchup + if (ArrayHelper::check( + $js_text + )) //<-- not really needed hmmm + { + // load the JS text to mismatch array + $lang_check[] = $js_text; + $this->langMismatch = ArrayHelper::merge( + array($js_text, $this->langMismatch) + ); + } + } + // now get the JText: :script() + if (in_array('JText:' . ':script(', $lang_string_targets)) + { + $sc_text[] = GetHelper::allBetween( + $content, "JText:" . ":script('", "'" + ); + $sc_text[] = GetHelper::allBetween( + $content, 'JText:' . ':script("', '"' + ); + // combine into one array + $sc_text = ArrayHelper::merge($sc_text); + // we need to add a check to insure these JavaScript lang matchup + if (ArrayHelper::check($sc_text)) + { + // load the Script text to match array + $lang_check[] = $sc_text; + $this->langMatch = ArrayHelper::merge( + array($sc_text, $this->langMatch) + ); + } + } + // now do the little trick for JustTEXT: :_('Just uppercase text'); + if (in_array('JustTEXT:' . ':_(', $lang_string_targets)) + { + $lang_only[] = GetHelper::allBetween( + $content, "JustTEXT:" . ":_('", "')" + ); + $lang_only[] = GetHelper::allBetween( + $content, 'JustTEXT:' . ':_("', '")' + ); + // merge lang only + $lang_only = ArrayHelper::merge($lang_only); + } + // set language data + foreach ($lang_string_targets as $lang_string_target) + { + // need some special treatment here + if ($lang_string_target === 'Joomla' . '.JText._(' + || $lang_string_target === 'JText:' . ':script(' + || $lang_string_target === 'JustTEXT:' . ':_(') + { + continue; + } + $lang_check[] = GetHelper::allBetween( + $content, $lang_string_target . "'", "'" + ); + $lang_check[] = GetHelper::allBetween( + $content, $lang_string_target . '"', '"' + ); + } + // the normal loading of the language strings + $lang_check = ArrayHelper::merge($lang_check); + if (ArrayHelper::check( + $lang_check + )) //<-- not really needed hmmm + { + foreach ($lang_check as $string) + { + if ($key_lang = $this->language->key($string)) + { + // load the language targets + foreach ($lang_string_targets as $lang_string_target) + { + // need some special treatment here + if ($lang_string_target === 'JustTEXT:' . ':_(') + { + continue; + } + $lang_holders[$lang_string_target . "'" . $string + . "'"] + = $lang_string_target . "'" . $key_lang . "'"; + $lang_holders[$lang_string_target . '"' . $string + . '"'] + = $lang_string_target . '"' . $key_lang . '"'; + } + } + } + } + // the uppercase loading only (for arrays and other tricks) + if (ArrayHelper::check($lang_only)) + { + foreach ($lang_only as $string) + { + if ($key_lang = $this->language->key($string)) + { + // load the language targets + $lang_holders["JustTEXT:" . ":_('" . $string . "')"] + = "'" . $key_lang . "'"; + $lang_holders['JustTEXT:' . ':_("' . $string . '")'] + = '"' . $key_lang . '"'; + } + } + } + // only continue if we have value to replace + if (ArrayHelper::check($lang_holders)) + { + $content = $this->placeholder->update($content, $lang_holders); + } + } + + return $content; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/Fieldset.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/Fieldset.php new file mode 100644 index 000000000..883d75e65 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/Fieldset.php @@ -0,0 +1,264 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Language; + + +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MetaData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitchList; + + +/** + * Compiler Language Fieldset + * + * @since 3.2.0 + */ +class Fieldset +{ + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The MetaData Class. + * + * @var MetaData + * @since 3.2.0 + */ + protected MetaData $metadata; + + /** + * The AccessSwitch Class. + * + * @var AccessSwitch + * @since 3.2.0 + */ + protected AccessSwitch $accessswitch; + + /** + * The AccessSwitchList Class. + * + * @var AccessSwitchList + * @since 3.2.0 + */ + protected AccessSwitchList $accessswitchlist; + + /** + * Constructor. + * + * @param Language $language The Language Class. + * @param MetaData $metadata The MetaData Class. + * @param AccessSwitch $accessswitch The AccessSwitch Class. + * @param AccessSwitchList $accessswitchlist The AccessSwitchList Class. + * + * @since 3.2.0 + */ + public function __construct(Language $language, MetaData $metadata, + AccessSwitch $accessswitch, + AccessSwitchList $accessswitchlist) + { + $this->language = $language; + $this->metadata = $metadata; + $this->accessswitch = $accessswitch; + $this->accessswitchlist = $accessswitchlist; + } + + /** + * Set the fieldset language + * + * @param bool $access The access switch + * @param bool $metadata The metadata switch + * @param string $langTarget The language target + * @param string $langView The single language view name + * @param string $langViews The list language view name + * @param string $nameSingle The single view name + * @param string $nameList The list view name + * @param string $nameSingleCode The single view code name + * @param string $nameListCode The list view code name + * + * @return void + * @since 3.2.0 + */ + public function set(bool $access, bool $metadata, string $langTarget, string $langView, string $langViews, + string $nameSingle, string $nameList, string $nameSingleCode, string $nameListCode): void + { + // add metadata to the view + if ($metadata) + { + $this->metadata->set($nameSingleCode, $nameListCode); + } + + // add access to the view + if ($access) + { + $this->accessswitch->set($nameSingleCode, true); + $this->accessswitchlist->set($nameListCode, true); + } + + // set default lang + $this->language->set( + $langTarget, $langView, $nameSingle + ); + $this->language->set( + $langTarget, $langViews, $nameList + ); + // set global item strings + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_ARCHIVED', + "%s " . $nameList . " archived." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_ARCHIVED_1', + "%s " . $nameSingle . " archived." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_CHECKED_IN_0', + "No " . $nameSingle + . " successfully checked in." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_CHECKED_IN_1', + "%d " . $nameSingle + . " successfully checked in." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_CHECKED_IN_MORE', + "%d " . $nameList + . " successfully checked in." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_DELETED', + "%s " . $nameList . " deleted." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_DELETED_1', + "%s " . $nameSingle . " deleted." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_FEATURED', + "%s " . $nameList . " featured." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_FEATURED_1', + "%s " . $nameSingle . " featured." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_PUBLISHED', + "%s " . $nameList . " published." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_PUBLISHED_1', + "%s " . $nameSingle . " published." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_TRASHED', + "%s " . $nameList . " trashed." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_TRASHED_1', + "%s " . $nameSingle . " trashed." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_UNFEATURED', + "%s " . $nameList . " unfeatured." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_UNFEATURED_1', + "%s " . $nameSingle . " unfeatured." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_UNPUBLISHED', + "%s " . $nameList . " unpublished." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_UNPUBLISHED_1', + "%s " . $nameSingle . " unpublished." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_FAILED_PUBLISHING', + "%s " . $nameList . " failed publishing." + ); + $this->language->set( + $langTarget, $langViews . '_N_ITEMS_FAILED_PUBLISHING_1', + "%s " . $nameSingle . " failed publishing." + ); + $this->language->set( + $langTarget, $langViews . '_BATCH_OPTIONS', + "Batch process the selected " . $nameList + ); + $this->language->set( + $langTarget, $langViews . '_BATCH_TIP', + "All changes will be applied to all selected " + . $nameList + ); + // set some basic defaults + $this->language->set( + $langTarget, $langView . '_ERROR_UNIQUE_ALIAS', + "Another " . $nameSingle + . " has the same alias." + ); + $this->language->set( + $langTarget, $langView . '_CREATED_DATE_LABEL', "Created Date" + ); + $this->language->set( + $langTarget, $langView . '_CREATED_DATE_DESC', + "The date this " . $nameSingle + . " was created." + ); + $this->language->set( + $langTarget, $langView . '_MODIFIED_DATE_LABEL', "Modified Date" + ); + $this->language->set( + $langTarget, $langView . '_MODIFIED_DATE_DESC', + "The date this " . $nameSingle + . " was modified." + ); + $this->language->set( + $langTarget, $langView . '_CREATED_BY_LABEL', "Created By" + ); + $this->language->set( + $langTarget, $langView . '_CREATED_BY_DESC', + "The user that created this " . $nameSingle + . "." + ); + $this->language->set( + $langTarget, $langView . '_MODIFIED_BY_LABEL', "Modified By" + ); + $this->language->set( + $langTarget, $langView . '_MODIFIED_BY_DESC', + "The last user that modified this " + . $nameSingle . "." + ); + $this->language->set( + $langTarget, $langView . '_ORDERING_LABEL', "Ordering" + ); + $this->language->set( + $langTarget, $langView . '_VERSION_LABEL', "Version" + ); + $this->language->set( + $langTarget, $langView . '_VERSION_DESC', + "A count of the number of times this " + . $nameSingle . " has been revised." + ); + $this->language->set( + $langTarget, $langView . '_SAVE_WARNING', + "Alias already existed so a number was added at the end. You can re-edit the " + . $nameSingle . " to customise the alias." + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Language/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/Data.php new file mode 100644 index 000000000..ab2710160 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/Data.php @@ -0,0 +1,356 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Library; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Field\Data as FieldData; +use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Library Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Field Data + * + * @var FieldData + * @since 3.2.0 + */ + protected FieldData $field; + + /** + * Compiler Files Folders + * + * @var Filesfolders + * @since 3.2.0 + */ + protected Filesfolders $filesFolders; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param FieldData|null $field The compiler field data object. + * @param Filesfolders|null $filesFolders The compiler files folders object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Registry $registry = null, + ?Customcode $customcode = null, ?Gui $gui = null, + ?FieldData $field = null, ?Filesfolders $filesFolders = null, + ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->field = $field ?: Compiler::_('Field.Data'); + $this->filesFolders = $filesFolders ?: Compiler::_('Model.Filesfolders'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Media Library Data and store globally in registry + * + * @param int $id the library id + * + * @return object|bool object on success + * @since 3.2.0 + */ + public function get(int $id) + { + // check if the lib has already been set + if (!$this->registry->exists("builder.libraries.$id")) + { + // get some switches + $uikit = $this->config->get('uikit', 0); + $footable_version = $this->config->get('footable_version', 0); + + // make sure we should continue and that the lib is not already being loaded + switch ($id) + { + case 1: // No Library + return false; + break; + case 3: // Uikit v3 + if (2 == $uikit || 3 == $uikit) + { + // already being loaded + $this->registry->set("builder.libraries.$id", false); + } + break; + case 4: // Uikit v2 + if (2 == $uikit || 1 == $uikit) + { + // already being loaded + $this->registry->set("builder.libraries.$id", false); + } + break; + case 5: // FooTable v2 + if (2 == $footable_version) + { + // already being loaded + $this->registry->set("builder.libraries.$id", false); + } + break; + case 6: // FooTable v3 + if (3 == $footable_version) + { + // already being loaded + $this->registry->set("builder.libraries.$id", false); + } + break; + } + } + + // check if the lib has already been set + if (!$this->registry->exists("builder.libraries.$id")) + { + $query = $this->db->getQuery(true); + + $query->select('a.*'); + $query->select( + $this->db->quoteName( + array( + 'a.id', + 'a.name', + 'a.how', + 'a.type', + 'a.addconditions', + 'b.addconfig', + 'c.addfiles', + 'c.addfolders', + 'c.addfilesfullpath', + 'c.addfoldersfullpath', + 'c.addurls', + 'a.php_setdocument' + ), array( + 'id', + 'name', + 'how', + 'type', + 'addconditions', + 'addconfig', + 'addfiles', + 'addfolders', + 'addfilesfullpath', + 'addfoldersfullpath', + 'addurls', + 'php_setdocument' + ) + ) + ); + + // from these tables + $query->from('#__componentbuilder_library AS a'); + $query->join( + 'LEFT', + $this->db->quoteName('#__componentbuilder_library_config', 'b') + . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('b.library') . ')' + ); + $query->join( + 'LEFT', $this->db->quoteName( + '#__componentbuilder_library_files_folders_urls', 'c' + ) . ' ON (' . $this->db->quoteName('a.id') . ' = ' + . $this->db->quoteName('c.library') . ')' + ); + $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); + $query->where($this->db->quoteName('a.target') . ' = 1'); + + // Reset the query using our newly populated query object. + $this->db->setQuery($query); + + // Load the results as a list of stdClass objects + $library = $this->db->loadObject(); + + // check if this lib uses build-in behaviour + if ($library->how == 4) + { + // fall back on build-in features + $buildin = [ + 3 => ['uikit' => 3], + 4 => ['uikit' => 1], + 5 => ['footable_version' => 2, 'footable' => true], + 6 => ['footable_version' => 3, 'footable' => true] + ]; + + if (isset($buildin[$library->id]) + && ArrayHelper::check( + $buildin[$library->id] + )) + { + // set the lib switch + foreach ($buildin[$library->id] as $lib => $val) + { + // ---- we are targeting these ---- + // $this->config->uikit + // $this->config->footable_version + // $this->config->footable + $this->config->set($lib, $val); + } + // since we are falling back on build-in feature + $library->how = 0; + } + else + { + // since we did not find build in behaviour we must load always. + $library->how = 1; + } + } + + // check if this lib has dynamic behaviour + if ($library->how > 0) + { + // set files and folders + $this->filesFolders->set($library); + + // add config fields only if needed + if ($library->how > 1) + { + // set the config data + $library->addconfig = (isset($library->addconfig) + && JsonHelper::check( + $library->addconfig + )) ? json_decode((string) $library->addconfig, true) : null; + + if (ArrayHelper::check($library->addconfig)) + { + $library->config = array_map( + function ($array) { + $array['alias'] = 0; + $array['title'] = 0; + $array['settings'] = $this->field->get( + $array['field'] + ); + + return $array; + }, array_values($library->addconfig) + ); + } + } + // if this lib is controlled by custom script + if (3 == $library->how) + { + // set Needed PHP + if (isset($library->php_setdocument) + && StringHelper::check( + $library->php_setdocument + )) + { + $library->document = $this->gui->set( + $this->customcode->update( + base64_decode((string) $library->php_setdocument) + ), + array( + 'table' => 'library', + 'field' => 'php_setdocument', + 'id' => (int) $id, + 'type' => 'php') + ); + } + } + // if this lib is controlled by conditions + elseif (2 == $library->how) + { + // set the addconditions data + $library->addconditions = (isset($library->addconditions) + && JsonHelper::check( + $library->addconditions + )) ? json_decode((string) $library->addconditions, true) : null; + + if (ArrayHelper::check( + $library->addconditions + )) + { + $library->conditions = array_values( + $library->addconditions + ); + } + } + + unset($library->php_setdocument); + unset($library->addconditions); + unset($library->addconfig); + + // load to global lib + $this->registry->set("builder.libraries.$id", $library); + } + else + { + $this->registry->set("builder.libraries.$id", false); + } + } + + // if set return + return $this->registry->get("builder.libraries.$id", false); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/Structure.php new file mode 100644 index 000000000..3a18703f2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/Structure.php @@ -0,0 +1,314 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Library; + + +use Joomla\CMS\Filesystem\Folder as JoomlaFolder; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\FileHelper; + + +/** + * Library Structure Builder Class + * + * @since 3.2.0 + */ +class Structure +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Registry Class. + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * The Component Class. + * + * @var Component + * @since 3.2.0 + */ + protected Component $component; + + /** + * The ContentOne Class. + * + * @var Content + * @since 3.2.0 + */ + protected Content $content; + + /** + * The Counter Class. + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * The Paths Class. + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * The Folder Class. + * + * @var Folder + * @since 3.2.0 + */ + protected Folder $folder; + + /** + * The File Class. + * + * @var File + * @since 3.2.0 + */ + protected File $file; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Registry $registry The Registry Class. + * @param Event $event The EventInterface Class. + * @param Component $component The Component Class. + * @param Content $content The ContentOne Class. + * @param Counter $counter The Counter Class. + * @param Paths $paths The Paths Class. + * @param Folder $folder The Folder Class. + * @param File $file The File Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Registry $registry, Event $event, + Component $component, Content $content, Counter $counter, + Paths $paths, Folder $folder, File $file) + { + $this->config = $config; + $this->registry = $registry; + $this->event = $event; + $this->component = $component; + $this->content = $content; + $this->counter = $counter; + $this->paths = $paths; + $this->folder = $folder; + $this->file = $file; + } + + /** + * Build the Libraries files, folders, url's and config + * + * @return void + * @since 3.2.0 + */ + public function build() + { + if (($libraries_ = $this->registry->get('builder.libraries')) !== null) + { + // for plugin event TODO change event api signatures + $component_context = $this->config->component_context; + + // Trigger Event: jcb_ce_onBeforeSetLibraries + $this->event->trigger( + 'jcb_ce_onBeforeSetLibraries', + array(&$component_context, &$libraries_) + ); + + // creat the main component folder + if (!JoomlaFolder::exists($this->paths->component_path)) + { + JoomlaFolder::create($this->paths->component_path); + + // count the folder created + $this->counter->folder++; + $this->file->html(''); + } + + // create media path if not set + $this->folder->create($this->paths->component_path . '/media'); + foreach ($libraries_ as $id => &$library) + { + if (ObjectHelper::check($library)) + { + // check if this lib has files + if (isset($library->files) + && ArrayHelper::check($library->files)) + { + // add to component files + foreach ($library->files as $file) + { + $this->component->appendArray('files', $file); + } + } + + // check if this lib has folders + if (isset($library->folders) + && ArrayHelper::check( + $library->folders + )) + { + // add to component folders + foreach ($library->folders as $folder) + { + $this->component->appendArray('folders', $folder); + } + } + + // check if this lib has urls + if (isset($library->urls) + && ArrayHelper::check($library->urls)) + { + // build media folder path + $libFolder = strtolower( + preg_replace( + '/\s+/', '-', + (string) StringHelper::safe( + $library->name, 'filename', ' ', false + ) + ) + ); + $mediaPath = '/media/' . $libFolder; + + // should we add the local folder + $addLocalFolder = false; + + // add to component urls + foreach ($library->urls as $n => &$url) + { + if (isset($url['type']) && $url['type'] > 1 + && isset($url['url']) + && StringHelper::check( + $url['url'] + )) + { + // create media/lib path if not set + $this->folder->create( + $this->paths->component_path . $mediaPath + ); + + // add local folder + $addLocalFolder = true; + + // set file name + $fileName = basename((string) $url['url']); + + // get the file contents + $data = FileHelper::getContent( + $url['url'] + ); + + // build sub path + if (strpos($fileName, '.js') !== false) + { + $path = '/js'; + } + elseif (strpos($fileName, '.css') !== false) + { + $path = '/css'; + } + else + { + $path = ''; + } + + // create sub media path if not set + $this->folder->create( + $this->paths->component_path . $mediaPath . $path + ); + + // set the path to library file + $url['path'] = $mediaPath . $path . '/' + . $fileName; // we need this for later + + // set full path + $path = $this->paths->component_path . $url['path']; + + // write data to path + $this->file->write($path, $data); + + // count the file created + $this->counter->file++; + } + } + + // only add if local + if ($addLocalFolder) + { + // add folder to xml of media folders + $this->content->add('EXSTRA_MEDIA_FOLDERS', + PHP_EOL . Indent::_(2) . "" + . $libFolder . ""); + } + } + + // if config fields are found load into component config (avoiding duplicates) + if (isset($library->how) && $library->how > 1 + && isset($library->config) + && ArrayHelper::check($library->config)) + { + foreach ($library->config as $cofig) + { + $found = array_filter( + $this->component->get('config'), + fn($item) => $item['field'] == $cofig['field'] + ); + + // set the config data if not found + if (!ArrayHelper::check($found)) + { + $this->component->appendArray('config', $cofig); + } + } + } + + // update the global value just in case for now + $this->registry->set("builder.libraries.$id", $library); + } + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Library/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Adminviews.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Adminviews.php new file mode 100644 index 000000000..73cd0fb85 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Adminviews.php @@ -0,0 +1,190 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Adminview\Data as Admin; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteEditView; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AdminFilterType; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Model Admin Views Class + * + * @since 3.2.0 + */ +class Adminviews +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Data Class. + * + * @var Admin + * @since 3.2.0 + */ + protected Admin $admin; + + /** + * The SiteEditView Class. + * + * @var SiteEditView + * @since 3.2.0 + */ + protected SiteEditView $siteeditview; + + /** + * The AdminFilterType Class. + * + * @var AdminFilterType + * @since 3.2.0 + */ + protected AdminFilterType $adminfiltertype; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Admin $admin The Data Class. + * @param SiteEditView $siteeditview The SiteEditView Class. + * @param AdminFilterType $adminfiltertype The AdminFilterType Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Admin $admin, SiteEditView $siteeditview, AdminFilterType $adminfiltertype) + { + $this->config = $config; + $this->admin = $admin; + $this->siteeditview = $siteeditview; + $this->adminfiltertype = $adminfiltertype; + } + + /** + * Set admin view data + * + * @param object $item The extension data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addadmin_views = (isset($item->addadmin_views) + && JsonHelper::check($item->addadmin_views)) + ? json_decode((string) $item->addadmin_views, true) : null; + + if (ArrayHelper::check($item->addadmin_views)) + { + $this->config->lang_target = 'admin'; + $this->config->build_target = 'admin'; + + // sort the views according to order + usort( + $item->addadmin_views, function ($a, $b) { + if ($a['order'] != 0 && $b['order'] != 0) + { + return $a['order'] <=> $b['order']; + } + elseif ($b['order'] != 0 && $a['order'] == 0) + { + return 1; + } + elseif ($a['order'] != 0 && $b['order'] == 0) + { + return 0; + } + + return 1; + } + ); + + // build the admin_views settings + $item->admin_views = array_map( + function ($array) { + $array = array_map( + function ($value) { + if (!ArrayHelper::check($value) + && !ObjectHelper::check($value) + && strval($value) === strval(intval($value))) + { + return (int) $value; + } + + return $value; + }, $array + ); + + // check if we must add to site + if (isset($array['edit_create_site_view']) + && is_numeric($array['edit_create_site_view']) + && $array['edit_create_site_view'] > 0) + { + $this->siteeditview->set($array['adminview'], true); + $this->config->lang_target = 'both'; + } + + // set the import/export option for this view + if (isset($array['port']) && $array['port']) + { + $this->config->set('add_eximport', true); + } + + // set the history tracking option for this view + if (isset($array['history']) && $array['history']) + { + $this->config->set('set_tag_history', true); + } + + // set the custom field integration for this view + if (isset($array['joomla_fields']) && $array['joomla_fields']) + { + $this->config->set('set_joomla_fields', true); + } + + // has become a legacy issue, can't remove this + $array['view'] = $array['adminview']; + + // get the admin settings/data + $array['settings'] = $this->admin->get( + $array['view'] + ); + + // set the filter option for this view | Side (old) [default for now] + $this->adminfiltertype->set($array['settings']->name_list_code, 1); + + if (isset($array['filter']) + && is_numeric( + $array['filter'] + ) && $array['filter'] > 0) + { + $this->adminfiltertype->set($array['settings']->name_list_code, + (int) $array['filter']); + } + + return $array; + + }, array_values($item->addadmin_views) + ); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Ajaxadmin.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Ajaxadmin.php new file mode 100644 index 000000000..295a75247 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Ajaxadmin.php @@ -0,0 +1,172 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteEditView; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Admin Ajax Class + * + * @since 3.2.0 + */ +class Ajaxadmin +{ + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'admin_view', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The SiteEditView Class. + * + * @var SiteEditView + * @since 3.2.0 + */ + protected SiteEditView $siteeditview; + + /** + * The Dispenser Class. + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param SiteEditView $siteeditview The SiteEditView Class. + * @param Dispenser $dispenser The Dispenser Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, SiteEditView $siteeditview, Dispenser $dispenser) + { + $this->config = $config; + $this->siteeditview = $siteeditview; + $this->dispenser = $dispenser; + } + + /** + * Set Ajax Code + * + * @param object $item The item data + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'admin_view') + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + if (isset($item->add_php_ajax) && $item->add_php_ajax == 1) + { + // insure the token is added to edit view at least + $this->dispenser->hub['token'][$item->name_single_code] + = true; + + $add_ajax_site = false; + + if ($this->siteeditview->exists($item->id)) + { + // we should add this site ajax to front ajax + $add_ajax_site = true; + $this->config->set('add_site_ajax', true); + } + + // check if controller input as been set + $item->ajax_input = (isset($item->ajax_input) + && JsonHelper::check($item->ajax_input)) + ? json_decode((string) $item->ajax_input, true) : null; + + if (ArrayHelper::check($item->ajax_input)) + { + if ($add_ajax_site) + { + $this->dispenser->hub['site']['ajax_controller'][$item->name_single_code] + = array_values($item->ajax_input); + } + + $this->dispenser->hub['admin']['ajax_controller'][$item->name_single_code] + = array_values($item->ajax_input); + + $this->config->set('add_ajax', true); + + unset($item->ajax_input); + } + + if (StringHelper::check($item->php_ajaxmethod)) + { + // make sure we are still in PHP + $this->guiMapper['type'] = 'php'; + + // update GUI mapper field + $this->guiMapper['field'] = 'php_ajaxmethod'; + + $this->dispenser->set( + $item->php_ajaxmethod, + 'admin', + 'ajax_model', + $item->name_single_code, + $this->guiMapper + ); + + if ($add_ajax_site) + { + $this->dispenser->set( + $item->php_ajaxmethod, + 'site', + 'ajax_model', + $item->name_single_code, + $this->guiMapper, + false, + false + ); + } + + // switch ajax on + $this->config->set('add_ajax', true); + + // unset anyway + unset($item->php_ajaxmethod); + } + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Ajaxcustomview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Ajaxcustomview.php new file mode 100644 index 000000000..e4e0d39c8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Ajaxcustomview.php @@ -0,0 +1,151 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Custom Ajax Custom View Class + * + * @since 3.2.0 + */ +class Ajaxcustomview +{ + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'site_view', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Dispenser|null $dispenser The compiler customcode dispenser + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Dispenser $dispenser = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + } + + /** + * Set Ajax Code + * + * @param object $item The item data + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'site_view') + { + // add_Ajax for this view + if (isset($item->add_php_ajax) && $item->add_php_ajax == 1) + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + // ajax target (since we only have two options really) + if ('site' === $this->config->build_target) + { + $target = 'site'; + } + else + { + $target = 'admin'; + } + + $add_ajax_site = false; + + // check if controller input as been set + $item->ajax_input = (isset($item->ajax_input) + && JsonHelper::check($item->ajax_input)) + ? json_decode((string) $item->ajax_input, true) : null; + + if (ArrayHelper::check($item->ajax_input)) + { + $this->dispenser->hub[$target]['ajax_controller'][$item->code] + = array_values($item->ajax_input); + + $add_ajax_site = true; + } + unset($item->ajax_input); + + // load the ajax class mathods (if set) + if (StringHelper::check($item->php_ajaxmethod)) + { + // set field + $this->guiMapper['field'] = 'php_ajaxmethod'; + $this->dispenser->set( + $item->php_ajaxmethod, + $target, + 'ajax_model', + $item->code, + $this->guiMapper + ); + + $add_ajax_site = true; + } + unset($item->php_ajaxmethod); + + // should ajax be set + if ($add_ajax_site) + { + // turn on ajax area + if ('site' === $this->config->build_target) + { + $this->config->set('add_site_ajax', true); + } + else + { + $this->config->set('add_ajax', true); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Conditions.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Conditions.php new file mode 100644 index 000000000..e3e59d072 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Conditions.php @@ -0,0 +1,182 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Field\TypeName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups as FieldGroups; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; + + +/** + * Model Conditions Class + * + * @since 3.2.0 + */ +class Conditions +{ + /** + * Compiler Type Name + * + * @var TypeName + * @since 3.2.0 + */ + protected TypeName $typeName; + + /** + * Compiler Field Name + * + * @var FieldName + * @since 3.2.0 + */ + protected FieldName $fieldName; + + /** + * Compiler Field Groups + * + * @var FieldGroups + * @since 3.2.0 + */ + protected FieldGroups $fieldGroups; + + /** + * Constructor + * + * @param TypeName|null $typeName The compiler type name object. + * @param FieldName|null $fieldName The compiler field name object. + * @param FieldGroups|null $fieldGroups The compiler field groups object. + * + * @since 3.2.0 + */ + public function __construct(?TypeName $typeName = null, ?FieldName $fieldName = null, ?FieldGroups $fieldGroups = null) + { + $this->typeName = $typeName ?: Compiler::_('Field.Type.Name'); + $this->fieldName = $fieldName ?: Compiler::_('Field.Name'); + $this->fieldGroups = $fieldGroups ?: Compiler::_('Field.Groups'); + } + + /** + * Set the conditions + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addconditions = (isset($item->addconditions) + && JsonHelper::check($item->addconditions)) + ? json_decode((string) $item->addconditions, true) : null; + + if (ArrayHelper::check($item->addconditions)) + { + $item->conditions = []; + $ne = 0; + foreach ($item->addconditions as $nr => $conditionValue) + { + if (ArrayHelper::check( + $conditionValue['target_field'] + ) && ArrayHelper::check($item->fields)) + { + foreach ( $conditionValue['target_field'] as $fieldKey => $fieldId) + { + foreach ($item->fields as $fieldValues) + { + if ((int) $fieldValues['field'] == (int) $fieldId) + { + // load the field details + $required = GetHelper::between( + $fieldValues['settings']->xml, + 'required="', '"' + ); + + $required = ($required === 'true' + || $required === '1') ? 'yes' : 'no'; + + $filter = GetHelper::between( + $fieldValues['settings']->xml, + 'filter="', '"' + ); + + $filter = StringHelper::check( + $filter + ) ? $filter : 'none'; + + // set the field name + $conditionValue['target_field'][$fieldKey] = [ + 'name' => $this->fieldName->get( + $fieldValues, $item->name_list_code + ), + 'type' => $this->typeName->get( + $fieldValues + ), + 'required' => $required, + 'filter' => $filter + ]; + + break; + } + } + } + } + + // load match field + if (ArrayHelper::check($item->fields) + && isset($conditionValue['match_field'])) + { + foreach ($item->fields as $fieldValue) + { + if ((int) $fieldValue['field'] == (int) $conditionValue['match_field']) + { + // set the type + $type = $this->typeName->get($fieldValue); + // set the field details + $conditionValue['match_name'] = $this->fieldName->get( + $fieldValue, $item->name_list_code + ); + $conditionValue['match_type'] = $type; + $conditionValue['match_xml'] = $fieldValue['settings']->xml; + + // if custom field load field being extended + if (!$this->fieldGroups->check($type)) + { + $conditionValue['match_extends'] = GetHelper::between( + $fieldValue['settings']->xml, + 'extends="', '"' + ); + } + else + { + $conditionValue['match_extends'] = ''; + } + break; + } + } + } + + // set condition values + $item->conditions[$ne] = $conditionValue; + + $ne++; + } + } + + unset($item->addconditions); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Createdate.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Createdate.php new file mode 100644 index 000000000..ed522e1ea --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Createdate.php @@ -0,0 +1,58 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model - Get Create Date + * + * @since 3.2.0 + */ +class Createdate +{ + /** + * Get the create date of an item + * + * @param mixed $item The item data + * + * @return string The create data + * @since 3.2.0 + */ + public function get(&$item): string + { + if (is_array($item) && isset($item['settings']) && isset($item['settings']->created) + && StringHelper::check($item['settings']->created)) + { + // first set the main date + $date = strtotime((string) $item['settings']->created); + } + elseif (is_object($item) && isset($item->created) + && StringHelper::check($item->created)) + { + // first set the main date + $date = strtotime((string) $item->created); + } + else + { + // first set the main date + $date = strtotime("now"); + } + + return Factory::getDate($date)->format('jS F, Y'); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Cssadminview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Cssadminview.php new file mode 100644 index 000000000..e9855a1c6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Cssadminview.php @@ -0,0 +1,90 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model CSS Admin View Class + * + * @since 3.2.0 + */ +class Cssadminview +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = [ + 'css_view', 'css_views' + ]; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Constructor + * + * @param Dispenser|null $dispenser The compiler customcode dispenser + * + * @since 3.2.0 + */ + public function __construct(?Dispenser $dispenser = null) + { + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + } + + /** + * Set Admin View Css + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + foreach ($this->areas as $area) + { + if (isset($item->{'add_' . $area}) + && $item->{'add_' . $area} == 1 + && StringHelper::check($item->{$area})) + { + $this->dispenser->set( + $item->{$area}, + $area, + $item->name_single_code, + null, + ['prefix' => PHP_EOL], + true, + true, + true + ); + + unset($item->{$area}); + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Csscustomview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Csscustomview.php new file mode 100644 index 000000000..6dcdc3d5f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Csscustomview.php @@ -0,0 +1,79 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Css Custom View Class + * + * @since 3.2.0 + */ +class Csscustomview +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = ['css_document', 'css']; + + /** + * Compiler Customcode Class + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Constructor + * + * @param Customcode|null $customcode The compiler customcode object. + * + * @since 3.2.0 + */ + public function __construct(?Customcode $customcode = null) + { + $this->customcode = $customcode ?: Compiler::_('Customcode'); + } + + /** + * Set Css code + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + foreach ($this->areas as $area) + { + if (isset($item->{'add_' . $area}) + && $item->{'add_' . $area} == 1 + && StringHelper::check($item->{$area})) + { + $item->{$area} = $this->customcode->update( + base64_decode((string) $item->{$area}) + ); + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customadminviews.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customadminviews.php new file mode 100644 index 000000000..691343555 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customadminviews.php @@ -0,0 +1,109 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customview\Data as Customview; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Model Custom Admin Views Class + * + * @since 3.2.0 + */ +class Customadminviews +{ + /** + * Component custom admin view Data + * + * @var Customview + * @since 3.2.0 + **/ + protected Customview $customadmin; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Constructor + * + * @param Customview|null $customadmin The custom admin view data object. + * @param Config|null $config The compiler config object. + * + * @since 3.2.0 + */ + public function __construct(?Customview $customadmin = null, ?Config $config = null) + { + $this->customadmin = $customadmin ?: Compiler::_('Customview.Data'); + $this->config = $config ?: Compiler::_('Config'); + } + + /** + * Set custom admin view data + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addcustom_admin_views = (isset($item->addcustom_admin_views) + && JsonHelper::check($item->addcustom_admin_views)) + ? json_decode((string) $item->addcustom_admin_views, true) : null; + + if (ArrayHelper::check($item->addcustom_admin_views)) + { + $this->config->lang_target = 'admin'; + $this->config->build_target = 'custom_admin'; + + // build the site_views settings + $item->custom_admin_views = array_map( + function ($array) { + // has become a legacy issue, can't remove this + $array['view'] = $array['customadminview']; + $array['settings'] = $this->customadmin->get( + $array['view'], 'custom_admin_view' + ); + + return array_map( + function ($value) { + if (!ArrayHelper::check($value) + && !ObjectHelper::check($value) + && strval($value) === strval(intval($value))) + { + return (int) $value; + } + + return $value; + }, $array + ); + }, array_values($item->addcustom_admin_views) + ); + + // unset original value + unset($item->addcustom_admin_views); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customalias.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customalias.php new file mode 100644 index 000000000..1ed1042c8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customalias.php @@ -0,0 +1,108 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomAlias as BuilderCustomAlias; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Custom Alias Class + * + * @since 3.2.0 + */ +class Customalias +{ + /** + * The BuilderCustomAlias Class. + * + * @var BuilderCustomAlias + * @since 3.2.0 + */ + protected BuilderCustomAlias $customalias; + + /** + * The Name Class. + * + * @var FieldName + * @since 3.2.0 + */ + protected FieldName $fieldname; + + /** + * Constructor. + * + * @param BuilderCustomAlias $customalias The CustomAlias Class. + * @param FieldName $fieldname The Name Class. + * + * @since 3.2.0 + */ + public function __construct(BuilderCustomAlias $customalias, FieldName $fieldname) + { + $this->customalias = $customalias; + $this->fieldname = $fieldname; + } + + /** + * Set activate alias builder + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + if (!$this->customalias->get($item->name_single_code) + && isset($item->alias_builder_type) && 2 == $item->alias_builder_type + && isset($item->alias_builder) && JsonHelper::check($item->alias_builder)) + { + // get the aliasFields + $alias_fields = (array) json_decode((string) $item->alias_builder, true); + + // get the active fields + $alias_fields = (array) array_filter( + $item->fields, function ($field) use ($alias_fields) { + // check if field is in view fields + if (in_array($field['field'], $alias_fields)) + { + return true; + } + + return false; + } + ); + + // check if all is well + if (ArrayHelper::check($alias_fields)) + { + // load the field names + $this->customalias->set($item->name_single_code, + (array) array_map( + function ($field) use (&$item) { + return $this->fieldname->get( + $field, $item->name_list_code + ); + }, $alias_fields + ) + ); + } + } + + // unset + unset($item->alias_builder); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Custombuttons.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Custombuttons.php new file mode 100644 index 000000000..48bd93914 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Custombuttons.php @@ -0,0 +1,158 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Templatelayout\Data as Templatelayout; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Custom Buttons Class + * + * @since 3.2.0 + */ +class Custombuttons +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = [ + 'php_model', + 'php_controller', + 'php_model_list', + 'php_controller_list' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'admin_view', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Template Layout + * + * @var Templatelayout + * @since 3.2.0 + */ + protected Templatelayout $templateLayout; + + /** + * Constructor + * + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param Templatelayout|null $templateLayout The compiler template layout object. + * + * @since 3.2.0 + */ + public function __construct(?Customcode $customcode = null, ?Gui $gui = null, + ?Templatelayout $templateLayout = null) + { + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->templateLayout = $templateLayout ?: Compiler::_('Templatelayout.Data'); + } + + /** + * Set Custom Buttons and Model/Controllers + * + * @param object $item The item data + * @param object $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'admin_view') + { + if (isset($item->add_custom_button) + && $item->add_custom_button == 1) + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + // get the code + $code = $item->name_single_code ?? $item->code ?? 'error'; + + // set for the code + foreach ($this->areas as $area) + { + if (isset($item->{$area}) + && StringHelper::check( + $item->{$area} + )) + { + // set field + $this->guiMapper['field'] = $area; + $item->{$area} = $this->gui->set( + $this->customcode->update( + base64_decode((string) $item->{$area}) + ), + $this->guiMapper + ); + + // check if we have template or layouts to load + $this->templateLayout->set( + $item->{$area}, $code + ); + } + } + + // set the button array + $item->custom_button = (isset($item->custom_button) + && JsonHelper::check($item->custom_button)) + ? json_decode((string) $item->custom_button, true) : null; + + if (ArrayHelper::check($item->custom_button)) + { + $item->custom_buttons = array_values($item->custom_button); + } + + unset($item->custom_button); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customimportscripts.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customimportscripts.php new file mode 100644 index 000000000..baa5ca327 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customimportscripts.php @@ -0,0 +1,132 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * Model Custom Import Scripts Class + * + * @since 3.2.0 + */ +class Customimportscripts +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = [ + 'php_import_ext', + 'php_import_display', + 'php_import', + 'php_import_setdata', + 'php_import_save', + 'php_import_headers', + 'html_import_view' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'admin_view', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Constructor + * + * @param Dispenser|null $dispenser The compiler customcode dispenser + * + * @since 3.2.0 + */ + public function __construct(?Dispenser $dispenser = null) + { + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + } + + /** + * Set Custom Import Scripts + * + * @param object $item The item data + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'admin_view') + { + // set custom import scripts + if (isset($item->add_custom_import) + && $item->add_custom_import == 1) + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + foreach ($this->areas as $area) + { + if (isset($item->$area) + && StringHelper::check($item->$area)) + { + // update GUI mapper field + $this->guiMapper['field'] = $area; + $this->guiMapper['type'] = 'php'; + + // Make sure html gets HTML comment for placeholder + if ('html_import_view' === $area) + { + $this->guiMapper['type'] = 'html'; + } + + $this->dispenser->set( + $item->$area, + $area, + 'import_' . $item->name_list_code, + null, + $this->guiMapper + ); + + unset($item->$area); + } + else + { + // load the default TODO: convert getDynamicScripts to a class + $this->dispenser->hub[$area]['import_' . $item->name_list_code] + = Helper::_('getDynamicScripts', [$area, true]); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customtabs.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customtabs.php new file mode 100644 index 000000000..00fecb922 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Customtabs.php @@ -0,0 +1,239 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomTabs as BuilderCustomTabs; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Model Custom Tabs Class + * + * @since 3.2.0 + */ +class Customtabs +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The CustomTabs Class. + * + * @var BuilderCustomTabs + * @since 3.2.0 + */ + protected BuilderCustomTabs $buildercustomtabs; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Customcode Class. + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param BuilderCustomTabs $buildercustomtabs The CustomTabs Class. + * @param Language $language The Language Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Customcode $customcode The Customcode Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, BuilderCustomTabs $buildercustomtabs, Language $language, Placeholder $placeholder, Customcode $customcode) + { + $this->config = $config; + $this->buildercustomtabs = $buildercustomtabs; + $this->language = $language; + $this->placeholder = $placeholder; + $this->customcode = $customcode; + } + + /** + * Set custom tabs + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->customtabs = (isset($item->customtabs) + && JsonHelper::check($item->customtabs)) + ? json_decode((string) $item->customtabs, true) : null; + + if (ArrayHelper::check($item->customtabs)) + { + // get the name + $name = $item->name_single_code; + + // setup custom tabs to global data sets + $this->buildercustomtabs->set($name, + array_map( + function ($tab) use (&$name) { + + // set the view name + $tab['view'] = $name; + + // load the dynamic data + $tab['html'] = $this->placeholder->update_( + $this->customcode->update($tab['html']) + ); + + // set the tab name + $tab['name'] = (isset($tab['name']) + && StringHelper::check( + $tab['name'] + )) ? $tab['name'] : 'Tab'; + + // set lang + $tab['lang'] = $this->config->lang_prefix . '_' + . StringHelper::safe( + $tab['view'], 'U' + ) . '_' . StringHelper::safe( + $tab['name'], 'U' + ); + $this->language->set( + 'both', $tab['lang'], $tab['name'] + ); + + // set code name + $tab['code'] = StringHelper::safe( + $tab['name'] + ); + + // check if the permissions for the tab should be added + $_tab = ''; + if (isset($tab['permission']) + && $tab['permission'] == 1) + { + $_tab = Indent::_(1); + } + + // check if the php of the tab is set, if not load it now + if (strpos((string) $tab['html'], 'bootstrap.addTab') === false + && strpos((string) $tab['html'], 'bootstrap.endTab') + === false) + { + // add the tab + $tmp = PHP_EOL . $_tab . Indent::_(1) + . ""; + $tmp .= PHP_EOL . $_tab . Indent::_(2) + . '
'; + $tmp .= PHP_EOL . $_tab . Indent::_(3) + . '
'; + $tmp .= PHP_EOL . $_tab . Indent::_(4) . implode( + PHP_EOL . $_tab . Indent::_(4), + (array) explode(PHP_EOL, trim((string) $tab['html'])) + ); + $tmp .= PHP_EOL . $_tab . Indent::_(3) . '
'; + $tmp .= PHP_EOL . $_tab . Indent::_(2) . '
'; + $tmp .= PHP_EOL . $_tab . Indent::_(1) + . ""; + + // update html + $tab['html'] = $tmp; + } + else + { + $tab['html'] = PHP_EOL . $_tab . Indent::_(1) + . implode( + PHP_EOL . $_tab . Indent::_(1), + (array) explode(PHP_EOL, trim((string) $tab['html'])) + ); + } + + // add the permissions if needed + if (isset($tab['permission']) + && $tab['permission'] == 1) + { + $tmp = PHP_EOL . Indent::_(1) + . "canDo->get('" + . $tab['view'] . "." . $tab['code'] + . ".viewtab')) : ?>"; + $tmp .= $tab['html']; + $tmp .= PHP_EOL . Indent::_(1) . ""; + // update html + $tab['html'] = $tmp; + // set lang for permissions + $tab['lang_permission'] = $tab['lang'] + . '_TAB_PERMISSION'; + $tab['lang_permission_desc'] = $tab['lang'] + . '_TAB_PERMISSION_DESC'; + $tab['lang_permission_title'] + = $this->placeholder->get('Views') . ' View ' + . $tab['name'] . ' Tab'; + $this->language->set( + 'both', $tab['lang_permission'], + $tab['lang_permission_title'] + ); + $this->language->set( + 'both', $tab['lang_permission_desc'], + 'Allow the users in this group to view ' + . $tab['name'] . ' Tab of ' + . $this->placeholder->get('views') + ); + // set the sort key + $tab['sortKey'] + = StringHelper::safe( + $tab['lang_permission_title'] + ); + } + + // return tab + return $tab; + + }, array_values($item->customtabs) + ) + ); + } + + unset($item->customtabs); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Dynamicget.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Dynamicget.php new file mode 100644 index 000000000..cf74f603b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Dynamicget.php @@ -0,0 +1,578 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteDynamicGet; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteMainGet; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Dynamicget\Selection; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Dynamic Get Class + * + * @since 3.2.0 + */ +class Dynamicget +{ + /** + * The joint types + * + * @var array + * @since 3.2.0 + */ + protected array $jointer = [ + 1 => 'LEFT', + 2 => 'LEFT OUTER', + 3 => 'INNER', + 4 => 'RIGHT', + 5 => 'RIGHT OUTER' + ]; + + /** + * The operator types + * + * @var array + * @since 3.2.0 + */ + protected array $operator = [ + 1 => '=', + 2 => '!=', + 3 => '<>', + 4 => '>', + 5 => '<', + 6 => '>=', + 7 => '<=', + 8 => '!<', + 9 => '!>', + 10 => 'IN', + 11 => 'NOT IN' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'dynamic_get', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The SiteDynamicGet Class. + * + * @var SiteDynamicGet + * @since 3.2.0 + */ + protected SiteDynamicGet $sitedynamicget; + + /** + * The SiteMainGet Class. + * + * @var SiteMainGet + * @since 3.2.0 + */ + protected SiteMainGet $sitemainget; + + /** + * The Customcode Class. + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * The Gui Class. + * + * @var Gui + * @since 3.2.0 + */ + protected Gui $gui; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The Selection Class. + * + * @var Selection + * @since 3.2.0 + */ + protected Selection $selection; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param SiteDynamicGet $sitedynamicget The SiteDynamicGet Class. + * @param SiteMainGet $sitemainget The SiteMainGet Class. + * @param Customcode $customcode The Customcode Class. + * @param Gui $gui The Gui Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Selection $selection The Selection Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, SiteDynamicGet $sitedynamicget, + SiteMainGet $sitemainget, Customcode $customcode, Gui $gui, + Placeholder $placeholder, Selection $selection) + { + $this->config = $config; + $this->sitedynamicget = $sitedynamicget; + $this->sitemainget = $sitemainget; + $this->customcode = $customcode; + $this->gui = $gui; + $this->placeholder = $placeholder; + $this->selection = $selection; + } + + /** + * Set Dynamic Get + * + * @param object $item The item data + * @param string $view_code The view code name + * @param string $context The context for events + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $view_code, string $context) + { + // reset buckets + $item->main_get = []; + $item->custom_get = []; + + // should joined and other tweaks be added + $add_tweaks_joints = true; + + // set source data + switch ($item->main_source) + { + case 1: + // check if auto sync is set + if ($item->select_all == 1) + { + $item->view_selection = '*'; + } + // set the view data + $item->main_get[0]['selection'] = $this->selection->get( + $item->key, $view_code, + $item->view_selection, + $item->view_table_main, 'a', 'view' + ); + $item->main_get[0]['as'] = 'a'; + $item->main_get[0]['key'] = $item->key; + $item->main_get[0]['context'] = $context; + unset($item->view_selection); + break; + case 2: + // check if auto sync is set + if ($item->select_all == 1) + { + $item->db_selection = '*'; + } + // set the database data + $item->main_get[0]['selection'] = $this->selection->get( + $item->key, $view_code, + $item->db_selection, + $item->db_table_main, 'a', 'db' + ); + $item->main_get[0]['as'] = 'a'; + $item->main_get[0]['key'] = $item->key; + $item->main_get[0]['context'] = $context; + unset($item->db_selection); + break; + case 3: + // set GUI mapper field + $this->guiMapper['field'] = 'php_custom_get'; + // get the custom query + $customQueryString + = $this->gui->set( + $this->customcode->update( + base64_decode((string) $item->php_custom_get) + ), + $this->guiMapper + ); + + // get the table name + $_searchQuery + = GetHelper::between( + $customQueryString, '$query->from(', ')' + ); + + if (StringHelper::check( + $_searchQuery + ) + && strpos((string) $_searchQuery, '#__') !== false) + { + $_queryName = GetHelper::between( + $_searchQuery, '#__', "'" + ); + + if (!StringHelper::check( + $_queryName + )) + { + $_queryName = GetHelper::between( + $_searchQuery, '#__', '"' + ); + } + } + + // set to blank if not found + if (!isset($_queryName) + || !StringHelper::check( + $_queryName + )) + { + $_queryName = ''; + } + + // set custom script + $item->main_get[0]['selection'] = [ + 'select' => $customQueryString, + 'from' => '', 'table' => '', 'type' => '', + 'name' => $_queryName]; + $item->main_get[0]['as'] = 'a'; + $item->main_get[0]['key'] = $item->key; + $item->main_get[0]['context'] = $context; + + // do not add + $add_tweaks_joints = false; + + break; + } + + // only add if main source is not custom + if ($add_tweaks_joints) + { + // set join_view_table details + $item->join_view_table = json_decode( + (string) $item->join_view_table, true + ); + + if (ArrayHelper::check( + $item->join_view_table + )) + { + // start the part of a table bucket + $_part_of_a = []; + // build relationship + $_relationship = array_map( + function ($op) use (&$_part_of_a) { + $bucket = []; + // array(on_field_as, on_field) + $bucket['on_field'] = array_map( + 'trim', + explode('.', (string) $op['on_field']) + ); + // array(join_field_as, join_field) + $bucket['join_field'] = array_map( + 'trim', + explode('.', (string) $op['join_field']) + ); + // triget filed that has table a relationship + if ($op['row_type'] == 1 + && ($bucket['on_field'][0] === 'a' + || isset($_part_of_a[$bucket['on_field'][0]]) + || isset($_part_of_a[$bucket['join_field'][0]]))) + { + $_part_of_a[$op['as']] = $op['as']; + } + + return $bucket; + }, $item->join_view_table + ); + + // loop joints + foreach ($item->join_view_table as $nr => &$option) + { + if (StringHelper::check( + $option['selection'] + )) + { + // convert the type + $option['type'] + = $this->jointer[$option['type']]; + // convert the operator + $option['operator'] + = $this->operator[$option['operator']]; + // get the on field values + $on_field + = $_relationship[$nr]['on_field']; + // get the join field values + $join_field + = $_relationship[$nr]['join_field']; + // set selection + $option['selection'] + = $this->selection->get( + $item->key, + $view_code, + $option['selection'], + $option['view_table'], + $option['as'], + 'view', + $option['row_type'] + ); + $option['key'] = $item->key; + $option['context'] = $context; + // load to the getters + if ($option['row_type'] == 1) + { + $item->main_get[] = $option; + if ($on_field[0] === 'a' + || isset($_part_of_a[$join_field[0]]) + || isset($_part_of_a[$on_field[0]])) + { + $this->sitemainget->set( + $this->config->build_target . '.' . $view_code . '.' . + $option['as'], $option['as'] + ); + } + else + { + $this->sitedynamicget->set( + $this->config->build_target . '.' . $view_code . '.' . + $option['as'] . '.' . $join_field[1], + $on_field[0] + ); + } + } + elseif ($option['row_type'] == 2) + { + $item->custom_get[] = $option; + if ($on_field[0] != 'a') + { + $this->sitedynamicget->set( + $this->config->build_target . '.' . $view_code . '.' . + $option['as'] . '.' . $join_field[1], + $on_field[0] + ); + } + } + } + unset($item->join_view_table[$nr]); + } + } + unset($item->join_view_table); + + // set join_db_table details + $item->join_db_table = json_decode( + (string) $item->join_db_table, true + ); + + if (ArrayHelper::check($item->join_db_table)) + { + // start the part of a table bucket + $_part_of_a = []; + // build relationship + $_relationship = array_map( + function ($op) use (&$_part_of_a) { + $bucket = []; + // array(on_field_as, on_field) + $bucket['on_field'] = array_map( + 'trim', + explode('.', (string) $op['on_field']) + ); + // array(join_field_as, join_field) + $bucket['join_field'] = array_map( + 'trim', + explode('.', (string) $op['join_field']) + ); + // triget filed that has table a relationship + if ($op['row_type'] == 1 + && ($bucket['on_field'][0] === 'a' + || isset($_part_of_a[$bucket['on_field'][0]]) + || isset($_part_of_a[$bucket['join_field'][0]]))) + { + $_part_of_a[$op['as']] = $op['as']; + } + + return $bucket; + }, $item->join_db_table + ); + + // loop joints + foreach ($item->join_db_table as $nr => &$option1) + { + if (StringHelper::check($option1['selection'])) + { + // convert the type + $option1['type'] = $this->jointer[$option1['type']]; + // convert the operator + $option1['operator'] = $this->operator[$option1['operator']]; + // get the on field values + $on_field = $_relationship[$nr]['on_field']; + // get the join field values + $join_field = $_relationship[$nr]['join_field']; + // set selection + $option1['selection'] = $this->selection->get( + $item->key, + $view_code, + $option1['selection'], + $option1['db_table'], + $option1['as'], + 'db', + $option1['row_type'] + ); + $option1['key'] = $item->key; + $option1['context'] = $context; + // load to the getters + if ($option1['row_type'] == 1) + { + $item->main_get[] = $option1; + if ($on_field[0] === 'a' + || isset($_part_of_a[$join_field[0]]) + || isset($_part_of_a[$on_field[0]])) + { + $this->sitemainget->set( + $this->config->build_target . '.' . $view_code . '.' . + $option1['as'], $option1['as'] + ); + } + else + { + $this->sitedynamicget->set( + $this->config->build_target . '.' . $view_code . '.' . + $option1['as'] . '.' . $join_field[1], + $on_field[0] + ); + } + } + elseif ($option1['row_type'] == 2) + { + $item->custom_get[] = $option1; + if ($on_field[0] != 'a') + { + $this->sitedynamicget->set( + $this->config->build_target . '.' . $view_code . '.' . + $option1['as'] . '.' . $join_field[1], + $on_field[0] + ); + } + } + } + unset($item->join_db_table[$nr]); + } + } + unset($item->join_db_table); + + // set filter details + $item->filter = json_decode( + (string) $item->filter, true + ); + + if (ArrayHelper::check($item->filter)) + { + foreach ($item->filter as $nr => &$option2) + { + if (isset($option2['operator'])) + { + $option2['operator'] = $this->operator[$option2['operator']]; + $option2['state_key'] = $this->placeholder->update_( + $this->customcode->update( + $option2['state_key'] + ) + ); + $option2['key'] = $item->key; + } + else + { + unset($item->filter[$nr]); + } + } + } + + // set where details + $item->where = json_decode((string) $item->where, true); + if (ArrayHelper::check($item->where)) + { + foreach ($item->where as $nr => &$option3) + { + if (isset($option3['operator'])) + { + $option3['operator'] = $this->operator[$option3['operator']]; + } + else + { + unset($item->where[$nr]); + } + } + } + else + { + unset($item->where); + } + + // set order details + $item->order = json_decode((string) $item->order, true); + if (!ArrayHelper::check($item->order)) + { + unset($item->order); + } + + // set grouping + $item->group = json_decode((string) $item->group, true); + if (!ArrayHelper::check($item->group)) + { + unset($item->group); + } + + // set global details + $item->global = json_decode( + (string) $item->global, true + ); + + if (!ArrayHelper::check($item->global)) + { + unset($item->global); + } + } + else + { + // when we have a custom query script we do not add the dynamic options + unset($item->join_view_table); + unset($item->join_db_table); + unset($item->filter); + unset($item->where); + unset($item->order); + unset($item->group); + unset($item->global); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Fields.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Fields.php new file mode 100644 index 000000000..42c4e2c60 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Fields.php @@ -0,0 +1,352 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Application\CMSApplication; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HistoryInterface; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Field; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups as FieldGroups; +use VDM\Joomla\Componentbuilder\Compiler\Model\Updatesql; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Model Fields Class + * + * @since 3.2.0 + */ +class Fields +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler History + * + * @var HistoryInterface + * @since 3.2.0 + */ + protected HistoryInterface $history; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Field + * + * @var Field + * @since 3.2.0 + */ + protected Field $field; + + /** + * Compiler Field Name + * + * @var FieldName + * @since 3.2.0 + */ + protected FieldName $fieldName; + + /** + * Compiler Field Groups + * + * @var FieldGroups + * @since 3.2.0 + */ + protected FieldGroups $fieldGroups; + + /** + * Compiler Update Sql + * + * @var UpdateSql + * @since 3.2.0 + */ + protected UpdateSql $updateSql; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param HistoryInterface|null $history The compiler history object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Field|null $field The compiler field object. + * @param FieldName|null $fieldName The compiler field name object. + * @param FieldGroups|null $fieldGroups The compiler field groups object. + * @param UpdateSql|null $updateSql The compiler field name object. + * @param CMSApplication|null $app The app object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Registry $registry = null, + ?HistoryInterface $history = null, ?Customcode $customcode = null, + ?Field $field = null, ?FieldName $fieldName = null, ?FieldGroups $fieldGroups = null, + ?UpdateSql $updateSql = null, ?CMSApplication $app = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->history = $history ?: Compiler::_('History'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->field = $field ?: Compiler::_('Field'); + $this->fieldName = $fieldName ?: Compiler::_('Field.Name'); + $this->fieldGroups = $fieldGroups ?: Compiler::_('Field.Groups'); + $this->updateSql = $updateSql ?: Compiler::_('Model.Updatesql'); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * Set fields + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->fields = []; + + $item->addfields = (isset($item->addfields) + && JsonHelper::check($item->addfields)) + ? json_decode((string) $item->addfields, true) : null; + + if (ArrayHelper::check($item->addfields)) + { + $ignore_fields = []; + $default_fields = $this->config->default_fields; + + // load the field data + $item->fields = array_map( + function ($field) use ( + &$item, &$ignore_fields, &$default_fields + ) { + // set the field details + $this->field->set( + $field, $item->name_single_code, + $item->name_list_code + ); + + // check if this field is a default field OR + // check if this is none database related field + if (in_array($field['base_name'], $default_fields) + || $this->fieldGroups->check($field['type_name'], 'spacer') + || (isset($field['list']) && $field['list'] == 2)) // 2 = none database + { + $ignore_fields[$field['field']] = $field['field']; + } + + // return field + return $field; + + }, array_values($item->addfields) + ); + + // build update SQL + if ($old_view = $this->history->get( + 'admin_fields', $item->addfields_id + )) + { + // add new fields were added + if (isset($old_view->addfields) + && JsonHelper::check( + $old_view->addfields + )) + { + $this->updateSql->set( + json_decode((string) $old_view->addfields, true), + $item->addfields, 'field', $item->name_single_code, + $ignore_fields + ); + } + // clear this data + unset($old_view); + } + + // sort the fields according to order + usort( + $item->fields, function ($a, $b) { + if (isset($a['order_list']) && isset($b['order_list'])) + { + if ($a['order_list'] != 0 && $b['order_list'] != 0) + { + return $a['order_list'] <=> $b['order_list']; + } + elseif ($b['order_list'] != 0 && $a['order_list'] == 0) + { + return 1; + } + elseif ($a['order_list'] != 0 && $b['order_list'] == 0) + { + return -1; + } + + return 1; + } + + return 0; + } + ); + + // do some house cleaning (for fields) + foreach ($item->fields as $field) + { + // so first we lock the field name in + $field_name = $this->fieldName->get( + $field, $item->name_list_code + ); + + // check if the field changed since the last compilation + // (default fields never change and are always added) + if (!isset($ignore_fields[$field['field']]) + && ObjectHelper::check( + $field['settings']->history + )) + { + // check if the datatype changed + if (isset($field['settings']->history->datatype)) + { + $this->updateSql->set( + $field['settings']->history->datatype, + $field['settings']->datatype, 'field.datatype', + $item->name_single_code . '.' . $field_name + ); + } + + // check if the datatype lenght changed + if (isset($field['settings']->history->datalenght) + && isset($field['settings']->history->datalenght_other)) + { + $this->updateSql->set( + $field['settings']->history->datalenght + . $field['settings']->history->datalenght_other, + $field['settings']->datalenght + . $field['settings']->datalenght_other, + 'field.lenght', + $item->name_single_code . '.' . $field_name + ); + } + + // check if the name changed + if (isset($field['settings']->history->xml) + && JsonHelper::check( + $field['settings']->history->xml + )) + { + // only run if this is not an alias or a tag + if ((!isset($field['alias']) || !$field['alias']) + && 'tag' !== $field['settings']->type_name) + { + // build temp field bucket + $tmpfield = []; + $tmpfield['settings'] = new \stdClass(); + + // convert the xml json string to normal string + $tmpfield['settings']->xml + = $this->customcode->update( + json_decode( + (string) $field['settings']->history->xml + ) + ); + + // add properties from current field as it is generic + $tmpfield['settings']->properties + = $field['settings']->properties; + // add the old name + $tmpfield['settings']->name + = $field['settings']->history->name; + // add the field type from current field since it is generic + $tmpfield['settings']->type_name + = $field['settings']->type_name; + // get the old name + $old_field_name = $this->fieldName->get( + $tmpfield + ); + + // only run this if not a multi field + if ($this->registry->get('unique.names.' . $item->name_list_code . '.names.' . $field_name) === null) + { + // this only works when the field is + // not multiple of the same field + $this->updateSql->set( + $old_field_name, $field_name, + 'field.name', + $item->name_single_code . '.' + . $field_name + ); + } + elseif ($old_field_name !== $field_name) + { + // give a notice atleast that the multi fields + // could have changed and no DB update was done + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEFIELD_NOTICEHTHREE'), + 'Notice' + ); + $this->app->enqueueMessage( + Text::sprintf( + 'You have a field called %s that has been added multiple times to the %s view, the name of that field has changed to %s. Normaly we would automaticly add the update SQL to your component, but with multiple fields this does not work automaticly since it could be that noting changed and it just seems like it did. Therefore you will have to do this manualy if it actualy did change!', + $field_name, + $item->name_single_code, + $old_field_name + ), 'Notice' + ); + } + + // remove tmp + unset($tmpfield); + } + } + } + } + } + + unset($item->addfields); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Filesfolders.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Filesfolders.php new file mode 100644 index 000000000..f3b30e26c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Filesfolders.php @@ -0,0 +1,81 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Files & Folders Class + * + * @since 3.2.0 + */ +class Filesfolders +{ + /** + * Compiler Files Folders + * + * @var array + * @since 3.2.0 + */ + protected array $keys = [ + 'files' => 'files', + 'folders' => 'folders', + 'urls' => 'urls', + 'filesfullpath' => 'files', + 'foldersfullpath' => 'folders' + ]; + + /** + * Set the file and folder data + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + foreach ($this->keys as $target => $value) + { + // set the add target data + $item->{'add' . $target} = (isset($item->{'add' . $target}) && + JsonHelper::check($item->{'add' . $target})) ? + json_decode((string) $item->{'add' . $target}, true) : null; + + // only continue if there are values + if (ArrayHelper::check($item->{'add' . $target})) + { + if (isset($item->{$value}) + && ArrayHelper::check($item->{$value})) + { + foreach ($item->{'add' . $target} as $taget) + { + $item->{$value}[] = $taget; + } + } + else + { + $item->{$value} = array_values( + $item->{'add' . $target} + ); + } + } + + unset($item->{'add' . $target}); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php new file mode 100644 index 000000000..d85d0876c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php @@ -0,0 +1,126 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HistoryInterface; +use VDM\Joomla\Componentbuilder\Compiler\Model\Updatesql; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Admin View History Class + * + * @since 3.2.0 + */ +class Historyadminview +{ + /** + * The compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler history + * + * @var HistoryInterface + * @since 3.2.0 + */ + protected HistoryInterface $history; + + /** + * The compiler update sql + * + * @var Updatesql + * @since 3.2.0 + */ + protected Updatesql $updatesql; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param HistoryInterface|null $history The compiler history object. + * @param Updatesql|null $updatesql The compiler updatesql object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?HistoryInterface $history = null, + ?Updatesql $updatesql = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->history = $history ?: Compiler::_('History'); + $this->updatesql = $updatesql ?: Compiler::_('Model.Updatesql'); + } + + /** + * check if an update SQL is needed + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + if (($old = $this->history->get('admin_view', $item->id)) !== null) + { + // check if the view name changed + if (StringHelper::check($old->name_single)) + { + $this->updatesql->set( + StringHelper::safe( + $old->name_single + ), $item->name_single_code, 'table_name', + $item->name_single_code + ); + } + + // loop the mysql table settings + foreach ($this->config->mysql_table_keys as $mysql_table_key => $mysql_table_val) + { + // check if the table engine changed + if (isset($old->{'mysql_table_' . $mysql_table_key}) + && isset($item->{'mysql_table_' . $mysql_table_key})) + { + $this->updatesql->set( + $old->{'mysql_table_' . $mysql_table_key}, + $item->{'mysql_table_' . $mysql_table_key}, + 'table_' . $mysql_table_key, $item->name_single_code + ); + } + // check if there is no history on table engine, and it changed from the default/global + elseif (isset($item->{'mysql_table_' . $mysql_table_key}) + && StringHelper::check( + $item->{'mysql_table_' . $mysql_table_key} + ) + && !is_numeric( + $item->{'mysql_table_' . $mysql_table_key} + )) + { + $this->updatesql->set( + $mysql_table_val['default'], + $item->{'mysql_table_' . $mysql_table_key}, + 'table_' . $mysql_table_key, $item->name_single_code + ); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php new file mode 100644 index 000000000..dca3671c8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php @@ -0,0 +1,150 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HistoryInterface; +use VDM\Joomla\Componentbuilder\Compiler\Model\Updatesql; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\JsonHelper; + + +/** + * Model Component History Class + * + * @since 3.2.0 + */ +class Historycomponent +{ + /** + * The compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler history + * + * @var HistoryInterface + * @since 3.2.0 + */ + protected HistoryInterface $history; + + /** + * The compiler update sql + * + * @var Updatesql + * @since 3.2.0 + */ + protected Updatesql $updatesql; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param HistoryInterface|null $history The compiler history object. + * @param Updatesql|null $updatesql The compiler updatesql object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?HistoryInterface $history = null, + ?Updatesql $updatesql = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->history = $history ?: Compiler::_('History'); + $this->updatesql = $updatesql ?: Compiler::_('Model.Updatesql'); + } + + /** + * check if an update SQL is needed + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + // update SQL for admin views + $this->setAdminView($item); + + // update SQL for component + $this->setComponent($item); + } + + /** + * check if an update SQL is needed + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + private function setAdminView(object $item) + { + $old_admin_views = $this->history->get( + 'component_admin_views', $item->addadmin_views_id + ); + + // add new views if found + if ($old_admin_views && ObjectHelper::check($old_admin_views)) + { + if (isset($old_admin_views->addadmin_views) + && JsonHelper::check( + $old_admin_views->addadmin_views + )) + { + $this->updatesql->set( + json_decode((string) $old_admin_views->addadmin_views, true), + $item->addadmin_views, 'adminview' + ); + } + } + } + + /** + * Set the component history + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + private function setComponent(object &$item) + { + $old_component = $this->history->get( + 'joomla_component', $this->config->component_id + ); + + // check if a new version was manually set + if ($old_component && ObjectHelper::check($old_component)) + { + $old_component_version = preg_replace( + '/[^0-9.]+/', '', (string) $old_component->component_version + ); + if ($old_component_version != $this->config->component_version) + { + // yes, this is a new version, this mean there may + // be manual sql and must be checked and updated + $item->old_component_version + = $old_component_version; + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Javascriptadminview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Javascriptadminview.php new file mode 100644 index 000000000..f6df06215 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Javascriptadminview.php @@ -0,0 +1,128 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Admin View Javascript Class + * + * @since 3.2.0 + */ +class Javascriptadminview +{ + /** + * The scripter add array + * + * @var array + * @since 3.2.0 + */ + protected array $scripter = [ + 'javascript_view_file', + 'javascript_view_footer', + 'javascript_views_file', + 'javascript_views_footer' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'admin_view', + 'id' => null, + 'field' => null, + 'type' => 'js', + 'prefix' => PHP_EOL + ]; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Constructor + * + * @param Dispenser|null $dispenser The compiler customcode dispenser + * + * @since 3.2.0 + */ + public function __construct(?Dispenser $dispenser = null) + { + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + } + + /** + * Set Admin View Javascript + * + * @param object $item The item data + * @param object $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'admin_view') + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + foreach ($this->scripter as $scripter) + { + if (isset($item->{'add_' . $scripter}) + && $item->{'add_' . $scripter} == 1 + && StringHelper::check($item->$scripter)) + { + $scripter_target = str_replace( + 'javascript_', '', (string) $scripter + ); + + // update GUI mapper field + $this->guiMapper['field'] = $scripter; + $this->dispenser->set( + $item->{$scripter}, + $scripter_target, + $item->name_single_code, + null, + $this->guiMapper, + true, + true, + true + ); + + // check if a token must be set + if ((strpos((string) $item->$scripter, "token") !== false + || strpos( + (string) $item->$scripter, "task=ajax" + ) !== false) && !$this->dispenser->hub['token'][$item->name_single_code]) + { + $this->dispenser->hub['token'][$item->name_single_code] + = true; + } + + unset($item->{$scripter}); + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Javascriptcustomview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Javascriptcustomview.php new file mode 100644 index 000000000..808848127 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Javascriptcustomview.php @@ -0,0 +1,116 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Javascript Custom View Class + * + * @since 3.2.0 + */ +class Javascriptcustomview +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = [ + 'javascript_file', + 'js_document' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => null, + 'id' => null, + 'field' => null, + 'type' => 'js' + ]; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Constructor + * + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * + * @since 3.2.0 + */ + public function __construct(?Customcode $customcode = null, ?Gui $gui = null) + { + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + } + + /** + * Set Javascript code + * + * @param object $item The item data + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'site_view') + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + foreach ($this->areas as $area) + { + if (isset($item->{'add_' . $area}) + && $item->{'add_' . $area} == 1 + && StringHelper::check($item->{$area})) + { + // update GUI mapper field + $this->guiMapper['field'] = $area; + $item->{$area} = $this->gui->set( + $this->customcode->update( + base64_decode((string) $item->{$area}) + ), + $this->guiMapper + ); + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Joomlamodules.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Joomlamodules.php new file mode 100644 index 000000000..959e80597 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Joomlamodules.php @@ -0,0 +1,84 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Joomlamodule\Data as Module; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; + + +/** + * Model Joomla Modules Class + * + * @since 3.2.0 + */ +class Joomlamodules +{ + /** + * Compiler Joomla Module Data Class + * + * @var Module + * @since 3.2.0 + */ + protected Module $module; + + /** + * Constructor + * + * @param Module|null $module The compiler Joomla module data object. + * + * @since 3.2.0 + */ + public function __construct(?Module $module = null) + { + $this->module = $module ?: Compiler::_('Joomlamodule.Data'); + } + + /** + * Set Joomla Module + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + // get all modules + $item->addjoomla_modules = (isset($item->addjoomla_modules) + && JsonHelper::check($item->addjoomla_modules)) + ? json_decode((string) $item->addjoomla_modules, true) : null; + + if (ArrayHelper::check($item->addjoomla_modules)) + { + $joomla_modules = array_map( + function ($array) use (&$item) { + // only load the modules whose target association calls for it + if (!isset($array['target']) || $array['target'] != 2) + { + return $this->module->set( + $array['module'], $item + ); + } + + return null; + }, array_values($item->addjoomla_modules) + ); + } + + unset($item->addjoomla_modules); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Joomlaplugins.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Joomlaplugins.php new file mode 100644 index 000000000..5362e4945 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Joomlaplugins.php @@ -0,0 +1,84 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Data as Plugin; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; + + +/** + * Model Joomla Plugins Class + * + * @since 3.2.0 + */ +class Joomlaplugins +{ + /** + * Compiler Joomla Plugin Data Class + * + * @var Plugin + * @since 3.2.0 + */ + protected Plugin $plugin; + + /** + * Constructor + * + * @param Plugin|null $plugin The compiler Joomla plugin data object. + * + * @since 3.2.0 + */ + public function __construct(?Plugin $plugin = null) + { + $this->plugin = $plugin ?: Compiler::_('Joomlaplugin.Data'); + } + + /** + * Set Joomla Plugins + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + // get all plugins + $item->addjoomla_plugins = (isset($item->addjoomla_plugins) + && JsonHelper::check($item->addjoomla_plugins)) + ? json_decode((string) $item->addjoomla_plugins, true) : null; + + if (ArrayHelper::check($item->addjoomla_plugins)) + { + $joomla_plugins = array_map( + function ($array) use (&$item) { + // only load the plugins whose target association calls for it + if (!isset($array['target']) || $array['target'] != 2) + { + return $this->plugin->set( + $array['plugin'], $item + ); + } + + return null; + }, array_values($item->addjoomla_plugins) + ); + } + + unset($item->addjoomla_plugins); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Libraries.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Libraries.php new file mode 100644 index 000000000..f39b75ffc --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Libraries.php @@ -0,0 +1,112 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\LibraryManager; +use VDM\Joomla\Componentbuilder\Compiler\Library\Data as Library; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Libraries Class + * + * @since 3.2.0 + */ +class Libraries +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The LibraryManager Class. + * + * @var LibraryManager + * @since 3.2.0 + */ + protected LibraryManager $librarymanager; + + /** + * The Data Class. + * + * @var Library + * @since 3.2.0 + */ + protected Library $library; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param LibraryManager $librarymanager The LibraryManager Class. + * @param Library $library The Data Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, LibraryManager $librarymanager, Library $library) + { + $this->config = $config; + $this->librarymanager = $librarymanager; + $this->library = $library; + } + + /** + * Set Libraries + * + * @param string $key The key mapper + * @param object $item The item data + * @param string|null $target The area being targeted + * + * @return void + * @since 3.2.0 + */ + public function set(string $key, object &$item, string $target = null) + { + // set the target + $target = $target ?: $this->config->build_target; + + // make sure json become array + if (JsonHelper::check($item->libraries)) + { + $item->libraries = json_decode((string) $item->libraries, true); + } + + // if we have an array add it + if (ArrayHelper::check($item->libraries)) + { + foreach ($item->libraries as $library) + { + if (!$this->librarymanager->exists($target . '.' . $key . '.' . (int) $library) + && $this->library->get((int) $library)) + { + $this->librarymanager->set($target . '.' . $key . '.' . (int) $library, true); + } + } + } + elseif (is_numeric($item->libraries) + && !$this->librarymanager->exists($target . '.' . $key . '.' . (int) $item->libraries) + && $this->library->get((int) $item->libraries)) + { + $this->librarymanager->set($target . '.' . $key . '.' . (int) $item->libraries, true); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Linkedviews.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Linkedviews.php new file mode 100644 index 000000000..37854bb40 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Linkedviews.php @@ -0,0 +1,76 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Linked Views Class + * + * @since 3.2.0 + */ +class Linkedviews +{ + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + } + + /** + * Set the linked views + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addlinked_views = (isset($item->addlinked_views) + && JsonHelper::check($item->addlinked_views)) + ? json_decode((string) $item->addlinked_views, true) : null; + + if (ArrayHelper::check($item->addlinked_views)) + { + // setup linked views to global data sets + $this->registry->set('builder.linked_admin_views.' . $item->name_single_code, + array_values( + $item->addlinked_views + ) + ); + } + + unset($item->addlinked_views); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Loader.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Loader.php new file mode 100644 index 000000000..99e6bedd6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Loader.php @@ -0,0 +1,211 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FootableScripts; +use VDM\Joomla\Componentbuilder\Compiler\Builder\GoogleChart; +use VDM\Joomla\Componentbuilder\Compiler\Builder\GetModule; +use VDM\Joomla\Componentbuilder\Compiler\Builder\UikitComp; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * Model Auto Loader Class + * + * @since 3.2.0 + */ +class Loader +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The FootableScripts Class. + * + * @var FootableScripts + * @since 3.2.0 + */ + protected FootableScripts $footablescripts; + + /** + * The GoogleChart Class. + * + * @var GoogleChart + * @since 3.2.0 + */ + protected GoogleChart $googlechart; + + /** + * The GetModule Class. + * + * @var GetModule + * @since 3.2.0 + */ + protected GetModule $getmodule; + + /** + * The UikitComp Class. + * + * @var UikitComp + * @since 3.2.0 + */ + protected UikitComp $uikitcomp; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param FootableScripts $footablescripts The FootableScripts Class. + * @param GoogleChart $googlechart The GoogleChart Class. + * @param GetModule $getmodule The GetModule Class. + * @param UikitComp $uikitcomp The UikitComp Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, FootableScripts $footablescripts, + GoogleChart $googlechart, GetModule $getmodule, UikitComp $uikitcomp) + { + $this->config = $config; + $this->footablescripts = $footablescripts; + $this->googlechart = $googlechart; + $this->getmodule = $getmodule; + $this->uikitcomp = $uikitcomp; + } + + /** + * Automatically load some stuff + * + * @param string $key The key mapper + * @param string $content The content to search through + * @param string|null $target The area being targeted + * + * @return void + * @since 3.2.0 + */ + public function set(string $key, string $content, ?string $target = null) + { + // set the target + $target = $target ?: $this->config->build_target; + + // check for footable + if (!$this->footablescripts->exists($target . '.' . $key)) + { + if ($this->getFootableScripts($content)) + { + $this->footablescripts->set($target . '.' . $key, true); + + $this->config->set('footable', true); + } + } + + // check for google chart + if (!$this->googlechart->exists($target . '.' . $key)) + { + if ($this->getGoogleChart($content)) + { + $this->googlechart->set($target . '.' . $key, true); + + $this->config->set('google_chart', true); + } + } + + // check for get module + if (!$this->getmodule->exists($target . '.' . $key)) + { + if ($this->getGetModule($content)) + { + $this->getmodule->set($target . '.' . $key, true); + } + } + } + + /** + * Automatically load uikit version 2 data files + * + * @param string $key The key mapper + * @param string $content The content to search through + * + * @return void + * @since 3.2.0 + */ + public function uikit(string $key, string $content) + { + // get/set uikit state + $uikit = false; + $uikit_ = $this->config->get('uikit', 0); + + // add uikit if required + if (2 == $uikit_ || 1 == $uikit_) + { + $uikit = true; + } + + // load uikit + if ($uikit) + { + // set uikit to views TODO: convert this getUikitComp to a class + if (($found = Helper::_('getUikitComp', + [$content, $this->uikitcomp->get($key, [])] + )) !== false) + { + $this->uikitcomp->set($key, $found); + } + } + } + + /** + * Check for footable scripts + * + * @param string $content The content to check + * + * @return boolean True if found + * @since 3.2.0 + */ + protected function getFootableScripts(string &$content): bool + { + return strpos($content, 'footable') !== false; + } + + /** + * Check for getModules script + * + * @param string $content The content to check + * + * @return boolean True if found + * @since 3.2.0 + */ + protected function getGetModule(string &$content): bool + { + return strpos($content, 'this->getModules(') !== false; + } + + /** + * Check for get Google Chart script + * + * @param string $content The content to check + * + * @return boolean True if found + * @since 3.2.0 + */ + protected function getGoogleChart(string &$content): bool + { + return strpos($content, 'Chartbuilder(') !== false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Modifieddate.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Modifieddate.php new file mode 100644 index 000000000..fc30b2c2d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Modifieddate.php @@ -0,0 +1,200 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Model - Get Modified Date + * + * @since 3.2.0 + */ +class Modifieddate +{ + /** + * The array of last modified dates + * + * @var array + * @since 3.2.0 + */ + protected array $last = []; + + /** + * Get the last modified date of an item + * + * @param array $item The item data + * + * @return string The modified date + * @since 3.2.0 + */ + public function get(array $item): string + { + $key = $this->getKey($item); + + if (!isset($this->last[$key])) + { + $date = max($this->getDate($item), $this->getModified($item)); + + $this->last[$key] = Factory::getDate($date)->format( + 'jS F, Y' + ); + } + + return $this->last[$key]; + } + + /** + * Get the last modified date of an item + * + * @param array|object $item The item data + * + * @return int The modified date as int + * @since 3.2.0 + */ + protected function getDate($item): int + { + if (is_array($item) && isset($item['settings']) && isset($item['settings']->modified) + && StringHelper::check($item['settings']->modified) + && '0000-00-00 00:00:00' !== $item['settings']->modified) + { + return strtotime((string) $item['settings']->modified); + } + elseif (is_object($item) && isset($item->modified) + && StringHelper::check($item->modified) + && '0000-00-00 00:00:00' !== $item->modified) + { + return strtotime((string) $item->modified); + } + + return strtotime("now"); + } + + /** + * Get the last modified date of an item's sub items + * + * @param array|object $item The item data + * + * @return int The modified date as int + * @since 3.2.0 + */ + protected function getModified($item): int + { + $date = 0; + + // if not settings is found + if (!is_array($item) || !isset($item['settings']) || !ObjectHelper::check($item['settings'])) + { + return $date; + } + + // check if we have fields + if (isset($item['settings']->fields) && ArrayHelper::check($item['settings']->fields)) + { + foreach ($item['settings']->fields as $field) + { + if (isset($field['settings']) + && ObjectHelper::check($field['settings']) + && isset($field['settings']->modified) + && StringHelper::check($field['settings']->modified) + && '0000-00-00 00:00:00' !== $field['settings']->modified) + { + $modified = strtotime((string) $field['settings']->modified); + $date = max($date, $modified); + } + } + } + // check if we have a main dynamic get + elseif (isset($item['settings']->main_get) + && ObjectHelper::check($item['settings']->main_get) + && isset($item['settings']->main_get->modified) + && StringHelper::check($item['settings']->main_get->modified) + && '0000-00-00 00:00:00' !== $item['settings']->main_get->modified) + { + $modified = strtotime((string) $item['settings']->main_get->modified); + $date = max($date, $modified); + } + + return $date; + } + + /** + * Get the key for an item + * + * @param array|object $item The item data + * + * @return string The key + * @since 3.2.0 + */ + protected function getKey($item): string + { + if (is_array($item)) + { + return $this->getKeyFromArray($item); + } + elseif (is_object($item)) + { + return $this->getKeyFromObject($item); + } + + return 'error'; + } + + /** + * Get the key for an item (array) + * + * @param array $item The item data + * + * @return string The key + * @since 3.2.0 + */ + protected function getKeyFromArray(array $item): string + { + if (isset($item['adminview'])) + { + return $item['adminview'] . 'admin'; + } + elseif (isset($item['siteview'])) + { + return $item['siteview'] . 'site'; + } + elseif (isset($item['customadminview'])) + { + return $item['customadminview'] . 'customadmin'; + } + + return 'error'; + } + + /** + * Get the key for an item (object) + * + * @param object $item The item data + * + * @return string The key + * @since 3.2.0 + */ + protected function getKeyFromObject(object $item): string + { + if (isset($item->key)) + { + return $item->key; + } + + return 'error'; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Mysqlsettings.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Mysqlsettings.php new file mode 100644 index 000000000..f626ffd02 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Mysqlsettings.php @@ -0,0 +1,89 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MysqlTableSetting; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model MySQL Settings Class + * + * @since 3.2.0 + */ +class Mysqlsettings +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The MysqlTableSetting Class. + * + * @var MysqlTableSetting + * @since 3.2.0 + */ + protected MysqlTableSetting $mysqltablesetting; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param MysqlTableSetting $mysqltablesetting The MysqlTableSetting Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, MysqlTableSetting $mysqltablesetting) + { + $this->config = $config; + $this->mysqltablesetting = $mysqltablesetting; + } + + /** + * Set MySQL table settings + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + foreach ($this->config->mysql_table_keys as $mysql_table_key => $mysql_table_val) + { + if (isset($item->{'mysql_table_' . $mysql_table_key}) + && StringHelper::check($item->{'mysql_table_' . $mysql_table_key}) + && !is_numeric($item->{'mysql_table_' . $mysql_table_key})) + { + $this->mysqltablesetting->set($item->name_single_code . '.' . + $mysql_table_key, $item->{'mysql_table_' . $mysql_table_key} + ); + } + else + { + $this->mysqltablesetting->set($item->name_single_code . '.' . + $mysql_table_key, $mysql_table_val['default'] + ); + } + + // remove the table values since we moved to another object + unset($item->{'mysql_table_' . $mysql_table_key}); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Permissions.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Permissions.php new file mode 100644 index 000000000..3c03e4911 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Permissions.php @@ -0,0 +1,49 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Permissions Class + * + * @since 3.2.0 + */ +class Permissions +{ + /** + * Set the local tabs + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addpermissions = (isset($item->addpermissions) + && JsonHelper::check($item->addpermissions)) + ? json_decode((string) $item->addpermissions, true) : null; + + if (ArrayHelper::check($item->addpermissions)) + { + $item->permissions = array_values($item->addpermissions); + } + + unset($item->addpermissions); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Phpadminview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Phpadminview.php new file mode 100644 index 000000000..d8c3134b2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Phpadminview.php @@ -0,0 +1,139 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Templatelayout\Data as Templatelayout; + + +/** + * Model PHP Admin View Class + * + * @since 3.2.0 + */ +class Phpadminview +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = [ + 'php_getitem', + 'php_before_save', + 'php_save', + 'php_getform', + 'php_postsavehook', + 'php_getitems', + 'php_getitems_after_all', + 'php_getlistquery', + 'php_allowadd', + 'php_allowedit', + 'php_before_cancel', + 'php_after_cancel', + 'php_before_delete', + 'php_after_delete', + 'php_before_publish', + 'php_after_publish', + 'php_batchcopy', + 'php_batchmove', + 'php_document' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => 'admin_view', + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Compiler Template Layout Data + * + * @var Templatelayout + * @since 3.2.0 + */ + protected Templatelayout $templateLayout; + + /** + * Constructor + * + * @param Dispenser|null $dispenser The compiler customcode dispenser + * @param Templatelayout|null $templateLayout The template layout data + * + * @since 3.2.0 + */ + public function __construct(?Dispenser $dispenser = null, ?Templatelayout $templateLayout = null) + { + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + $this->templateLayout = $templateLayout ?: Compiler::_('Templatelayout.Data'); + } + + /** + * Set PHP code + * + * @param object $item The item data + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'admin_view') + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + foreach ($this->areas as $area) + { + if (isset($item->{'add_' . $area}) + && $item->{'add_' . $area} == 1) + { + // update GUI mapper field + $this->guiMapper['field'] = $area; + $this->dispenser->set( + $item->{$area}, + $area, + $item->name_single_code, + null, + $this->guiMapper + ); + + // check if we have template or layouts to load + $this->templateLayout->set( + $item->{$area}, $item->name_single_code + ); + + unset($item->{$area}); + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Phpcustomview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Phpcustomview.php new file mode 100644 index 000000000..1c06d5b43 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Phpcustomview.php @@ -0,0 +1,152 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Model\Loader; +use VDM\Joomla\Componentbuilder\Compiler\Templatelayout\Data as Templatelayout; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model PHP Custom View Class + * + * @since 3.2.0 + */ +class Phpcustomview +{ + /** + * The areas add array + * + * @var array + * @since 3.2.0 + */ + protected array $areas = [ + 'php_view', + 'php_jview', + 'php_jview_display', + 'php_document' + ]; + + /** + * The gui mapper array + * + * @var array + * @since 3.2.0 + */ + protected array $guiMapper = [ + 'table' => null, + 'id' => null, + 'field' => null, + 'type' => 'php' + ]; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * Compiler Auto Loader + * + * @var Loader + * @since 3.2.0 + */ + protected Loader $loader; + + /** + * Compiler Template Layout Data + * + * @var Templatelayout + * @since 3.2.0 + */ + protected Templatelayout $templateLayout; + + /** + * Constructor + * + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui. + * @param Loader|null $loader The compiler loader object. + * @param Templatelayout|null $templateLayout The template layout data. + * + * @since 3.2.0 + */ + public function __construct(?Customcode $customcode = null, ?Gui $gui = null, + ?Loader $loader = null, ?Templatelayout $templateLayout = null) + { + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->loader = $loader ?: Compiler::_('Model.Loader'); + $this->templateLayout = $templateLayout ?: Compiler::_('Templatelayout.Data'); + } + + /** + * Set PHP code + * + * @param object $item The item data + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item, string $table = 'site_view') + { + // set some gui mapper values + $this->guiMapper['table'] = $table; + $this->guiMapper['id'] = (int) $item->id; + + foreach ($this->areas as $area) + { + if (isset($item->{'add_' . $area}) + && $item->{'add_' . $area} == 1 + && StringHelper::check($item->$area)) + { + // update GUI mapper field + $this->guiMapper['field'] = $area; + $item->{$area} = $this->gui->set( + $this->customcode->update( + base64_decode((string) $item->{$area}) + ), + $this->guiMapper + ); + + // check if we have template or layouts to load + $this->templateLayout->set( + $item->{$area}, $item->code + ); + + // auto loaders + $this->loader->set($item->code, $item->{$area}); + + // set uikit version 2 + $this->loader->uikit($item->code, $item->{$area}); + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Relations.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Relations.php new file mode 100644 index 000000000..051228213 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Relations.php @@ -0,0 +1,196 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListJoin; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListHeadOverride; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldRelations; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Relations Class + * + * @since 3.2.0 + */ +class Relations +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Language Class. + * + * @var Language + * @since 3.2.0 + */ + protected Language $language; + + /** + * The Customcode Class. + * + * @var Customcode + * @since 3.2.0 + */ + protected Customcode $customcode; + + /** + * The ListJoin Class. + * + * @var ListJoin + * @since 3.2.0 + */ + protected ListJoin $listjoin; + + /** + * The ListHeadOverride Class. + * + * @var ListHeadOverride + * @since 3.2.0 + */ + protected ListHeadOverride $listheadoverride; + + /** + * The FieldRelations Class. + * + * @var FieldRelations + * @since 3.2.0 + */ + protected FieldRelations $fieldrelations; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Language $language The Language Class. + * @param Customcode $customcode The Customcode Class. + * @param ListJoin $listjoin The ListJoin Class. + * @param ListHeadOverride $listheadoverride The ListHeadOverride Class. + * @param FieldRelations $fieldrelations The FieldRelations Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Language $language, Customcode $customcode, ListJoin $listjoin, + ListHeadOverride $listheadoverride, FieldRelations $fieldrelations) + { + $this->config = $config; + $this->language = $language; + $this->customcode = $customcode; + $this->listjoin = $listjoin; + $this->listheadoverride = $listheadoverride; + $this->fieldrelations = $fieldrelations; + } + + /** + * Set the relations + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addrelations = (isset($item->addrelations) + && JsonHelper::check($item->addrelations)) + ? json_decode((string) $item->addrelations, true) : null; + + if (ArrayHelper::check($item->addrelations)) + { + foreach ($item->addrelations as $nr => $relationsValue) + { + // only add if list view field is selected and joined fields are set + if (isset($relationsValue['listfield']) + && is_numeric( + $relationsValue['listfield'] + ) + && $relationsValue['listfield'] > 0 + && isset($relationsValue['area']) + && is_numeric($relationsValue['area']) + && $relationsValue['area'] > 0) + { + // do a dynamic update on the set values + if (isset($relationsValue['set']) + && StringHelper::check( + $relationsValue['set'] + )) + { + $relationsValue['set'] = $this->customcode->update( + $relationsValue['set'] + ); + } + + // load the field relations + $this->fieldrelations->set($item->name_list_code . '.' . (int) $relationsValue['listfield'] + . '.' . (int) $relationsValue['area'], $relationsValue); + + // load the list joints + if (isset($relationsValue['joinfields']) + && ArrayHelper::check( + $relationsValue['joinfields'] + )) + { + foreach ($relationsValue['joinfields'] as $join) + { + $this->listjoin->set($item->name_list_code . '.' . (int) $join, (int) $join); + } + } + + // set header over-ride + if (isset($relationsValue['column_name']) + && StringHelper::check( + $relationsValue['column_name'] + )) + { + $check_column_name = trim( + strtolower((string) $relationsValue['column_name']) + ); + + // confirm it should really make the over ride + if ('default' !== $check_column_name) + { + $column_name_lang = $this->config->lang_prefix . '_' + . StringHelper::safe( + $item->name_list_code, 'U' + ) . '_' . StringHelper::safe( + $relationsValue['column_name'], 'U' + ); + $this->language->set( + 'admin', $column_name_lang, + $relationsValue['column_name'] + ); + $this->listheadoverride-> + set($item->name_list_code . '.' . (int) $relationsValue['listfield'], + $column_name_lang + ); + + } + } + } + } + } + + unset($item->addrelations); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Siteviews.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Siteviews.php new file mode 100644 index 000000000..e60e76330 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Siteviews.php @@ -0,0 +1,109 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customview\Data as Customview; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Model Site Views Class + * + * @since 3.2.0 + */ +class Siteviews +{ + /** + * Component Site view Data + * + * @var Customview + * @since 3.2.0 + **/ + protected Customview $site; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Constructor + * + * @param Customview|null $site The site view data object. + * @param Config|null $config The compiler config object. + * + * @since 3.2.0 + */ + public function __construct(?Customview $site = null, ?Config $config = null) + { + $this->site = $site ?: Compiler::_('Customview.Data'); + $this->config = $config ?: Compiler::_('Config'); + } + + /** + * Set site view data + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addsite_views = (isset($item->addsite_views) + && JsonHelper::check($item->addsite_views)) + ? json_decode((string) $item->addsite_views, true) : null; + + if (ArrayHelper::check($item->addsite_views)) + { + $this->config->lang_target = 'site'; + $this->config->build_target = 'site'; + + // build the site_views settings + $item->site_views = array_map( + function ($array) { + // has become a legacy issue, can't remove this + $array['view'] = $array['siteview']; + $array['settings'] = $this->site->get( + $array['view'] + ); + + return array_map( + function ($value) { + if (!ArrayHelper::check($value) + && !ObjectHelper::check($value) + && strval($value) === strval(intval($value))) + { + return (int) $value; + } + + return $value; + }, $array + ); + }, array_values($item->addsite_views) + ); + + // unset original value + unset($item->addsite_views); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sql.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sql.php new file mode 100644 index 000000000..ac2df63ec --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sql.php @@ -0,0 +1,97 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Model\Sqldump; + + +/** + * Model Sql Class + * + * @since 3.2.0 + */ +class Sql +{ + /** + * Compiler Customcode Dispenser + * + * @var Dispenser + * @since 3.2.0 + */ + protected Dispenser $dispenser; + + /** + * Compiler SQL Dump + * + * @var Sqldump + * @since 3.2.0 + */ + protected Sqldump $dump; + + /** + * Constructor + * + * @param Dispenser|null $dispenser The compiler customcode dispenser. + * @param Sqldump|null $dump The compiler SQL dump. + * + * @since 3.2.0 + */ + public function __construct(?Dispenser $dispenser = null, ?Sqldump $dump = null) + { + $this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser'); + $this->dump = $dump ?: Compiler::_('Model.Sqldump'); + } + + /** + * Set sql + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + if (isset($item->add_sql) && $item->add_sql == 1 && isset($item->source)) + { + if ($item->source == 1 && isset($item->tables) && + ($string = $this->dump->get( + $item->tables, $item->name_single_code, $item->id + )) !== null) + { + // build and add the SQL dump + // we add this directly to avoid + // dynamic set behaviour + // TODO: create a function in dispenser to manage these + $this->dispenser->hub['sql'][$item->name_single_code] + = $string; + } + elseif ($item->source == 2 && isset($item->sql)) + { + // add the SQL dump string + $this->dispenser->set( + $item->sql, + 'sql', + $item->name_single_code + ); + } + } + + unset($item->tables); + unset($item->sql); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sqldump.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sqldump.php new file mode 100644 index 000000000..e6ed67572 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sqldump.php @@ -0,0 +1,321 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * SQL Dump Class + * + * @since 3.2.0 + */ +class Sqldump +{ + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * @param \JDatabaseDriver|null $db The database object. + + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null, ?\JDatabaseDriver $db = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get SQL Dump + * + * @param array $tables The tables to use in build + * @param string $view The target view/table to dump in + * @param int $view_id The id of the target view + * + * @return string|null The data found with the alias + * @since 3.2.0 + */ + public function get(array $tables, string $view, int $view_id): ?string + { + // first build a query statement to get all the data (insure it must be added - check the tweaking) + if (ArrayHelper::check($tables) + && $this->registry-> // default is to add + get('builder.sql_tweak.' . (int) $view_id . '.add', true)) + { + $counter = 'a'; + + // Create a new query object. + $query = $this->db->getQuery(true); + + // switch to only trigger the run of the query if we have tables to query + $run_query = false; + foreach ($tables as $table) + { + if (isset($table['table'])) + { + if ($counter === 'a') + { + // the main table fields + if (strpos((string) $table['sourcemap'], PHP_EOL) !== false) + { + $fields = explode(PHP_EOL, (string) $table['sourcemap']); + if (ArrayHelper::check($fields)) + { + // reset array buckets + $sourceArray = []; + $targetArray = []; + foreach ($fields as $field) + { + if (strpos($field, "=>") !== false) + { + list($source, $target) = explode( + "=>", $field + ); + $sourceArray[] = $counter . '.' . trim( + $source + ); + $targetArray[] = trim($target); + } + } + if (ArrayHelper::check( + $sourceArray + ) + && ArrayHelper::check( + $targetArray + )) + { + // add to query + $query->select( + $this->db->quoteName( + $sourceArray, $targetArray + ) + ); + $query->from( + '#__' . $table['table'] . ' AS a' + ); + $run_query = true; + } + // we may need to filter the selection + if (($ids_ = $this->registry-> + get('builder.sql_tweak.' . (int) $view_id . '.where', null)) !== null) + { + // add to query the where filter + $query->where( + 'a.id IN (' . $ids_ . ')' + ); + } + } + } + } + else + { + // the other tables + if (strpos((string) $table['sourcemap'], PHP_EOL) !== false) + { + $fields = explode(PHP_EOL, (string) $table['sourcemap']); + if (ArrayHelper::check($fields)) + { + // reset array buckets + $sourceArray = []; + $targetArray = []; + foreach ($fields as $field) + { + if (strpos($field, "=>") !== false) + { + list($source, $target) = explode( + "=>", $field + ); + $sourceArray[] = $counter . '.' . trim( + $source + ); + $targetArray[] = trim($target); + } + if (strpos($field, "==") !== false) + { + list($aKey, $bKey) = explode( + "==", $field + ); + // add to query + $query->join( + 'LEFT', $this->db->quoteName( + '#__' . $table['table'], + $counter + ) . ' ON (' . $this->db->quoteName( + 'a.' . trim($aKey) + ) . ' = ' . $this->db->quoteName( + $counter . '.' . trim($bKey) + ) . ')' + ); + } + } + if (ArrayHelper::check( + $sourceArray + ) + && ArrayHelper::check( + $targetArray + )) + { + // add to query + $query->select( + $this->db->quoteName( + $sourceArray, $targetArray + ) + ); + } + } + } + } + $counter++; + } + else + { + // see where + // var_dump($view); + // jexit(); + } + } + + // check if we should run query + if ($run_query) + { + // now get the data + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // get the data + $data = $this->db->loadObjectList(); + + // start building the MySql dump + $dump = "--"; + $dump .= PHP_EOL . "-- Dumping data for table `#__" + . Placefix::_("component") . "_" . $view + . "`"; + $dump .= PHP_EOL . "--"; + $dump .= PHP_EOL . PHP_EOL . "INSERT INTO `#__" . Placefix::_("component") . "_" . $view . "` ("; + foreach ($data as $line) + { + $comaSet = 0; + foreach ($line as $fieldName => $fieldValue) + { + if ($comaSet == 0) + { + $dump .= $this->db->quoteName($fieldName); + } + else + { + $dump .= ", " . $this->db->quoteName( + $fieldName + ); + } + $comaSet++; + } + break; + } + $dump .= ") VALUES"; + $coma = 0; + foreach ($data as $line) + { + if ($coma == 0) + { + $dump .= PHP_EOL . "("; + } + else + { + $dump .= "," . PHP_EOL . "("; + } + $comaSet = 0; + foreach ($line as $fieldName => $fieldValue) + { + if ($comaSet == 0) + { + $dump .= $this->escape($fieldValue); + } + else + { + $dump .= ", " . $this->escape( + $fieldValue + ); + } + $comaSet++; + } + $dump .= ")"; + $coma++; + } + $dump .= ";"; + + // return build dump query + return $dump; + } + } + } + + return null; + } + + /** + * Escape the values for a SQL dump + * + * @param string|array $value the value to escape + * + * @return string|array on success with escaped string + * @since 3.2.0 + */ + protected function escape($value) + { + // if array then return mapped + if (ArrayHelper::check($value)) + { + return array_map(__METHOD__, $value); + } + + // if string make sure it is correctly escaped + if (StringHelper::check($value) && !is_numeric($value)) + { + return $this->db->quote($value); + } + + // if empty value return place holder + if (empty($value)) + { + return "''"; + } + + // if not array or string then return number + return $value; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sqltweaking.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sqltweaking.php new file mode 100644 index 000000000..960f6076d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Sqltweaking.php @@ -0,0 +1,180 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Model Sql Tweaking Class + * + * @since 3.2.0 + */ +class Sqltweaking +{ + /** + * Compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + } + + /** + * Set sql tweaking if needed + * + * @param object $item The extension data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + // set the sql_tweak data + $item->sql_tweak = (isset($item->sql_tweak) + && JsonHelper::check($item->sql_tweak)) + ? json_decode((string) $item->sql_tweak, true) : null; + + if (ArrayHelper::check($item->sql_tweak)) + { + // build the tweak settings + $this->tweak( + array_map( + fn($array) => array_map( + function ($value) { + if (!ArrayHelper::check($value) + && !ObjectHelper::check( + $value + ) + && strval($value) === strval( + intval($value) + )) + { + return (int) $value; + } + + return $value; + }, $array + ), array_values($item->sql_tweak) + ) + ); + } + + unset($item->sql_tweak); + } + + /** + * To limit the SQL Demo data build in the views + * + * @param array $settings Tweaking array. + * + * @return void + * @since 3.2.0 + */ + protected function tweak($settings) + { + if (ArrayHelper::check($settings)) + { + foreach ($settings as $setting) + { + // should sql dump be added + if (1 == $setting['add_sql']) + { + // add sql (by option) + if (2 == $setting['add_sql_options']) + { + // rest always + $id_array = []; + + // by id (first remove backups) + $ids = $setting['ids']; + + // now get the ids + if (strpos((string) $ids, ',') !== false) + { + $id_array = (array) array_map( + 'trim', explode(',', (string) $ids) + ); + } + else + { + $id_array[] = trim((string) $ids); + } + $id_array_new = []; + + // check for ranges + foreach ($id_array as $key => $id) + { + if (strpos($id, '=>') !== false) + { + $id_range = (array) array_map( + 'trim', explode('=>', $id) + ); + unset($id_array[$key]); + // build range + if (count((array) $id_range) == 2) + { + $range = range( + $id_range[0], $id_range[1] + ); + $id_array_new = [...$id_array_new, ...$range]; + } + } + } + + if (ArrayHelper::check($id_array_new)) + { + $id_array = [...$id_array_new, ...$id_array]; + } + + // final fixing to array + if (ArrayHelper::check($id_array)) + { + // unique + $id_array = array_unique($id_array, SORT_NUMERIC); + // sort + sort($id_array, SORT_NUMERIC); + // now set it to global + $this->registry-> + set('builder.sql_tweak.' . (int) $setting['adminview'] . '.where', implode(',', $id_array)); + } + } + } + else + { + // do not add sql dump options + $this->registry-> + set('builder.sql_tweak.' . (int) $setting['adminview'] . '.add', false); + } + } + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Tabs.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Tabs.php new file mode 100644 index 000000000..f882ffc40 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Tabs.php @@ -0,0 +1,71 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Model Tabs Class + * + * @since 3.2.0 + */ +class Tabs +{ + /** + * Set the local tabs + * + * @param object $item The view data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + $item->addtabs = (isset($item->addtabs) + && JsonHelper::check($item->addtabs)) + ? json_decode((string) $item->addtabs, true) : null; + + if (ArrayHelper::check($item->addtabs)) + { + $nr = 1; + foreach ($item->addtabs as $tab) + { + $item->tabs[$nr] = trim((string) $tab['name']); + $nr++; + } + } + + // if Details tab is not set, then set it here + if (!isset($item->tabs[1])) + { + $item->tabs[1] = 'Details'; + } + + // always make sure that publishing is lowercase + if (($removeKey = array_search( + 'publishing', array_map('strtolower', $item->tabs) + )) !== false) + { + $item->tabs[$removeKey] = 'publishing'; + } + + // make sure to set the publishing tab (just in case we need it) + $item->tabs[15] = 'publishing'; + + unset($item->addtabs); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php new file mode 100644 index 000000000..9d994fe3b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php @@ -0,0 +1,90 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Joomla Update Server Class + * + * @since 3.2.0 + */ +class Updateserver +{ + /** + * Set version updates + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + // set the version updates + $item->version_update = (isset($item->version_update) + && JsonHelper::check($item->version_update)) + ? json_decode((string) $item->version_update, true) : null; + if (ArrayHelper::check($item->version_update)) + { + $item->version_update = array_values( + $item->version_update + ); + + // set the change log details + $this->changelog($item); + } + } + + /** + * Set changelog values to component changelog + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + protected function changelog(object &$item) + { + // set the version updates + $bucket = []; + foreach ($item->version_update as $update) + { + if (isset($update['change_log']) && StringHelper::check($update['change_log']) + && isset($update['version']) && StringHelper::check($update['version'])) + { + $bucket[] = [ + 'version' => $update['version'], + 'change_log' => '# v' . $update['version'] . PHP_EOL . PHP_EOL . $update['change_log'] + ]; + } + } + + // Sort bucket by version, newest at the top + usort($bucket, function ($a, $b) { + return version_compare($b['version'], $a['version']); + }); + + // Extract change logs from sorted bucket + $sorted_change_logs = array_column($bucket, 'change_log'); + + if (ArrayHelper::check($sorted_change_logs)) + { + $item->changelog = implode(PHP_EOL . PHP_EOL, $sorted_change_logs); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php new file mode 100644 index 000000000..c2242e14d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php @@ -0,0 +1,259 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Model Update sql Class + * + * @since 3.2.0 + */ +class Updatesql +{ + /** + * The admin view names + * + * @var array + * @since 3.2.0 + */ + protected array $name = []; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Constructor + * + * @param Registry|null $registry The compiler registry object. + * + * @since 3.2.0 + */ + public function __construct(?Registry $registry = null) + { + $this->registry = $registry ?: Compiler::_('Registry'); + } + + /** + * check if an update SQL is needed + * + * @param mixed $old The old values + * @param mixed $new The new values + * @param string $type The type of values + * @param mixed $key The id/key where values changed + * @param array|null $ignore The ids to ignore + * + * @return void + * @since 3.2.0 + */ + public function set($old, $new, string $type, $key = null, ?array $ignore = null) + { + // check if there were new items added + if (ArrayHelper::check($new) && ArrayHelper::check($old)) + { + // check if this is old repeatable field + if (isset($new[$type])) + { + foreach ($new[$type] as $item) + { + $newItem = true; + + // check if this is an id to ignore + if (ArrayHelper::check($ignore) + && in_array( + $item, $ignore + )) + { + // don't add ignored ids + $newItem = false; + } + // check if this is old repeatable field + elseif (isset($old[$type]) + && ArrayHelper::check($old[$type])) + { + if (!in_array($item, $old[$type])) + { + // we have a new item, lets add to SQL + $this->add($type, $item, $key); + } + + // add only once + $newItem = false; + } + elseif (!isset($old[$type])) + { + // we have new values + foreach ($old as $oldItem) + { + if (isset($oldItem[$type])) + { + if ($oldItem[$type] == $item[$type]) + { + $newItem = false; + break; + } + } + else + { + $newItem = false; + break; + } + } + } + else + { + $newItem = false; + } + + // add if new + if ($newItem) + { + // we have a new item, lets add to SQL + $this->add($type, $item[$type], $key); + } + } + } + else + { + foreach ($new as $item) + { + if (isset($item[$type])) + { + // search to see if this is a new value + $newItem = true; + + // check if this is an id to ignore + if (ArrayHelper::check($ignore) + && in_array($item[$type], $ignore)) + { + // don't add ignored ids + $newItem = false; + } + // check if this is old repeatable field + elseif (isset($old[$type]) + && ArrayHelper::check($old[$type])) + { + if (in_array($item[$type], $old[$type])) + { + $newItem = false; + } + } + elseif (!isset($old[$type])) + { + // we have new values + foreach ($old as $oldItem) + { + if (isset($oldItem[$type])) + { + if ($oldItem[$type] == $item[$type]) + { + $newItem = false; + break; + } + } + else + { + $newItem = false; + break; + } + } + } + else + { + $newItem = false; + } + + // add if new + if ($newItem) + { + // we have a new item, lets add to SQL + $this->add($type, $item[$type], $key); + } + } + } + } + } + elseif ($key && ((StringHelper::check($new) && StringHelper::check($old)) + || (is_numeric($new) && is_numeric($old))) && $new !== $old) + { + // set at key + $this->registry->set('builder.update_sql.' . $type . '.' . $key, ['old' => $old, 'new' => $new]); + } + } + + /** + * Set the add sql + * + * @param string $type The type of values + * @param int $item The item id to add + * @param mixed $key The id/key where values changed + * + * @return void + * @since 3.2.0 + */ + protected function add(string $type, int $item, $key = null) + { + // add key if found + if ($key) + { + $this->registry->set('builder.add_sql.' . $type . '.' . $key . '.' . $item, $item); + } + else + { + // convert admin view id to name + if ('adminview' === $type) + { + $this->registry->set('builder.add_sql.' . $type . '.' . $this->name($item), + $item + ); + } + else + { + $this->registry->set('builder.add_sql.' . $type, $item); + } + } + } + + /** + * Get the Admin view table name + * + * @param int $id The item id to add + * + * @return string the admin view code name + * @since 3.2.0 + */ + protected function name(int $id): string + { + // get name if not set + if (!isset($this->name[$id])) + { + $this->name[$id] = StringHelper::safe( + GetHelper::var('admin_view', $id, 'id', 'name_single') + ); + } + + return $this->name[$id] ?? 'error'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Whmcs.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Whmcs.php new file mode 100644 index 000000000..378ca8739 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Whmcs.php @@ -0,0 +1,72 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Model; + + +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Model Whmcs Class + * + * @since 3.2.0 + */ +class Whmcs +{ + /** + * Set whmcs links if needed + * + * @param object $item The extension data + * + * @return void + * @since 3.2.0 + */ + public function set(object &$item) + { + if (1 == $item->add_license + && (!isset($item->whmcs_buy_link) + || !StringHelper::check( + $item->whmcs_buy_link + ))) + { + // update with the whmcs url + if (isset($item->whmcs_url) + && StringHelper::check($item->whmcs_url)) + { + $item->whmcs_buy_link = $item->whmcs_url; + } + // use the company website + elseif (isset($item->website) + && StringHelper::check($item->website)) + { + $item->whmcs_buy_link = $item->website; + $item->whmcs_url = rtrim((string) $item->website, '/') + . '/whmcs'; + } + // none set + else + { + $item->whmcs_buy_link = '#'; + $item->whmcs_url = '#'; + } + } + // since the license details are not set clear + elseif (0 == $item->add_license) + { + $item->whmcs_key = ''; + $item->whmcs_buy_link = ''; + $item->whmcs_url = ''; + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder.php new file mode 100644 index 000000000..cb10955ca --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder.php @@ -0,0 +1,508 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PlaceholderInterface; + + +/** + * Compiler Placeholder + * + * @since 3.2.0 + */ +class Placeholder implements PlaceholderInterface +{ + /** + * The active placeholders + * + * @var array + * @since 3.2.0 + **/ + public array $active = []; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Constructor. + * + * @param Config|null $config The compiler config object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null) + { + $this->config = $config ?: Compiler::_('Config'); + } + + /** + * Set content + * + * @param string $key The main string key + * @param mixed $value The values to set + * @param bool $hash Add the hash around the key + * + * @return void + * @since 3.2.0 + */ + public function set(string $key, $value, bool $hash = true) + { + if ($hash) + { + $this->set_($key, $value); + $this->set_h($key, $value); + } + else + { + $this->active[$key] = $value; + } + } + + /** + * Get content by key + * + * @param string $key The main string key + * + * @return mixed + * @since 3.2.0 + */ + public function get(string $key) + { + return $this->active[$key] ?? $this->get_($key) ?? $this->get_h($key) ?? null; + } + + /** + * Does key exist at all in any variation + * + * @param string $key The main string key + * + * @return bool + * @since 3.2.0 + */ + public function exist(string $key): bool + { + return isset($this->active[$key]) || $this->exist_($key) || $this->exist_h($key); + } + + /** + * Add content + * + * @param string $key The main string key + * @param mixed $value The values to set + * @param bool $hash Add the hash around the key + * + * @return void + * @since 3.2.0 + */ + public function add(string $key, $value, bool $hash = true) + { + if ($hash) + { + $this->add_($key, $value); + $this->add_h($key, $value); + } + elseif (isset($this->active[$key])) + { + $this->active[$key] .= $value; + } + else + { + $this->active[$key] = $value; + } + } + + /** + * Remove content + * + * @param string $key The main string key + * + * @return void + * @since 3.2.0 + */ + public function remove(string $key) + { + if (isset($this->active[$key])) + { + unset($this->active[$key]); + } + else + { + $this->remove_($key); + $this->remove_h($key); + } + } + + /** + * Set content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function set_(string $key, $value) + { + $this->active[Placefix::_($key)] = $value; + } + + /** + * Get content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * + * @return mixed + * @since 3.2.0 + */ + public function get_(string $key) + { + return $this->active[Placefix::_($key)] ?? null; + } + + /** + * Does key exist with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * + * @return bool + * @since 3.2.0 + */ + public function exist_(string $key): bool + { + return isset($this->active[Placefix::_($key)]); + } + + /** + * Add content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function add_(string $key, $value) + { + if (isset($this->active[Placefix::_($key)])) + { + $this->active[Placefix::_($key)] .= $value; + } + else + { + $this->active[Placefix::_($key)] = $value; + } + } + + /** + * Remove content with [ [ [ ... ] ] ] hash + * + * @param string $key The main string key + * + * @return void + * @since 3.2.0 + */ + public function remove_(string $key) + { + if ($this->exist_($key)) + { + unset($this->active[Placefix::_($key)]); + } + } + + /** + * Set content with # # # hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function set_h(string $key, $value) + { + $this->active[Placefix::_h($key)] = $value; + } + + /** + * Get content with # # # hash + * + * @param string $key The main string key + * + * @return mixed + * @since 3.2.0 + */ + public function get_h(string $key) + { + return $this->active[Placefix::_h($key)] ?? null; + } + + /** + * Does key exist with # # # hash + * + * @param string $key The main string key + * + * @return bool + * @since 3.2.0 + */ + public function exist_h(string $key): bool + { + return isset($this->active[Placefix::_h($key)]); + } + + /** + * Add content with # # # hash + * + * @param string $key The main string key + * @param mixed $value The values to set + * + * @return void + * @since 3.2.0 + */ + public function add_h(string $key, $value) + { + if ($this->exist_h($key)) + { + $this->active[Placefix::_h($key)] .= $value; + } + else + { + $this->active[Placefix::_h($key)] = $value; + } + } + + /** + * Remove content with # # # hash + * + * @param string $key The main string key + * + * @return void + * @since 3.2.0 + */ + public function remove_h(string $key) + { + if ($this->exist_h($key)) + { + unset($this->active[Placefix::_h($key)]); + } + } + + /** + * Set a type of placeholder with set of values + * + * @param string $key The main string for placeholder key + * @param array $values The values to add + * + * @return void + * @since 3.2.0 + */ + public function setType(string $key, array $values) + { + // always fist reset the type + $this->clearType($key); + + // only add if there are values + if (ArrayHelper::check($values)) + { + $number = 0; + foreach ($values as $value) + { + $this->set($key . $number, $value); + $number++; + } + } + } + + /** + * Remove a type of placeholder by main key + * + * @param string $key The main string for placeholder key + * + * @return void + * @since 3.2.0 + */ + public function clearType(string $key) + { + $keys = [Placefix::_($key), Placefix::_h($key), $key]; + + foreach ($keys as $_key) + { + $this->active = array_filter( + $this->active, + fn(string $k) => preg_replace('/\d/', '', $k) !== $_key, + ARRAY_FILTER_USE_KEY + ); + } + } + + /** + * Update the data with the placeholders + * + * @param string $data The actual data + * @param array $placeholder The placeholders + * @param int $action The action to use + * + * THE ACTION OPTIONS ARE + * 1 -> Just replace (default) + * 2 -> Check if data string has placeholders + * 3 -> Remove placeholders not in data string + * + * @return string + * @since 3.2.0 + */ + public function update(string $data, array $placeholder, int $action = 1): string + { + // make sure the placeholders is an array + if (!ArrayHelper::check($placeholder)) + { + return $data; + } + + // continue with the work of replacement + if (1 == $action) // <-- just replace (default) + { + return str_replace( + array_keys($placeholder), array_values($placeholder), $data + ); + } + elseif (2 == $action) // <-- check if data string has placeholders + { + $replace = false; + foreach (array_keys($placeholder) as $key) + { + if (strpos($data, $key) !== false) + { + $replace = true; + break; + } + } + // only replace if the data has these placeholder values + if ($replace) + { + return str_replace( + array_keys($placeholder), array_values($placeholder), $data + ); + } + } + elseif (3 == $action) // <-- remove placeholders not in data string + { + $replace = $placeholder; + foreach (array_keys($replace) as $key) + { + if (strpos($data, $key) === false) + { + unset($replace[$key]); + } + } + // only replace if the data has these placeholder values + if (ArrayHelper::check($replace)) + { + return str_replace( + array_keys($replace), array_values($replace), $data + ); + } + } + + return $data; + } + + /** + * Update the data with the active placeholders + * + * @param string $data The actual data + * + * @return string + * @since 3.2.0 + */ + public function update_(string $data): string + { + // just replace the placeholders in data + return str_replace( + array_keys($this->active), array_values($this->active), $data + ); + } + + /** + * return the placeholders for inserted and replaced code + * + * @param int $type The type of placement + * @param int|null $id The code id in the system + * + * @return array with start and end keys + * @since 3.2.0 + */ + public function keys(int $type, ?int $id = null): array + { + switch ($type) + { + case 11: + //***[REPLACED$$$$]***//**1**/ + if ($this->config->get('add_placeholders', false) === true) + { + return [ + 'start' => '/***[REPLACED$$$$]***//**' . $id . '**/', + 'end' => '/***[/REPLACED$$$$]***/' + ]; + } + break; + case 12: + //***[INSERTED$$$$]***//**1**/ + if ($this->config->get('add_placeholders', false) === true) + { + return [ + 'start' => '/***[INSERTED$$$$]***//**' . $id . '**/', + 'end' => '/***[/INSERTED$$$$]***/' + ]; + } + break; + case 21: + // + if ($this->config->get('add_placeholders', false) === true) + { + return [ + 'start' => '', + 'end' => '' + ]; + } + break; + case 22: + // + if ($this->config->get('add_placeholders', false) === true) + { + return [ + 'start' => '', + 'end' => '' + ]; + } + break; + case 33: + return ['start' => Placefix::h(), 'end' => Placefix::h()]; + break; + case 66: + return ['start' => Placefix::b(), 'end' => Placefix::d()]; + break; + } + + return [ 'start' => "", 'end' => ""]; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php new file mode 100644 index 000000000..6a075540e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php @@ -0,0 +1,400 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Placeholder; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Language; +use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor as Power; + + +/** + * Compiler Placeholder Reverse + * + * @since 3.2.0 + */ +class Reverse +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Compiler Language + * + * @var Language + * @since 3.2.0 + **/ + protected Language $language; + + /** + * Compiler Language Extractor + * + * @var Extractor + * @since 3.2.0 + **/ + protected Extractor $extractor; + + /** + * Super Power Extractor + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Constructor. + * + * @param Config|null $config The compiler config object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Language|null $language The compiler language object. + * @param Extractor|null $extractor The compiler language extractor object. + * @param Power|null $power The compiler power extractor object. + * + * @since 3.2.0 + */ + public function __construct( + ?Config $config = null, ?Placeholder $placeholder = null, + ?Language $language = null, ?Extractor $extractor = null, + ?Power $power = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->language = $language ?: Compiler::_('Language'); + $this->extractor = $extractor ?: Compiler::_('Language.Extractor'); + $this->power = $power ?: Compiler::_('Power.Extractor'); + } + + /** + * Reverse Engineer the dynamic placeholders (TODO hmmmm this is not ideal) + * + * @param string $string The string to reverse + * @param array $placeholders The values to search for + * @param string $target The target path type + * @param int|null $id The custom code id + * @param string $field The field name + * @param string $table The table name + * @param array|null $useStatements The file use statements (needed for super powers) + * + * @return string + * @since 3.2.0 + */ + public function engine(string $string, array &$placeholders, + string $target, ?int $id = null, string $field = 'code', + string $table = 'custom_code', ?array $useStatements = null): string + { + // get local code if set + if ($id > 0 && $code = base64_decode( + (string) GetHelper::var($table, $id, 'id', $field) + )) + { + $string = $this->setReverse( + $string, $code, $target, $useStatements + ); + } + + return $this->placeholder->update($string, $placeholders, 2); + } + + /** + * Reverse engineer the dynamic language, and super powers + * + * @param string $updateString The string to update + * @param string $string The string to use language update + * @param string $target The target path type + * @param array|null $useStatements The file use statements (needed for super powers) + * + * @return string + * @since 3.2.0 + */ + protected function setReverse(string $updateString, string $string, + string $target, ?array $useStatements): string + { + // we have to reverse engineer to super powers + $updateString = $this->reverseSuperPowers($updateString, $string, $useStatements); + + // reverse engineer the language strings + $updateString = $this->reverseLanguage($updateString, $string, $target); + + // reverse engineer the custom code (if possible) + // $updateString = $this->reverseCustomCode($updateString, $string); // TODO - we would like to also reverse basic customcode + + return $updateString; + } + + /** + * Set the super powers keys for the reveres process + * + * @param string $updateString The string to update + * @param string $string The string to use for super power update + * @param array|null $useStatements The file use statements (needed for super powers) + * + * @return string + * @since 3.2.0 + */ + protected function reverseSuperPowers(string $updateString, string $string, + ?array $useStatements): string + { + // only if we have use statements can we reverse engineer this + if ($useStatements !== null && ($powers = $this->power->reverse($string)) !== null && + ($reverse = $this->getReversePower($powers, $useStatements)) !== null) + { + return $this->placeholder->update($updateString, $reverse); + } + + return $updateString; + } + + /** + * Set the super powers keys for the reveres process + * + * @param array $powers The powers found in the database text + * @param array $useStatements The file use statements + * + * @return array|null + * @since 3.2.0 + */ + protected function getReversePower(array $powers, array $useStatements): ?array + { + $matching_statements = []; + foreach ($useStatements as $use_statement) + { + $namespace = substr($use_statement, 4, -1); // remove 'use ' and ';' + $class_name = ''; + + // Check for 'as' alias + if (strpos($namespace, ' as ') !== false) + { + list($namespace, $class_name) = explode(' as ', $namespace); + } + + // If there is no 'as' alias, get the class name from the last '\' + if (empty($class_name)) + { + $last_slash = strrpos($namespace, '\\'); + if ($last_slash !== false) + { + $class_name = substr($namespace, $last_slash + 1); + } + } + + // Check if the namespace is in the powers array + if (in_array($namespace, $powers)) + { + $guid = array_search($namespace, $powers); + $matching_statements[$class_name] = + 'Super_'.'_'.'_' . str_replace('-', '_', $guid) . '_'.'_'.'_Power'; + } + } + + if ($matching_statements !== []) + { + return $matching_statements; + } + + return null; + } + + /** + * Set the language strings for the reveres process + * + * @param string $updateString The string to update + * @param string $string The string to use language update + * @param string $target The target path type + * + * @return string + * @since 3.2.0 + */ + protected function reverseLanguage(string $updateString, string $string, string $target): string + { + // get targets to search for + $lang_string_targets = array_filter( + $this->config->lang_string_targets, + fn($get): bool => strpos($string, (string) $get) !== false + ); + // check if we should continue + if (ArrayHelper::check($lang_string_targets)) + { + // start lang holder + $lang_holders = []; + // set the lang for both since we don't know what area is being targeted + $_tmp = $this->config->lang_target; + // set the lang based on target + if (strpos($target, 'module') !== false) + { + // backup lang prefix + $_tmp_lang_prefix = $this->config->lang_prefix; + // set the new lang prefix + $lang_prefix = strtoupper( + str_replace('module', 'mod', $target) + ); + $this->config->set('lang_prefix', $lang_prefix); + // now set the lang + if (isset($this->extractor->langKeys[$this->config->lang_prefix])) + { + $this->config->lang_target = $this->extractor->langKeys[$this->config->lang_prefix]; + } + else + { + $this->config->lang_target = 'module'; + } + } + elseif (strpos($target, 'plugin') !== false) + { + // backup lang prefix + $_tmp_lang_prefix = $this->config->lang_prefix; + // set the new lang prefix + $lang_prefix = strtoupper( + str_replace('plugin', 'plg', $target) + ); + $this->config->set('lang_prefix', $lang_prefix); + // now set the lang + if (isset($this->extractor->langKeys[$this->config->lang_prefix])) + { + $this->config->lang_target = $this->extractor->langKeys[$this->config->lang_prefix]; + } + else + { + $this->config->lang_target = 'plugin'; + } + } + else + { + $this->config->lang_target = 'both'; + } + // set language data + foreach ($lang_string_targets as $lang_string_target) + { + $lang_check[] = GetHelper::allBetween( + $string, $lang_string_target . "'", "'" + ); + $lang_check[] = GetHelper::allBetween( + $string, $lang_string_target . '"', '"' + ); + } + // merge arrays + $lang_array = ArrayHelper::merge($lang_check); + // continue only if strings were found + if (ArrayHelper::check( + $lang_array + )) //<-- not really needed hmmm + { + foreach ($lang_array as $lang) + { + $_key_lang = StringHelper::safe($lang, 'U'); + // this is there to insure we dont break already added Language strings + if ($_key_lang === $lang) + { + continue; + } + // build lang key + $key_lang = $this->config->lang_prefix . '_' . $_key_lang; + // set lang content string + $this->language->set($this->config->lang_target, $key_lang, $lang); + // reverse the placeholders + foreach ($lang_string_targets as $lang_string_target) + { + $lang_holders[$lang_string_target . "'" . $key_lang . "'"] + = $lang_string_target . "'" . $lang . "'"; + $lang_holders[$lang_string_target . '"' . $key_lang . '"'] + = $lang_string_target . '"' . $lang . '"'; + } + } + // return the found placeholders + $updateString = $this->placeholder->update( + $updateString, $lang_holders + ); + } + // reset the lang + $this->config->lang_target = $_tmp; + // also rest the lang prefix if set + if (isset($_tmp_lang_prefix)) + { + $lang_prefix = $_tmp_lang_prefix; + $this->config->set('lang_prefix', $_tmp_lang_prefix); + } + } + + return $updateString; + } + + /** + * Set the custom code placeholder for the reveres process + * + * @param string $updateString The string to update + * @param string $string The string to use for super power update + * + * @return string + * @since 3.2.0 + */ + protected function reverseCustomCode(string $updateString, string $string): string + { + // check if content has custom code place holder + if (strpos($string, '[CUSTO' . 'MCODE=') !== false) + { + $found = GetHelper::allBetween( + $string, '[CUSTO' . 'MCODE=', ']' + ); + $bucket = []; + if (ArrayHelper::check($found)) + { + foreach ($found as $key) + { + // we only update those without args + if (is_numeric($key) && $get_func_name = GetHelper::var( + 'custom_code', $key, 'id', 'function_name' + )) + { + $bucket[$get_func_name] = (int) $key; + } + elseif (StringHelper::check($key) + && strpos((string) $key, '+') === false) + { + $get_func_name = trim((string) $key); + if (isset($bucket[$get_func_name]) || !$found_local = GetHelper::var( + 'custom_code', $get_func_name, 'function_name', + 'id' + )) + { + continue; + } + $bucket[$get_func_name] = (int) $found_local; + } + } + // TODO - we need to now get the customcode + // search and replace the customcode with the placeholder + } + } + + return $updateString; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php new file mode 100644 index 000000000..314ae6a25 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php @@ -0,0 +1,1075 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\GuidHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\String\NamespaceHelper; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Power\Super as Superpower; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PowerInterface; + + +/** + * Compiler Power + * + * @since 3.2.0 + */ +class Power implements PowerInterface +{ + /** + * All loaded powers + * + * @var array + * @since 3.2.0 + **/ + public array $active = []; + + /** + * All power namespaces + * + * @var array + * @since 3.2.0 + **/ + public array $namespace = []; + + /** + * All composer namespaces + * + * @var array + * @since 3.2.0 + **/ + public array $composer = []; + + /** + * All super powers of this build + * + * @var array + * @since 3.2.0 + **/ + public array $superpowers = []; + + /** + * Old super powers found in the local repos + * + * @var array + * @since 3.2.0 + **/ + public array $old_superpowers = []; + + /** + * The url to the power, if there is an error. + * + * @var string + * @since 3.2.0 + **/ + protected string $fixUrl; + + /** + * The state of all loaded powers + * + * @var array + * @since 3.2.0 + **/ + protected array $state = []; + + /** + * The state of retry to loaded powers + * + * @var array + * @since 3.2.0 + **/ + protected array $retry = []; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Compiler Customcode + * + * @var Customcode + * @since 3.2.0 + **/ + protected Customcode $customcode; + + /** + * Compiler Customcode in Gui + * + * @var Gui + * @since 3.2.0 + **/ + protected Gui $gui; + + /** + * The JCB Superpower class + * + * @var Superpower + * @since 3.2.0 + **/ + protected Superpower $superpower; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Database object to query local DB + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param Config|null $config The compiler config object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * @param Customcode|null $customcode The compiler customcode object. + * @param Gui|null $gui The compiler customcode gui object. + * @param Superpower|null $superpower The JCB superpower object. + * @param \JDatabaseDriver|null $db The Database Driver object. + * @param CMSApplication|null $app The CMS Application object. + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Placeholder $placeholder = null, + ?Customcode $customcode = null, ?Gui $gui = null, ?Superpower $superpower = null, + ?\JDatabaseDriver $db = null, ?CMSApplication $app = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $this->customcode = $customcode ?: Compiler::_('Customcode'); + $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->superpower = $superpower ?: Compiler::_('Superpower'); + $this->db = $db ?: Factory::getDbo(); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * load all the powers linked to this component + * + * @param array $guids The global unique ids of the linked powers + * + * @return void + * @since 3.2.0 + */ + public function load(array $guids) + { + if (ArrayHelper::check($guids)) + { + foreach ($guids as $guid => $build) + { + $this->get($guid, $build); + } + } + } + + /** + * Get a power + * + * @param string $guid The global unique id of the power + * @param int $build Force build switch (to override global switch) + * + * @return object|null + * @since 3.2.0 + */ + public function get(string $guid, int $build = 0): ?object + { + if (($this->config->get('add_power', true) || $build == 1) && $this->set($guid)) + { + return $this->active[$guid]; + } + + return null; + } + + /** + * Set a power + * + * @param string $guid The global unique id of the power + * + * @return bool true on successful setting of a power + * @since 3.2.0 + */ + private function set(string $guid): bool + { + // check if we have been here before + if ($this->isPowerSet($guid)) + { + return $this->state[$guid]; + } + elseif ($this->isGuidValid($guid)) + { + // get the power data + $this->active[$guid] = $this->getPowerData($guid); + + if (is_object($this->active[$guid])) + { + // make sure that in recursion we + // don't try to load this power again + // since during the load of a power we also load + // all powers linked to it + $this->state[$guid] = true; + + // make sure to add any language strings found to all language files + // since we can't know where this is used at this point + $tmp_lang_target = $this->config->lang_target; + $this->config->lang_target = 'both'; + + // we set the fix url if needed + $this->fixUrl + = '"index.php?option=com_componentbuilder&view=powers&task=power.edit&id=' + . $this->active[$guid]->id . '" target="_blank"'; + + // set some keys + $this->active[$guid]->target_type = 'P0m3R!'; + $this->active[$guid]->key = $this->active[$guid]->id . '_' . $this->active[$guid]->target_type; + + // reserve some values for the linker + $this->active[$guid]->unchanged_namespace = $this->active[$guid]->namespace; + $this->active[$guid]->unchanged_description = $this->active[$guid]->description; + + // now set the name + $this->active[$guid]->name = $this->placeholder->update_( + $this->customcode->update($this->active[$guid]->name) + ); + + // now set the code_name and class name + $this->active[$guid]->code_name = $this->active[$guid]->class_name = ClassfunctionHelper::safe( + $this->active[$guid]->name + ); + + // set official name + $this->active[$guid]->official_name = StringHelper::safe( + $this->active[$guid]->name, 'W' + ); + + // set name space + if (!$this->setNamespace($guid)) + { + $this->state[$guid] = false; + unset($this->active[$guid]); + // reset back to starting value + $this->config->lang_target = $tmp_lang_target; + + return false; + } + + // load use ids + $use = []; + $as = []; + + // set extra classes + $this->setLoadSelection($guid); + + // set use classes + $this->setUseSelection($guid, $use, $as); + + // set implement interfaces + $this->setImplements($guid, $use); + + // set extend class + $this->setExtend($guid, $use); + + // set GUI mapper + $guiMapper = [ + 'table' => 'power', + 'id' => (int) $this->active[$guid]->id, + 'type' => 'php' + ]; + + // add the licensing template + $this->setLicensingTemplate($guid, $guiMapper); + + // add the header script + $this->setHeader($guid, $guiMapper); + + // set composer + $this->setComposer($guid); + + // now set the description + $this->active[$guid]->description = (StringHelper::check($this->active[$guid]->description)) ? $this->placeholder->update_( + $this->customcode->update($this->active[$guid]->description), + ) : ''; + + // add the main code if set + $this->setMainClassCode($guid, $guiMapper); + + // load the use classes + $this->setUseAs($guid, $use, $as); + + // reset back to starting value + $this->config->lang_target = $tmp_lang_target; + + // set the approved super power values + $this->setSuperPowers($guid); + + return true; + } + } + + // we failed to get the power, + // so we raise an error message + // only if guid is valid + if ($this->isGuidValid($guid)) + { + // now we search for it via the super power paths + if (empty($this->retry[$guid]) && $this->superpower->load($guid, ['remote', 'local'])) + { + // we found it and it was loaded into the database + unset($this->state[$guid]); + unset($this->active[$guid]); + + // we make sure that this retry only happen once! (just in-case...) + $this->retry[$guid] = true; + + // so we try to load it again + return $this->set($guid); + } + + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_PPOWER_BGUIDSB_NOT_FOUNDP', $guid), + 'Error' + ); + } + + // let's not try again + $this->state[$guid] = false; + + return false; + } + + /** + * Check if the power is already set + * + * @param string $guid The global unique id of the power + * + * @return bool true if the power is already set + * @since 3.2.0 + */ + private function isPowerSet(string $guid): bool + { + return isset($this->state[$guid]); + } + + /** + * Validate the GUID + * + * @param string $guid The global unique id of the power + * + * @return bool true if the GUID is valid + * @since 3.2.0 + */ + private function isGuidValid(string $guid): bool + { + return GuidHelper::valid($guid); + } + + /** + * Get the power data from the database + * + * @param string $guid The global unique id of the power + * + * @return object|null The power data + * @since 3.2.0 + */ + private function getPowerData(string $guid): ?object + { + $query = $this->db->getQuery(true); + $query->select('a.*'); + $query->from('#__componentbuilder_power AS a'); + $query->where($this->db->quoteName('a.guid') . ' = ' . $this->db->quote($guid)); + + $this->db->setQuery($query); + $this->db->execute(); + + if ($this->db->getNumRows()) + { + return $this->db->loadObject(); + } + + return null; + } + + /** + * Set the namespace for this power + * + * @param string $guid The global unique id of the power + * + * @return bool + * @since 3.2.0 + */ + private function setNamespace(string $guid): bool + { + // set namespace + $this->active[$guid]->namespace = $this->placeholder->update_( + $this->active[$guid]->namespace + ); + + // validate namespace + if (strpos($this->active[$guid]->namespace, '\\') === false) + { + // we raise an error message + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP', + ucfirst((string) $this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->namespace, + '"https://www.php-fig.org/psr/psr-4/" target="_blank"', $this->active[$guid]->type, + $this->fixUrl), + 'Error' + ); + + // we break out here + return false; + } + + // setup the path array + $path_array = (array) explode('\\', $this->active[$guid]->namespace); + + // make sure all sub folders in src dir is set and remove all characters that will not work in folders naming + $this->active[$guid]->namespace = $this->getCleanNamespace(str_replace('.', '\\', $this->active[$guid]->namespace)); + + // make sure it has two or more + if (ArrayHelper::check($path_array) <= 1) + { + // we raise an error message + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_S_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP', + ucfirst((string) $this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->namespace, + '"https://www.php-fig.org/psr/psr-4/" target="_blank"', $this->active[$guid]->type, + $this->fixUrl), + 'Error' + ); + + // we break out here + return false; + } + + // get the file and class name (the last value in array) + $file_name = array_pop($path_array); + + // src array bucket + $src_array = []; + + // do we have src folders + if (strpos($file_name, '.') !== false) + { + // we have src folders in the namespace + $src_array = (array) explode('.', $file_name); + + // get the file and class name (the last value in array) + $this->active[$guid]->file_name = array_pop($src_array); + + // namespace array + $namespace_array = [...$path_array, ...$src_array]; + } + else + { + // set the file name + $this->active[$guid]->file_name = $file_name; + + // namespace array + $namespace_array = $path_array; + } + + // the last value is the same as the class name + if ($this->active[$guid]->file_name !== $this->active[$guid]->class_name) + { + // we raise an error message + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_PS_NAMING_MISMATCH_ERROR_SPPTHE_S_NAME_IS_BSB_AND_THE_ENDING_FILE_NAME_IN_THE_NAMESPACE_IS_BSB_THIS_IS_BAD_CONVENTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPA_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP', + ucfirst((string) $this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->type, $this->active[$guid]->class_name, $this->active[$guid]->file_name, + '"https://www.php-fig.org/psr/psr-4/" target="_blank"', + $this->fixUrl), + 'Error' + ); + + // we break out here + return false; + } + + // make sure the arrays are namespace safe + $path_array = + array_map( + fn($val) => $this->getCleanNamespace($val), + $path_array + ); + $namespace_array = + array_map( + fn($val) => $this->getCleanNamespace($val), + $namespace_array + ); + + // set the actual class namespace + $this->active[$guid]->_namespace = implode('\\', $namespace_array); + + // set global namespaces for autoloader + $this->namespace[implode('.', $path_array)] = $path_array; + + // get the parent folder (the first value in array) + $prefix_folder = implode('.', $path_array); + + // make sub folders if still found + $sub_folder = ''; + if (ArrayHelper::check($src_array)) + { + // make sure the arrays are namespace safe + $sub_folder = '/' . implode('/', + array_map( + fn($val) => $this->getCleanNamespace($val), + $src_array + ) + ); + } + + // now we set the paths + $this->active[$guid]->path_jcb = $this->config->get('jcb_powers_path', 'libraries/jcb_powers'); + $this->active[$guid]->path_parent = $this->active[$guid]->path_jcb . '/' . $prefix_folder; + $this->active[$guid]->path = $this->active[$guid]->path_parent . '/src' . $sub_folder; + + return true; + } + + /** + * Set Use Classes + * + * @param string $guid The global unique id of the power + * @param array $use The use array + * @param array $as The use as array + * + * @return void + * @since 3.2.0 + */ + private function setUseSelection(string $guid, array &$use, array &$as) + { + // check if we have use selection + $this->active[$guid]->use_selection = (isset($this->active[$guid]->use_selection) + && JsonHelper::check( + $this->active[$guid]->use_selection + )) ? json_decode((string) $this->active[$guid]->use_selection, true) : null; + + if (ArrayHelper::check($this->active[$guid]->use_selection)) + { + $use = array_values(array_map(function ($u) use(&$as) { + // track the AS options + $as[$u['use']] = empty($u['as']) ? 'default' : (string) $u['as']; + // return the guid + return $u['use']; + }, $this->active[$guid]->use_selection)); + } + else + { + $this->active[$guid]->use_selection = null; + } + } + + /** + * Load Extra Classes + * + * @param string $guid The global unique id of the power + * + * @return void + * @since 3.2.0 + */ + private function setLoadSelection(string $guid) + { + // check if we have load selection + $this->active[$guid]->load_selection = (isset($this->active[$guid]->load_selection) + && JsonHelper::check( + $this->active[$guid]->load_selection + )) ? json_decode((string) $this->active[$guid]->load_selection, true) : null; + + if (ArrayHelper::check($this->active[$guid]->load_selection)) + { + // load use ids + array_map( + // just load it directly and be done with it + fn($power) => $this->set($power['load']), + $this->active[$guid]->load_selection + ); + } + else + { + $this->active[$guid]->load_selection = null; + } + } + + /** + * Set Composer Linked Use and Access Point + * + * @param string $guid The global unique id of the power + * + * @return void + * @since 3.2.0 + */ + private function setComposer(string $guid) + { + // does this have composer powers + $_composer = (isset($this->active[$guid]->composer) + && JsonHelper::check( + $this->active[$guid]->composer + )) ? json_decode((string) $this->active[$guid]->composer, true) : null; + + unset($this->active[$guid]->composer); + + if (ArrayHelper::check($_composer)) + { + // reserve composer values for the linker + $this->active[$guid]->unchanged_composer = $_composer; + + foreach ($_composer as $composer) + { + if (isset($composer['access_point']) && StringHelper::check($composer['access_point']) && + isset($composer['namespace']) && ArrayHelper::check($composer['namespace'])) + { + foreach ($composer['namespace'] as $_namespace) + { + // make sure we have a valid namespace + if (isset($_namespace['use']) && StringHelper::check($_namespace['use']) && + strpos((string) $_namespace['use'], '\\') !== false) + { + // add the namespace to this access point + $as = 'default'; + if (strpos((string) $_namespace['use'], ' as ') !== false) + { + $namespace_as = explode(' as ', (string) $_namespace['use']); + // make sure the AS value is set + if (count($namespace_as) == 2) + { + $as = trim(trim($namespace_as[1], ';')); + } + $namespace = $this->getCleanNamespace($namespace_as[0]); + } + else + { + // trim possible use or ; added to the namespace + $namespace = $this->getCleanNamespace($_namespace['use']); + } + + // check if still valid + if (!StringHelper::check($namespace)) + { + continue; + } + + // add to the header of the class + $this->addToHeader($guid, $this->getUseNamespace($namespace, $as)); + + // add composer namespaces for autoloader + $this->composer[$namespace] = $composer['access_point']; + } + } + } + } + } + else + { + // reserve composer values for the linker + $this->active[$guid]->unchanged_composer = ''; + } + } + + /** + * Set Implements Interface classes + * + * @param string $guid The global unique id of the power + * @param array $use The use array + * + * @return void + * @since 3.2.0 + */ + private function setImplements(string $guid, array &$use) + { + // see if we have implements + $this->active[$guid]->implement_names = []; + + // does this implement + $this->active[$guid]->implements = (isset($this->active[$guid]->implements) + && JsonHelper::check( + $this->active[$guid]->implements + )) ? json_decode((string) $this->active[$guid]->implements, true) : null; + + if ($this->active[$guid]->implements) + { + foreach ($this->active[$guid]->implements as $implement) + { + if ($implement == -1 + && StringHelper::check($this->active[$guid]->implements_custom)) + { + // reserve implements custom for the linker + $this->active[$guid]->unchanged_implements_custom = $this->active[$guid]->implements_custom; + + $this->active[$guid]->implement_names[] = $this->placeholder->update_( + $this->customcode->update($this->active[$guid]->implements_custom) + ); + + // just add this once + unset($this->active[$guid]->implements_custom); + } + // does this extend existing + elseif (GuidHelper::valid($implement)) + { + // check if it was set + if ($this->set($implement)) + { + // get the name + $this->active[$guid]->implement_names[] = $this->get($implement, 1)->class_name; + // add to use + $use[] = $implement; + } + } + } + } + } + + /** + * Set Extend Class + * + * @param string $guid The global unique id of the power + * @param array $use The use array + * + * @return void + * @since 3.2.0 + */ + private function setExtend(string $guid, array &$use) + { + // does this extend something + $this->active[$guid]->extends_name = null; + + // we first check for custom extending options + if ($this->active[$guid]->extends == -1 + && StringHelper::check($this->active[$guid]->extends_custom)) + { + // reserve extends custom for the linker + $this->active[$guid]->unchanged_extends_custom = $this->active[$guid]->extends_custom; + + $this->active[$guid]->extends_name = $this->placeholder->update_( + $this->customcode->update($this->active[$guid]->extends_custom) + ); + + // just add once + unset($this->active[$guid]->extends_custom); + } + // does this extend existing + elseif (GuidHelper::valid($this->active[$guid]->extends)) + { + // check if it was set + if ($this->set($this->active[$guid]->extends)) + { + // get the name + $this->active[$guid]->extends_name = $this->get($this->active[$guid]->extends, 1)->class_name; + // add to use + $use[] = $this->active[$guid]->extends; + } + } + } + + /** + * Set Extra Use Classes + * + * @param string $guid The global unique id of the power + * @param array $use The use array + * @param array $as The use as array + * + * @return void + * @since 3.2.0 + */ + private function setUseAs(string $guid, array $use, array $as) + { + // now add all the extra use statements + if (ArrayHelper::check($use)) + { + foreach (array_unique($use) as $u) + { + if ($this->set($u)) + { + // get the namespace + $namespace = $this->get($u, 1)->namespace; + + // check if it has an AS option + if (isset($as[$u]) && StringHelper::check($as[$u])) + { + // add to the header of the class + $this->addToHeader($guid, $this->getUseNamespace($namespace, $as[$u])); + } + else + { + // add to the header of the class + $this->addToHeader($guid, $this->getUseNamespace($namespace)); + } + } + } + } + } + + /** + * Get Clean Namespace without use or ; as part of the name space + * + * @param string $namespace The actual name space + * @param bool $removeNumbers The switch to remove numbers + * + * @return string + * @since 3.2.0 + */ + private function getCleanNamespace(string $namespace): string + { + // trim possible (use) or (;) or (starting or ending \) added to the namespace + return NamespaceHelper::safe(str_replace(['use ', ';'], '', $namespace)); + } + + /** + * Get [use Namespace\Class;] + * + * @param string $namespace The actual name space + * @param string $as The use as name (default is none) + * + * @return string + * @since 3.2.0 + */ + private function getUseNamespace(string $namespace, string $as = 'default'): string + { + // check if it has an AS option + if ($as !== 'default') + { + return 'use ' . $namespace . ' as ' . $as . ';'; + } + return 'use ' . $namespace . ';'; + } + + /** + * Add to class header + * + * @param string $guid The global unique id of the power + * @param string $string The string to add to header + * + * @return void + * @since 3.2.0 + */ + private function addToHeader(string $guid, string $string) + { + // check if it is already added manually + if (isset($this->active[$guid]->head) && + strpos((string) $this->active[$guid]->head, $string) === false) + { + $this->active[$guid]->head .= $string . PHP_EOL; + } + } + + /** + * Set the power licensing template + * + * @param string $guid The global unique id of the power + * @param array $guiMapper The gui mapper array + * + * @return void + * @since 3.2.0 + */ + private function setLicensingTemplate(string $guid, array $guiMapper): void + { + if ($this->active[$guid]->add_licensing_template == 2 && + StringHelper::check($this->active[$guid]->licensing_template)) + { + // set GUI mapper field + $guiMapper['field'] = 'licensing_template'; + + // reserve licensing template for the linker + $this->active[$guid]->unchanged_licensing_template = base64_decode( + (string) $this->active[$guid]->licensing_template + ); + + // base64 Decode code + $this->active[$guid]->licensing_template = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + $this->active[$guid]->unchanged_licensing_template + ) + ), + $guiMapper + ); + } + else + { + $this->active[$guid]->add_licensing_template = 1; + $this->active[$guid]->licensing_template = ''; + $this->active[$guid]->unchanged_licensing_template = ''; + } + } + + /** + * Set the power header script + * + * @param string $guid The global unique id of the power + * @param array $guiMapper The gui mapper array + * + * @return void + * @since 3.2.0 + */ + private function setHeader(string $guid, array $guiMapper): void + { + if ($this->active[$guid]->add_head == 1) + { + // set GUI mapper field + $guiMapper['field'] = 'head'; + + // reserve header for the linker + $this->active[$guid]->unchanged_head = base64_decode( + (string) $this->active[$guid]->head + ); + + // base64 Decode code + $this->active[$guid]->head = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + $this->active[$guid]->unchanged_head + ) + ), + $guiMapper + ) . PHP_EOL; + } + else + { + $this->active[$guid]->head = ''; + $this->active[$guid]->unchanged_head = ''; + } + } + + /** + * Set the power main class code + * + * @param string $guid The global unique id of the power + * @param array $guiMapper The gui mapper array + * + * @return void + * @since 3.2.0 + */ + private function setMainClassCode(string $guid, array $guiMapper): void + { + if (StringHelper::check($this->active[$guid]->main_class_code)) + { + // reserve main class code for the linker + $this->active[$guid]->unchanged_main_class_code = base64_decode( + (string) $this->active[$guid]->main_class_code + ); + + // set GUI mapper field + $guiMapper['field'] = 'main_class_code'; + + // base64 Decode code + $this->active[$guid]->main_class_code = $this->gui->set( + $this->placeholder->update_( + $this->customcode->update( + $this->active[$guid]->unchanged_main_class_code + ) + ), + $guiMapper + ); + } + else + { + $this->active[$guid]->unchanged_main_class_code = ''; + $this->active[$guid]->main_class_code = ''; + } + } + + /** + * Set the super powers of this power + * + * @param string $guid The global unique id of the power + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowers(string $guid): void + { + // set the approved super power values + if ($this->config->add_super_powers && $this->active[$guid]->approved == 1) + { + $this->active[$guid]->approved_paths = (isset($this->active[$guid]->approved_paths) + && JsonHelper::check( + $this->active[$guid]->approved_paths + )) ? json_decode((string) $this->active[$guid]->approved_paths, true) : null; + + if (ArrayHelper::check($this->active[$guid]->approved_paths)) + { + $global_path = $this->config->local_powers_repository_path; + + // update all paths + $this->active[$guid]->super_power_paths = array_map(function($path) use($global_path, $guid) { + + // remove branch + if (($pos = strpos($path, ':')) !== false) + { + $path = substr($path, 0, $pos); + } + + // set the repo path + $repo = $global_path . '/' . $path; + + // set SuperPowerKey (spk) + $spk = 'Super_'.'_' . str_replace('-', '_', $guid) . '_'.'_Power'; + + // set the global super power + $this->superpowers[$repo][$guid] = [ + 'name' => $this->active[$guid]->code_name, + 'type' => $this->active[$guid]->type, + 'namespace' => $this->active[$guid]->_namespace, + 'code' => 'src/' . $guid . '/code.php', + 'power' => 'src/' . $guid . '/code.power', + 'settings' => 'src/' . $guid . '/settings.json', + 'path' => 'src/' . $guid, + 'spk' => $spk, + 'guid' => $guid + ]; + + return $repo . '/src/' . $guid; + }, array_values($this->active[$guid]->approved_paths)); + + return; + } + } + + // reset all to avoid any misunderstanding down steam + $this->active[$guid]->super_power_paths = null; + $this->active[$guid]->approved_paths = null; + $this->active[$guid]->approved = null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Autoloader.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Autoloader.php new file mode 100644 index 000000000..2a0dec87e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Autoloader.php @@ -0,0 +1,412 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Compiler Autoloader + * + * @since 3.2.0 + */ +class Autoloader +{ + /** + * The Power Class. + * + * @var Power + * @since 3.2.0 + */ + protected Power $power; + + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The ContentOne Class. + * + * @var Content + * @since 3.2.0 + */ + protected Content $content; + + /** + * Helper Class Autoloader + * + * @var string + * @since 3.2.0 + **/ + protected string $helper = ''; + + /** + * Constructor. + * + * @param Power $power The Power Class. + * @param Config $config The Config Class. + * @param Content $content The ContentOne Class. + * + * @since 3.2.0 + */ + public function __construct(Power $power, Config $config, Content $content) + { + $this->power = $power; + $this->config = $config; + $this->content = $content; + + // reset all autoloaders power placeholders + $this->content->set('ADMIN_POWER_HELPER', ''); + $this->content->set('SITE_POWER_HELPER', ''); + $this->content->set('CUSTOM_POWER_AUTOLOADER', ''); + } + + /** + * Set the autoloader into the active content array + * + * @return void + * @since 3.2.0 + */ + public function set() + { + if (ArrayHelper::check($this->power->namespace)) + { + /************************* IMPORTANT SORT NOTICE *********************************************** + * make sure the name space values are sorted from the longest string to the shortest + * so that the search do not mistakenly match a shorter namespace before a longer one + * that has the same short namespace for example: + * NameSpace\SubName\Sub <- will always match first + * NameSpace\SubName\SubSubName + * Should the shorter namespace be listed [first] it will match both of these: + * NameSpace\SubName\Sub\ClassName + * ^^^^^^^^^^^^^^^^^^^^^^ + * NameSpace\SubName\SubSubName\ClassName + * ^^^^^^^^^^^^^^^^^^^^^^ + ***********************************************************************************************/ + uksort($this->power->namespace, fn($a, $b) => strlen((string) $b) - strlen((string) $a)); + + // check if we are using a plugin + if ($this->loadPluginAutoloader()) + { + $this->content->set('PLUGIN_POWER_AUTOLOADER', $this->getPluginAutoloader()); + } + + // load to the helper class + if ($this->loadHelperAutoloader()) + { + // load to admin helper class + $this->content->add('ADMIN_POWER_HELPER', $this->getHelperAutoloader()); + + // load to site helper class if needed + if ($this->loadSiteAutoloader()) + { + $this->content->add('SITE_POWER_HELPER', $this->getHelperAutoloader()); + } + } + + // to add to custom files + $this->content->add('CUSTOM_POWER_AUTOLOADER', $this->getHelperAutoloader()); + } + } + + /** + * Should we load the plugin autoloader + * + * @return bool + * @since 3.2.0 + */ + private function loadPluginAutoloader(): bool + { + return $this->content->exists('PLUGIN_POWER_AUTOLOADER'); + } + + /** + * Should we load the helper class autoloader + * + * @return bool + * @since 3.2.0 + */ + private function loadHelperAutoloader(): bool + { + // for now we load it if the plugin is not loaded + // but we may want to add a switch that + // controls this behaviour. + return !$this->loadPluginAutoloader(); + } + + /** + * Should we load the autoloader in site area + * + * @return bool + * @since 3.2.0 + */ + private function loadSiteAutoloader(): bool + { + return (!$this->config->remove_site_folder || !$this->config->remove_site_edit_folder); + } + + /** + * Get helper autoloader code + * + * @return string + * @since 3.2.0 + */ + private function getPluginAutoloader(): string + { + // load the code + $code = []; + + // if we should not load in the site are + if (($script = $this->getBLockSiteLoading()) !== null) + { + $code[] = $script; + } + + // add the composer stuff here + if (($script = $this->getComposer(2)) !== null) + { + $code[] = $script; + } + + // get the helper autoloader + if (($script = $this->getAutoloader(2)) !== null) + { + $code[] = $script; + } + + // if we have any + if (!empty($code)) + { + return PHP_EOL . PHP_EOL . implode(PHP_EOL . PHP_EOL, $code); + } + + return ''; + } + + /** + * Get helper autoloader code + * + * @return string + * @since 3.2.0 + */ + private function getHelperAutoloader(): string + { + // check if it was already build + if (!empty($this->helper)) + { + return $this->helper; + } + + // load the code + $code = []; + + // add the composer stuff here + if (($script = $this->getComposer(0)) !== null) + { + $code[] = $script; + } + + // get the helper autoloader + if (($script = $this->getAutoloader(0)) !== null) + { + $code[] = $script; + } + + // if we have any + if (!empty($code)) + { + $this->helper = PHP_EOL . PHP_EOL . implode(PHP_EOL . PHP_EOL, $code); + } + + return $this->helper; + } + + /** + * Get code that will block the plugin from loading + * the autoloader in the site area + * + * @return string|null + * @since 3.2.0 + */ + private function getBLockSiteLoading(): ?string + { + // if we should not load in the site are + if (!$this->loadSiteAutoloader()) + { + // we add code to prevent this plugin from triggering on the site area + $not_site = []; + $not_site[] = Indent::_(2) . '//' + . Line::_(__Line__, __Class__) . ' do not run the autoloader in the site area'; + $not_site[] = Indent::_(2) . 'if ($this->app->isClient(\'site\'))'; + $not_site[] = Indent::_(2) . '{'; + $not_site[] = Indent::_(3) . 'return;'; + $not_site[] = Indent::_(2) . '}'; + + return implode(PHP_EOL, $not_site); + } + + return null; + } + + /** + * Get autoloader code + * + * @param int $tabSpace The dynamic tab spacer + * + * @return string|null + * @since 3.2.0 + */ + private function getAutoloader(int $tabSpace): ?string + { + if (($size = ArrayHelper::check($this->power->namespace)) > 0) + { + // we start building the spl_autoload_register function call + $autoload_method = []; + $autoload_method[] = Indent::_($tabSpace) . '//' + . Line::_(__Line__, __Class__) . ' register this component namespace'; + $autoload_method[] = Indent::_($tabSpace) . 'spl_autoload_register(function ($class) {'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '//' + . Line::_(__Line__, __Class__) . ' project-specific base directories and namespace prefix'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '$search = ['; + + // counter to manage the comma in the actual array + $counter = 1; + foreach ($this->power->namespace as $base_dir => $prefix) + { + // don't add the ending comma on last value + if ($size == $counter) + { + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . "'" . $this->config->get('jcb_powers_path', 'libraries/jcb_powers') . "/$base_dir' => '" . implode('\\\\', $prefix) . "'"; + } + else + { + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . "'" . $this->config->get('jcb_powers_path', 'libraries/jcb_powers') . "/$base_dir' => '" . implode('\\\\', $prefix) . "',"; + } + $counter++; + } + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '];'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '// Start the search and load if found'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '$found = false;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '$found_base_dir = "";'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '$found_len = 0;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . 'foreach ($search as $base_dir => $prefix)'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '{'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . '//' + . Line::_(__Line__, __Class__) . ' does the class use the namespace prefix?'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . '$len = strlen($prefix);'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . 'if (strncmp($prefix, $class, $len) === 0)'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . '{'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(3) . '//' + . Line::_(__Line__, __Class__) . ' we have a match so load the values'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(3) . '$found = true;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(3) . '$found_base_dir = $base_dir;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(3) . '$found_len = $len;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(3) . '//' + . Line::_(__Line__, __Class__) . ' done here'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(3) . 'break;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . '}'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '}'; + + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '//' + . Line::_(__Line__, __Class__) . ' check if we found a match'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . 'if (!$found)'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '{'; + + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . '//' + . Line::_(__Line__, __Class__) . ' not found so move to the next registered autoloader'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . 'return;'; + + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '}'; + + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '//' + . Line::_(__Line__, __Class__) . ' get the relative class name'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '$relative_class = substr($class, $found_len);'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '//' + . Line::_(__Line__, __Class__) . ' replace the namespace prefix with the base directory, replace namespace'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '// separators with directory separators in the relative class name, append'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '// with .php'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . "\$file = JPATH_ROOT . '/' . \$found_base_dir . '/src' . str_replace('\\\\', '/', \$relative_class) . '.php';"; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '//' + . Line::_(__Line__, __Class__) . ' if the file exists, require it'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . 'if (file_exists($file))'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '{'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(2) . 'require $file;'; + $autoload_method[] = Indent::_($tabSpace) . Indent::_(1) . '}'; + $autoload_method[] = Indent::_($tabSpace) . '});'; + + return implode(PHP_EOL, $autoload_method); + } + + return null; + } + + /** + * Get the composer autoloader routine + * + * @param int $tabSpace The dynamic tab spacer + * + * @return string|null + * @since 3.2.0 + */ + private function getComposer(int $tabSpace): ?string + { + if (ArrayHelper::check($this->power->composer)) + { + // load the composer routine + $composer_routine = []; + + // counter to manage the comma in the actual array + $add_once = []; + foreach ($this->power->composer as $access_point) + { + // don't add the ending comma on last value + if (empty($add_once[$access_point])) + { + $composer_routine[] = Indent::_($tabSpace) . "\$composer_autoloader = JPATH_LIBRARIES . '/$access_point';"; + $composer_routine[] = Indent::_($tabSpace) . 'if (file_exists($composer_autoloader))'; + $composer_routine[] = Indent::_($tabSpace) . "{"; + $composer_routine[] = Indent::_($tabSpace) . Indent::_(1) . 'require_once $composer_autoloader;'; + $composer_routine[] = Indent::_($tabSpace) . "}"; + + $add_once[$access_point] = true; + } + } + + // this is just about the [autoloader or autoloaders] in the comment ;) + if (count($add_once) == 1) + { + array_unshift($composer_routine, Indent::_($tabSpace) . '//' + . Line::_(__Line__, __Class__) . ' add the autoloader for the composer classes'); + } + else + { + array_unshift($composer_routine, Indent::_($tabSpace) . '//' + . Line::_(__Line__, __Class__) . ' add the autoloaders for the composer classes'); + } + + return implode(PHP_EOL, $composer_routine); + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Extractor.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Extractor.php new file mode 100644 index 000000000..b1b0c5287 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Extractor.php @@ -0,0 +1,244 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\GuidHelper; + + +/** + * Compiler Power Extractor + * @since 3.2.0 + */ +final class Extractor +{ + /** + * The pattern to get the powers + * + * @var string + * @since 3.2.0 + **/ + protected string $pattern = '/Super_'.'_'.'_[a-zA-Z0-9_]+_'.'_'.'_Power/'; + + /** + * Powers GUID's + * + * @var array + * @since 3.2.0 + **/ + protected array $powers = []; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param \JDatabaseDriver|null $db The database object. + * @since 3.2.0 + */ + public function __construct(?\JDatabaseDriver $db = null) + { + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Super Powers from the code string + * + * @param string $code The code + * + * @return array|null + * @since 3.2.0 + */ + public function get_(): ?array + { + return $this->powers !== [] ? $this->powers : null; + } + + /** + * Get Super Powers from the code string + * + * @param string $code The code + * + * @return array|null + * @since 3.2.0 + */ + public function get(string $code): ?array + { + $matches = []; + preg_match_all($this->pattern, $code, $matches); + + $found = $matches[0]; + + if (!empty($found)) + { + return $this->map($found); + } + + return null; + } + + /** + * Get Super Powers from the code string + * + * @param string $code The code + * + * @return array|null + * @since 3.2.0 + */ + public function reverse(string $code): ?array + { + $matches = []; + preg_match_all($this->pattern, $code, $matches); + + $found = $matches[0]; + + if (!empty($found) && ($guids = $this->filter($found)) !== null) + { + return $this->namespaces($guids); + } + + return null; + } + + /** + * Get Super Powers from the code string and load it + * + * @param string $code The code + * + * @return void + * @since 3.2.0 + */ + public function search(string $code) + { + $matches = []; + preg_match_all($this->pattern, $code, $matches); + + $found = $matches[0]; + + if (!empty($found)) + { + $this->load($found); + } + } + + /** + * Load the Super Powers found + * + * @param array $found The found Super Powers + * + * @return void + * @since 3.2.0 + */ + protected function load(array $found) + { + foreach ($found as $super_power) + { + $guid = str_replace(['Super_'.'_'.'_', '_'.'_'.'_Power'], '', $super_power); + $guid = str_replace('_', '-', $guid); + + if (GuidHelper::valid($guid)) + { + $this->powers[$guid] = 1; // 1 force the power to be added + } + } + } + + /** + * Map the Super Powers to GUIDs + * + * @param array $found The found Super Powers + * + * @return array + * @since 3.2.0 + */ + protected function map(array $found): ?array + { + $guids = []; + + foreach ($found as $super_power) + { + $guid = str_replace(['Super_'.'_'.'_', '_'.'_'.'_Power'], '', $super_power); + $guid = str_replace('_', '-', $guid); + + if (GuidHelper::valid($guid)) + { + $guids[$super_power] = $guid; + } + } + + return $guids !== [] ? $guids : null; + } + + /** + * Filter the Super Powers to GUIDs + * + * @param array $found The found Super Powers + * + * @return array + * @since 3.2.0 + */ + protected function filter(array $found): ?array + { + $guids = []; + + foreach ($found as $super_power) + { + $guid = str_replace(['Super_'.'_'.'_', '_'.'_'.'_Power'], '', $super_power); + $guid = str_replace('_', '-', $guid); + + if (GuidHelper::valid($guid)) + { + $guids[$guid] = $guid; + } + } + + return $guids !== [] ? array_values($guids) : null; + } + + /** + * Get the complete namespace strings of the guids passed as an array. + * + * @param array $guids The guids to filter the results + * + * @return array|null The result namespaces with their guids + * @since 3.2.0 + **/ + protected function namespaces(array $guids): ?array + { + $query = $this->db->getQuery(true); + $query->select( + 'DISTINCT REPLACE(' + . $this->db->quoteName('namespace') + . ', ".", "\\\") AS full_namespace, ' + . $this->db->quoteName('guid') + ) + ->from($this->db->quoteName('#__componentbuilder_power')) + ->where($this->db->quoteName('guid') . ' IN (' . implode(',', array_map([$this->db, 'quote'], $guids)) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + if ($this->db->getNumRows()) + { + return $this->db->loadAssocList('guid', 'full_namespace'); + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php new file mode 100644 index 000000000..ed1ed4100 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php @@ -0,0 +1,464 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti as Contents; +use VDM\Joomla\Componentbuilder\Compiler\Power\Autoloader; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repo\Readme as RepoReadme; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repos\Readme as ReposReadme; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; + + +/** + * Compiler Power Infusion + * @since 3.2.0 + */ +class Infusion +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The Power Class. + * + * @var Power + * @since 3.2.0 + */ + protected Power $power; + + /** + * The ContentOne Class. + * + * @var Content + * @since 3.2.0 + */ + protected Content $content; + + /** + * The ContentMulti Class. + * + * @var Contents + * @since 3.2.0 + */ + protected Contents $contents; + + /** + * The Autoloader Class. + * + * @var Autoloader + * @since 3.2.0 + */ + protected Autoloader $autoloader; + + /** + * The Parser Class. + * + * @var Parser + * @since 3.2.0 + */ + protected Parser $parser; + + /** + * The Readme Class. + * + * @var RepoReadme + * @since 3.2.0 + */ + protected RepoReadme $reporeadme; + + /** + * The Readme Class. + * + * @var ReposReadme + * @since 3.2.0 + */ + protected ReposReadme $reposreadme; + + /** + * The Placeholder Class. + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * The EventInterface Class. + * + * @var Event + * @since 3.2.0 + */ + protected Event $event; + + /** + * Power linker values + * + * @var array + * @since 3.2.0 + **/ + protected array $linker = [ + 'add_head' => 'add_head', + 'unchanged_description' => 'description', + 'extends' => 'extends', + 'unchanged_extends_custom' => 'extends_custom', + 'guid' => 'guid', + 'unchanged_head' => 'head', + 'use_selection' => 'use_selection', + 'implements' => 'implements', + 'unchanged_implements_custom' => 'implements_custom', + 'load_selection' => 'load_selection', + 'name' => 'name', + 'power_version' => 'power_version', + 'system_name' => 'system_name', + 'type' => 'type', + 'unchanged_namespace' => 'namespace', + 'unchanged_composer' => 'composer', + 'add_licensing_template' => 'add_licensing_template', + 'unchanged_licensing_template' => 'licensing_template' + ]; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param Power $power The Power Class. + * @param Content $content The ContentOne Class. + * @param Contents $contents The ContentMulti Class. + * @param Autoloader $autoloader The Autoloader Class. + * @param Parser $parser The Parser Class. + * @param RepoReadme $reporeadme The Readme Class. + * @param ReposReadme $reposreadme The Readme Class. + * @param Placeholder $placeholder The Placeholder Class. + * @param Event $event The EventInterface Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, Power $power, Content $content, + Contents $contents, Autoloader $autoloader, + Parser $parser, RepoReadme $reporeadme, + ReposReadme $reposreadme, Placeholder $placeholder, + Event $event) + { + $this->config = $config; + $this->power = $power; + $this->content = $content; + $this->contents = $contents; + $this->autoloader = $autoloader; + $this->parser = $parser; + $this->reporeadme = $reporeadme; + $this->reposreadme = $reposreadme; + $this->placeholder = $placeholder; + $this->event = $event; + } + + /** + * Infuse the powers data with the content + * + * @return void + * @since 3.2.0 + */ + public function set() + { + // parse all powers main code + $this->parsePowers(); + + // set the powers + $this->setSuperPowers(); + + // set the powers + $this->setPowers(); + } + + /** + * We parse the powers to get the class map of all methods + * + * @return void + * @since 3.2.0 + */ + private function parsePowers() + { + // we only do this if super powers are active + if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) + { + foreach ($this->power->active as $n => &$power) + { + if (ObjectHelper::check($power) && isset($power->main_class_code) && + StringHelper::check($power->main_class_code)) + { + // only parse those approved + if ($power->approved == 1) + { + $power->main_class_code = $this->placeholder->update($power->main_class_code, $this->content->allActive()); + $power->parsed_class_code = $this->parser->code($power->main_class_code); + } + } + } + } + } + + /** + * Set the Super Powers details + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowers() + { + // infuse super powers details if set + if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) + { + // TODO we need to update the event signatures + $context = $this->config->component_context; + + foreach ($this->power->superpowers as $path => $powers) + { + $key = StringHelper::safe($path); + + // Trigger Event: jcb_ce_onBeforeInfuseSuperPowerDetails + $this->event->trigger( + 'jcb_ce_onBeforeInfuseSuperPowerDetails', + array(&$context, &$path, &$key, &$powers) + ); + + // we add and all missing powers + if (isset($this->power->old_superpowers[$path])) + { + $this->mergePowers($powers, $this->power->old_superpowers[$path]); + } + + // POWERREADME + $this->contents->set("{$key}|POWERREADME", $this->reposreadme->get($powers)); + + // sort all powers + $this->sortPowers($powers); + + // POWERINDEX + $this->contents->set("{$key}|POWERINDEX", $this->index($powers)); + + // Trigger Event: jcb_ce_onAfterInfuseSuperPowerDetails + $this->event->trigger( + 'jcb_ce_onAfterInfuseSuperPowerDetails', + array(&$context, &$path, &$key, &$powers) + ); + } + } + } + + /** + * Merge the old missing powers found in local repository back into the index + * + * @return void + * @since 3.2.0 + */ + private function mergePowers(array &$powers, array &$old) + { + foreach ($old as $guid => $values) + { + if (!isset($powers[$guid])) + { + $powers[$guid] = $values; + } + } + } + + /** + * Sort Powers + * + * @return void + * @since 3.2.0 + */ + private function sortPowers(array &$powers) + { + ksort($powers, SORT_STRING); + } + + /** + * Set the Powers code + * + * @return void + * @since 3.2.0 + */ + private function setPowers() + { + // infuse powers data if set + if (ArrayHelper::check($this->power->active)) + { + // TODO we need to update the event signatures + $context = $this->config->component_context; + + foreach ($this->power->active as $power) + { + if (ObjectHelper::check($power)) + { + // Trigger Event: jcb_ce_onBeforeInfusePowerData + $this->event->trigger( + 'jcb_ce_onBeforeInfusePowerData', + array(&$context, &$power) + ); + + // POWERCODE + $this->contents->set("{$power->key}|POWERCODE", $this->code($power)); + + // CODEPOWER + $this->contents->set("{$power->key}|CODEPOWER", $this->raw($power)); + + // POWERLINKER + $this->contents->set("{$power->key}|POWERLINKER", $this->linker($power)); + + // POWERLINKER + $this->contents->set("{$power->key}|POWERREADME", $this->reporeadme->get($power)); + + // Trigger Event: jcb_ce_onAfterInfusePowerData + $this->event->trigger( + 'jcb_ce_onAfterInfusePowerData', + array(&$context, &$power) + ); + } + } + + // now set the power autoloader + $this->autoloader->set(); + } + } + + /** + * Build the Super Power Index + * + * @param array $powers All powers of this super power. + * + * @return string + * @since 3.2.0 + */ + private function index(array &$powers): string + { + return json_encode($powers, JSON_PRETTY_PRINT); + } + + /** + * Get the Power code + * + * @param object $power A power object. + * + * @return string + * @since 3.2.0 + */ + private function code(object &$power): string + { + $code = []; + + // set the name space + $code[] = 'namespace ' . $power->_namespace . ';' . PHP_EOL; + + // check if we have header data + if (StringHelper::check($power->head)) + { + $code[] = PHP_EOL . $power->head; + } + + // add description if set + if (StringHelper::check($power->description)) + { + // check if this is escaped + if (strpos((string) $power->description, '/*') === false) + { + // make this description escaped + $power->description = '/**' . PHP_EOL . ' * ' . implode(PHP_EOL . ' * ', explode(PHP_EOL, (string) $power->description)) . PHP_EOL . ' */'; + } + $code[] = PHP_EOL . $power->description; + } + + // build power declaration + $declaration = $power->type . ' ' . $power->class_name; + + // check if we have extends + if (StringHelper::check($power->extends_name)) + { + $declaration .= ' extends ' . $power->extends_name; + } + + // check if we have implements + if (ArrayHelper::check($power->implement_names)) + { + $declaration .= ' implements ' . implode(', ', $power->implement_names); + } + + $code[] = $declaration; + $code[] = '{'; + + // add the main code if set + if (StringHelper::check($power->main_class_code)) + { + $code[] = $power->main_class_code; + } + + $code[] = '}' . PHP_EOL; + + return $this->placeholder->update(implode(PHP_EOL, $code), $this->content->allActive()); + } + + /** + * Get the Raw (unchanged) Power code + * + * @param object $power A power object. + * + * @return string + * @since 3.2.0 + */ + private function raw(object &$power): string + { + // add the raw main code if set + if (isset($power->unchanged_main_class_code) && StringHelper::check($power->unchanged_main_class_code)) + { + return $power->unchanged_main_class_code; + } + return ''; + } + + /** + * Get the Power Linker + * + * @param object $power A power object. + * + * @return string + * @since 3.2.0 + */ + private function linker(object &$power): string + { + $linker = []; + + // set the linking values + foreach ($power as $key => $value) + { + if (isset($this->linker[$key])) + { + $linker[$this->linker[$key]] = $value; + } + } + + return json_encode($linker, JSON_PRETTY_PRINT); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Injector.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Injector.php new file mode 100644 index 000000000..e650f4b71 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Injector.php @@ -0,0 +1,481 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; + + +/** + * Compiler Power Injector + * @since 3.2.0 + */ +final class Injector +{ + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Powers Extractor + * + * @var Extractor + * @since 3.2.0 + **/ + protected Extractor $extractor; + + /** + * Compiler Powers Parser + * + * @var Parser + * @since 3.2.0 + **/ + protected Parser $parser; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Super Power Update Map + * + * @var array + * @since 3.2.0 + */ + protected array $map = []; + + /** + * Insert Use Statements + * + * @var array + * @since 3.2.0 + */ + protected array $useStatements = []; + + /** + * Insert Trait Statements + * + * @var array + * @since 3.2.0 + */ + protected array $traits = []; + + /** + * Constructor. + * + * @param Power|null $power The power object. + * @param Extractor|null $extractor The powers extractor object. + * @param Parser|null $parser The powers parser object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Extractor $extractor = null, + ?Parser $parser = null, ?Placeholder $placeholder = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->extractor = $extractor ?: Compiler::_('Power.Extractor'); + $this->parser = $parser ?: Compiler::_('Power.Parser'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + } + + /** + * Inject the powers found in the code + * + * @param string $code The class code + * + * @return string The updated code + * @since 3.2.0 + */ + public function power(string $code): string + { + if (($guids = $this->extractor->get($code)) !== null) + { + return $this->update($guids, $code); + } + + return $code; + } + + /** + * Update the code + * + * @param array $guids The Power guids found + * @param string $code The class code + * + * @return string The updated code + * @since 3.2.0 + */ + protected function update(array $guids, string $code): string + { + $use_statements = $this->parser->getUseStatements($code); + $traits = $this->parser->getTraits( + $this->parser->getClassCode($code) ?? '' + ); + + // reset with each file + $this->map = []; + $this->useStatements = []; + $this->traits = []; + + foreach ($guids as $key => $guid) + { + if (($power = $this->power->get($guid)) !== null) + { + if (($name = $this->inspect($power, $use_statements, $traits)) !== null) + { + $this->map[$key] = $name; + } + } + } + + // update + if ($this->map !== []) + { + if ($this->useStatements !== []) + { + $code = $this->addUseStatements($code, $use_statements); + } + + return $this->placeholder->update($code, $this->map); + } + + return $code; + } + + /** + * inspect the super power + * + * @param object|null $power The power object. + * @param array|null $useStatements The code use statments + * @param array|null $traits The code traits use statments + * + * @return string|null The class name (or as name) + * @since 3.2.0 + */ + protected function inspect(object $power, ?array $useStatements, ?array $traits): ?string + { + if (isset($power->type) && in_array($power->type, ['class', 'abstract class', 'final class', 'trait'])) + { + $statement = 'use ' . $power->_namespace . '\\' . $power->class_name; + // other class names + $use_other = []; + $trait_other = []; + // some tracker globals + $has_use_statement = false; // add if not found + $has_trait_statement = !('trait' === $power->type); // don't add if not trait + $name = null; + $trait_name = null; + + // check if the name space is loaded + if ($useStatements !== null) + { + foreach ($useStatements as $use_statement) + { + if ($use_statement === $statement . ';' || strpos($use_statement, $statement . ' as ') !== false) + { + $name = $this->getName($use_statement); + $has_use_statement = true; + } + else + { + $tmp = $this->getName($use_statement); + if ($power->class_name === $tmp) + { + $use_other[$tmp] = $tmp; + } + } + } + } + + // check if the trait is loaded + if (!$has_trait_statement && $traits !== null) + { + $trait_statement = $name ?? $power->class_name; + + foreach ($traits as $trait) + { + if ($trait === $trait_statement) + { + $trait_name = $trait; + $has_trait_statement = true; + } + } + } + + // build the name + $name = $trait_name ?? $name ?? $power->class_name; + + // if we have a trait we may need to add use and trait + if ('trait' === $power->type) + { + if (!$has_trait_statement) + { + $this->traits[$name] = 'use ' . $name . ';'; + } + } + + // check if we need to update the name + if ($use_other !== []) + { + // set search namespace + $namespace = ($name !== $power->class_name) ? $power->_namespace . '\\' . $power->class_name : $power->_namespace; + + // get the unique name + $name = $this->getUniqueName($name, $namespace, $use_other); + } + + if (!$has_use_statement) + { + // if the name is not the same as class name + if ($name !== $power->class_name) + { + $statement .= ' as ' . $name . ';'; + } + else + { + $statement .= ';'; + } + + $this->useStatements[$name] = $statement; + } + + return $name; + } + + return null; + } + + /** + * Extracts the class name from a use statement. + * + * @param string $useStatement The use statement from which to extract the class name + * + * @return string|null The class name or null if not found + * @since 3.2.0 + */ + protected function getName(string $useStatement): ?string + { + // If the input doesn't start with 'use ', assume it's a class name without a use statement + if (strpos($useStatement, 'use ') !== 0) + { + $parts = explode('\\', $useStatement); + $result = end($parts); + + // Remove '\\' from the beginning and end of the resulting string + $result = trim($result, '\\'); + + // If the resulting string is empty, return null + return empty($result) ? null : $result; + } + + $pattern = '/use\s+([\w\\\\]+)(?:\s+as\s+)?([\w]+)?;/'; + + if (preg_match($pattern, $useStatement, $matches)) + { + // If there's an alias, return it + if (!empty($matches[2])) + { + return $matches[2]; + } + + // If there's no alias, extract the class name from the namespace + $parts = explode('\\', $matches[1]); + return end($parts); + } + + return null; + } + + /** + * Removes the last space from the namespace. + * + * @param string $name The current name + * @param string $namespace The namespace + * @param array $useOther The other use names + * + * @return string The namespace shortened + * @since 3.2.0 + */ + protected function getUniqueName(string $name, string $namespace, array $useOther): string + { + // if the name is already used + while (isset($useOther[$name])) + { + if (($tmp = $this->getName($namespace)) !== null) + { + $name = ucfirst($tmp) . $name; + $namespace = $this->removeLastSpace($namespace); + } + } + + return $name; + } + + /** + * Removes the last space from the namespace. + * + * @param string $namespace The namespace + * + * @return string The namespace shortened + * @since 3.2.0 + */ + protected function removeLastSpace(string $namespace): string + { + // Remove '\\' from the beginning and end of the resulting string + $namespace = trim($namespace, '\\'); + + $parts = explode('\\', $namespace); + + // Remove the last part (the class name) + array_pop($parts); + + // Reassemble the namespace without the class name + return implode('\\', $parts); + } + + /** + * Insert a line before the class declaration in the given class code. + * + * @param string $code The class code + * @param array|null $useStatements The existing use statements + * + * @return string The modified file content + * @since 3.2.0 + */ + protected function addUseStatements(string $code, ?array $useStatements): string + { + if ($useStatements !== null) + { + // we add the use statements using existing use statements + $key = end($useStatements); + + array_unshift($this->useStatements, $key); + + return $this->placeholder->update($code, [$key => implode(PHP_EOL, array_values($this->useStatements))]); + } + + return $this->addLines($code, implode(PHP_EOL, array_values($this->useStatements))); + } + + /** + * Insert a line before the class declaration in the given class code. + * + * @param string $code The class code + * @param string $lines The new lines to insert + * + * @return string The modified file content + * @since 3.2.0 + */ + protected function addLines(string $code, string $lines): string + { + // Pattern to match class, final class, abstract class, interface, and trait + $pattern = '/(?:class|final class|abstract class|interface|trait)\s+[a-zA-Z0-9_]+\s*(?:extends\s+[a-zA-Z0-9_]+\s*)?(?:implements\s+[a-zA-Z0-9_]+(?:\s*,\s*[a-zA-Z0-9_]+)*)?\s*\{/s'; + + // Find the position of the class declaration + preg_match($pattern, $code, $matches, PREG_OFFSET_CAPTURE); + $class_declaration_pos = $matches[0][1] ?? null; + + if (null !== $class_declaration_pos) + { + // Find the position of the last newline character before the class declaration + $last_newline_pos = strrpos($code, PHP_EOL, -(strlen($code) - $class_declaration_pos)); + + // Find the position of the comment block right before the class declaration + $comment_pattern = '/\s*\*\/\s*$/m'; + $insert_pos = null; + if (preg_match($comment_pattern, $code, $comment_matches, PREG_OFFSET_CAPTURE, 0, $last_newline_pos)) + { + $insert_pos = (int) $comment_matches[0][1] + strlen($comment_matches[0][0]); + } + else + { + // Find the last empty line before the class declaration + $empty_line_pattern = '/(^|\r\n|\r|\n)[\s]*($|\r\n|\r|\n)/'; + if (preg_match($empty_line_pattern, $code, $empty_line_matches, PREG_OFFSET_CAPTURE, 0, $last_newline_pos)) + { + $insert_pos = (int) $empty_line_matches[0][1] + strlen($empty_line_matches[0][0]); + } + } + + // Insert the new line at the found position + if (null !== $insert_pos) + { + return substr_replace($code, $lines . PHP_EOL, $insert_pos, 0); + } + } + + // last try targeting the defined line + return $this->addLinesAfterDefinedLine($code, $lines); + } + + /** + * Inserts a new line after the defined('_JEXEC') line. + * + * @param string $code The class code + * @param string $lines The new lines to insert + * + * @return string The modified file content + * @since 3.2.0 + */ + protected function addLinesAfterDefinedLine(string $code, string $lines): string + { + // Patterns to match the defined('_JEXEC') and defined('JPATH_BASE') lines + $patterns = [ + "/defined\('_JEXEC'\)(.*?)\s*;/", + "/defined\('JPATH_BASE'\)(.*?)\s*;/", + ]; + + $insert_pos = null; + + // Iterate through the patterns and try to find a match + foreach ($patterns as $pattern) + { + preg_match($pattern, $code, $matches, PREG_OFFSET_CAPTURE); + $defined_line_pos = $matches[0][1] ?? null; + + if ($defined_line_pos !== null) + { + // Find the position of the newline character after the defined() line + $next_lines_pos = strpos($code, PHP_EOL, (int) $defined_line_pos + strlen($matches[0][0])); + + // Insert the new line at the found position + if ($next_lines_pos !== false) + { + $insert_pos = $next_lines_pos; + break; + } + } + } + + // Insert the new line at the found position + if ($insert_pos !== null) + { + $code = substr_replace($code, PHP_EOL . $lines, $insert_pos, 0); + } + + return $code; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Parser.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Parser.php new file mode 100644 index 000000000..ac911e4a8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Parser.php @@ -0,0 +1,644 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +/** + * Compiler Power Parser + * Very basic php class methods parser, does not catch all edge-cases! + * Use this only on code that are following standard good practices + * Suggested improvements are welcome + * @since 3.2.0 + */ +final class Parser +{ + /** + * Get properties and method declarations and other details from the given code. + * + * @param string $code The code containing class properties & methods + * + * @return array An array of properties & method declarations of the given code + * @since 3.2.0 + */ + public function code(string $code): array + { + return [ + 'properties' => $this->properties($code), + 'methods' => $this->methods($code) + ]; + } + + /** + * Get the class body + * + * @param string $code The class as a string + * + * @return string|null The class body, or null if not found + * @since 3.2.0 + **/ + public function getClassCode(string $code): ?string + { + // Match class, final class, abstract class, interface, and trait + $pattern = '/(?:class|final class|abstract class|interface|trait)\s+[a-zA-Z0-9_]+\s*(?:extends\s+[a-zA-Z0-9_]+\s*)?(?:implements\s+[a-zA-Z0-9_]+(?:\s*,\s*[a-zA-Z0-9_]+)*)?\s*\{/s'; + + // Split the input code based on the class declaration pattern + $parts = preg_split($pattern, $code, 2, PREG_SPLIT_DELIM_CAPTURE); + $body = $parts[1] ?? ''; + + if ($body !== '') + { + // Remove leading and trailing white space + $body = trim($body); + + // Remove the first opening curly brace if it exists + if (mb_substr($body, 0, 1) === '{') + { + $body = mb_substr($body, 1); + } + + // Remove the last closing curly brace if it exists + if (mb_substr($body, -1) === '}') + { + $body = mb_substr($body, 0, -1); + } + + return $body; + } + + // No class body found, return null + return null; + } + + /** + * Get the class license + * + * @param string $code The class as a string + * + * @return string|null The class license, or null if not found + * @since 3.2.0 + **/ + public function getClassLicense(string $code): ?string + { + // Check if the file starts with ' $match) + { + $declaration = $match[0] ?? null; + + if ($declaration !== null) + { + $names = preg_replace('/\s*use\s+/', '', $declaration); + $names = preg_replace('/\s*;/', '', $names); + $names = preg_split('/\s*,\s*/', $names); + + $traitNames = array_merge($traitNames, $names); + } + } + + return $traitNames; + } + + return null; + } + + /** + * Extracts properties declarations and other details from the given code. + * + * @param string $code The code containing class properties + * + * @return array|null An array of properties declarations and details + * @since 3.2.0 + */ + private function properties(string $code): ?array + { + // regex to target all properties + $access = '(?var|public|protected|private)'; + $type = '(?(?:\?|)[\p{L}0-9\\\\]*\s+)?'; + $static = '(?static)?'; + $name = '\$(?\p{L}[\p{L}0-9]*)'; + $default = '(?:\s*=\s*(?\[[^\]]*\]|\d+|\'[^\']*?\'|"[^"]*?"|false|true|null))?'; + $property_pattern = "/\b{$access}\s*{$type}{$static}\s*{$name}{$default};/u"; + + preg_match_all($property_pattern, $code, $matches, PREG_SET_ORDER); + + if ($matches != []) + { + $properties = []; + foreach ($matches as $n => $match) + { + $declaration = $match[0] ?? null; + + if (is_string($declaration)) + { + $comment = $this->extractDocBlock($code, $declaration); + $declaration = trim(preg_replace('/\s{2,}/', ' ', + preg_replace('/[\r\n]+/', ' ', $declaration))); + + $properties[] = [ + 'name' => isset($match['name']) ? '$' . $match['name'] : 'error', + 'access' => $match['access'] ?? 'public', + 'type' => isset($match['type']) ? trim($match['type']) : null, + 'static' => (bool) $match['static'] ?? false, + 'default' => $match['default'] ?? null, + 'comment' => $comment, + 'declaration' => $declaration + ]; + } + } + + return $properties; + } + + return null; + } + + /** + * Extracts method declarations and other details from the given code. + * + * @param string $code The code containing class methods + * + * @return array|null An array of method declarations and details + * @since 3.2.0 + */ + private function methods(string $code): ?array + { + // regex to target all methods/functions + $final_modifier = '(?Pfinal)?\s*'; + $abstract_modifier = '(?Pabstract)?\s*'; + $access_modifier = '(?Ppublic|protected|private)?\s*'; + $static_modifier = '(?Pstatic)?\s*'; + $modifier = "{$final_modifier}{$abstract_modifier}{$access_modifier}{$static_modifier}"; + $name = '(?P\w+)'; + $arguments = '(?P\(.*?\))?'; + $return_type = '(?P\s*:\s*(?:\?[\w\\\\]+|\\\\?[\w\\\\]+(?:\|\s*(?:\?[\w\\\\]+|\\\\?[\w\\\\]+))*)?)?'; + $method_pattern = "/(^\s*?\b{$modifier}function\s+{$name}{$arguments}{$return_type})/sm"; + + preg_match_all($method_pattern, $code, $matches, PREG_SET_ORDER); + + if ($matches != []) + { + $methods = []; + foreach ($matches as $n => $match) + { + $full_declaration = $match[0] ?? null; + + if (is_string($full_declaration)) + { + $comment = $this->extractDocBlock($code, $full_declaration); + + $full_declaration = trim(preg_replace('/\s{2,}/', ' ', + preg_replace('/[\r\n]+/', ' ', $full_declaration))); + + // extract method's body + $start_pos = strpos($code, $full_declaration) + strlen($full_declaration); + $method_body = $this->extractMethodBody($code, $start_pos); + + // now load what we found + $methods[] = [ + 'name' => $match['name'] ?? 'error', + 'access' => $match['access_modifier'] ?? 'public', + 'static' => (bool) $match['static_modifier'] ?? false, + 'final' => (bool) $match['final_modifier'] ?? false, + 'abstract' => (bool) $match['abstract_modifier'] ?? false, + 'return_type' => $this->extractReturnType($match['return_type'] ?? null, $comment), + 'since' => $this->extractSinceVersion($comment), + 'deprecated' => $this->extractDeprecatedVersion($comment), + 'arguments' => $this->extractFunctionArgumentDetails($comment, $match['arguments'] ?? null), + 'comment' => $comment, + 'declaration' => str_replace(["\r\n", "\r", "\n"], '', $full_declaration), + 'body' => $method_body + ]; + } + } + + return $methods; + } + + return null; + } + + /** + * Extracts the PHPDoc block for a given function declaration. + * + * @param string $code The source code containing the function + * @param string $declaration The part of the function declaration + * + * @return string|null The PHPDoc block, or null if not found + * @since 3.2.0 + */ + private function extractDocBlock(string $code, string $declaration): ?string + { + // Split the code string with the function declaration + $parts = explode($declaration, $code); + if (count($parts) < 2) + { + // Function declaration not found in the code + return null; + } + + // Get the part with the comment (if any) + $comment = $parts[0]; + + // Split the last part using the comment block start marker + $commentParts = preg_split('/(})?\s+(?=\s*\/\*)(\*)?/', $comment); + + // Get the last comment block + $lastCommentPart = end($commentParts); + + // Search for the comment block in the last comment part + if (preg_match('/(\/\*\*[\s\S]*?\*\/)\s*$/u', $lastCommentPart, $matches)) + { + $comment = $matches[1] ?? null; + // check if we actually have a comment + if ($comment) + { + return $this->removeWhiteSpaceFromComment($comment); + } + } + + return null; + } + + /** + * Extracts method body based on starting position of method declaration. + * + * @param string $code The class code + * @param string $startPos The starting position of method declaration + * + * @return string|null Method body or null if not found + * @since 3.2.0 + */ + private function extractMethodBody(string $code, int $startPos): ?string + { + $braces_count = 0; + $in_method = false; + $method_body = ""; + + for ($i = $startPos; $i < strlen($code); $i++) { + if ($code[$i] === '{') + { + $braces_count++; + if (!$in_method) + { + $in_method = true; + continue; + } + } + + if ($code[$i] === '}') + { + $braces_count--; + } + + if ($in_method) + { + $method_body .= $code[$i]; + } + + if ($braces_count <= 0 && $in_method) + { + // remove the closing brace + $method_body = substr($method_body, 0, -1); + break; + } + } + + return $in_method ? $method_body : null; + } + + /** + * Extracts the function argument details. + * + * @param string|null $comment The function comment if found + * @param string|null $arguments The arguments found on function declaration + * + * @return array|null The function argument details + * @since 3.2.0 + */ + private function extractFunctionArgumentDetails(?string $comment, ?string $arguments): ?array + { + $arg_types_from_declaration = $this->extractArgTypesArguments($arguments); + $arg_types_from_comments = null; + + if ($comment) + { + $arg_types_from_comments = $this->extractArgTypesFromComment($comment); + } + + // merge the types + if ($arg_types_from_declaration) + { + return $this->mergeArgumentTypes($arg_types_from_declaration, $arg_types_from_comments); + } + + return null; + } + + /** + * Extracts the function return type. + * + * @param string|null $returnType The return type found in declaration + * @param string|null $comment The function comment if found + * + * @return string|null The function return type + * @since 3.2.0 + */ + private function extractReturnType(?string $returnType, ?string $comment): ?string + { + if ($returnType === null && $comment) + { + return $this->extractReturnTypeFromComment($comment); + } + + return trim(trim($returnType, ':')); + } + + /** + * Extracts argument types from a given comment. + * + * @param string $comment The comment containing the argument types + * + * @return array|null An array of argument types + * @since 3.2.0 + */ + private function extractArgTypesFromComment(string $comment): ?array + { + preg_match_all('/@param\s+((?:[^\s|]+(?:\|)?)+)?\s+\$([^\s]+)/', $comment, $matches, PREG_SET_ORDER); + + if ($matches !== []) + { + $arg_types = []; + + foreach ($matches as $match) + { + $arg = $match[2] ?? null; + $type = $match[1] ?: null; + if (is_string($arg)) + { + $arg_types['$' .$arg] = $type; + } + } + + return $arg_types; + } + + return null; + } + + /** + * Extracts argument types from a given declaration. + * + * @param string|null $arguments The arguments found on function declaration + * + * @return array|null An array of argument types + * @since 3.2.0 + */ + private function extractArgTypesArguments(?string $arguments): ?array + { + if ($arguments) + { + $args = preg_split('/,(?![^()\[\]]*(\)|\]))/', trim($arguments, '()')); + if ($args !== []) + { + $argument_types = []; + foreach ($args as $arg) + { + $eqPos = strpos($arg, '='); + + if ($eqPos !== false) + { + $arg_parts = [ + substr($arg, 0, $eqPos), + substr($arg, $eqPos + 1) + ]; + } + else + { + $arg_parts = [$arg]; + } + + if (preg_match('/(?:(\??(?:\w+|\\\\[\w\\\\]+)(?:\|\s*\??(?:\w+|\\\\[\w\\\\]+))*)\s+)?\$(\w+)/', $arg_parts[0], $arg_matches)) + { + $type = $arg_matches[1] ?: null; + $name = $arg_matches[2] ?: null; + $default = isset($arg_parts[1]) ? preg_replace('/\s{2,}/', ' ', + preg_replace('/[\r\n]+/', ' ', trim($arg_parts[1]))) : null; + + if (is_string($name)) + { + $argument_types['$' . $name] = [ + 'type' => $type, + 'default' => $default, + ]; + } + } + } + + return $argument_types; + } + } + + return null; + } + + /** + * Extracts return type from a given declaration. + * + * @param string $comment The comment containing the return type + * + * @return string|null The return type + * @since 3.2.0 + */ + private function extractReturnTypeFromComment(string $comment): ?string + { + if (preg_match('/@return\s+((?:[^\s|]+(?:\|)?)+)/', $comment, $matches)) + { + return $matches[1] ?: null; + } + + return null; + } + + /** + * Extracts the version number from the @since tag in the given comment. + * + * @param string|null $comment The comment containing the @since tag and version number + * + * @return string|null The extracted version number or null if not found + * @since 3.2.0 + */ + private function extractSinceVersion(?string $comment): ?string + { + if (is_string($comment) && preg_match('/@since\s+(v?\d+(?:\.\d+)*(?:-(?:alpha|beta|rc)\d*)?)/', $comment, $matches)) + { + return $matches[1] ?: null; + } + + return null; + } + + /** + * Extracts the version number from the deprecated tag in the given comment. + * + * @param string|null $comment The comment containing the deprecated tag and version number + * + * @return string|null The extracted version number or null if not found + * @since 3.2.0 + */ + private function extractDeprecatedVersion(?string $comment): ?string + { + if (is_string($comment) && preg_match('/@deprecated\s+(v?\d+(?:\.\d+)*(?:-(?:alpha|beta|rc)\d*)?)/', $comment, $matches)) + { + return $matches[1] ?: null; + } + + return null; + } + + /** + * Remove all white space from each line of the comment + * + * @param string $comment The function declaration containing the return type + * + * @return string The return comment + * @since 3.2.0 + */ + private function removeWhiteSpaceFromComment(string $comment): string + { + // Remove comment markers and leading/trailing whitespace + $comment = preg_replace('/^\/\*\*[\r\n\s]*|[\r\n\s]*\*\/$/m', '', $comment); + $comment = preg_replace('/^[\s]*\*[\s]?/m', '', $comment); + + // Split the comment into lines + $lines = preg_split('/\r\n|\r|\n/', $comment); + + // Remove white spaces from each line + $trimmedLines = array_map('trim', $lines); + + // Join the lines back together + return implode("\n", array_filter($trimmedLines)); + } + + /** + * Merges the types from the comments and the arguments. + * + * @param array $argTypesFromDeclaration An array of argument types and default values from the declaration + * @param array|null $argTypesFromComments An array of argument types from the comments + * + * @return array A merged array of argument information + * @since 3.2.0 + */ + private function mergeArgumentTypes(array $argTypesFromDeclaration, ?array $argTypesFromComments): array + { + $mergedArguments = []; + + foreach ($argTypesFromDeclaration as $name => $declarationInfo) + { + $mergedArguments[$name] = [ + 'name' => $name, + 'type' => $declarationInfo['type'] ?: $argTypesFromComments[$name] ?? null, + 'default' => $declarationInfo['default'] ?: null, + ]; + } + + return $mergedArguments; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Plantuml.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Plantuml.php new file mode 100644 index 000000000..dc4c2abc2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Plantuml.php @@ -0,0 +1,459 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +/** + * Compiler Power Plantuml Builder + * @since 3.2.0 + */ +class Plantuml +{ + /** + * Get a namespace diagram of a group of class + * + * @param string $namespace the namespace name + * @param string $classes the ready build class uml + * + * @return string + * @since 3.2.0 + */ + public function namespaceDiagram(string $namespace, string $classes): string + { + $namespace_depth = substr_count($namespace, '\\'); + $namespace_color = $this->getNamespaceColor($namespace_depth); + + // Set the scale of the diagram + // $plant_uml = "scale 0.8\n\n"; + + // Add namespace + $plant_uml = "namespace $namespace #$namespace_color {\n\n"; + + // Add class + $plant_uml .= $classes; + + $plant_uml .= "}\n"; + + return $plant_uml; + } + + /** + * Get a class basic diagram of a class + * + * @param array $power the class being built + * @param array $code the class code being built + * + * @return string + * @since 3.2.0 + */ + public function classBasicDiagram(array $power, array $code): string + { + // Set some global values + $class_name = $power['name']; + $class_type = $power['type']; + + // set the class color + $class_color = $this->getClassColor($class_type); + + // set the class type label + $type_label = $this->getClassTypeLable($class_type); + + // set the class type tag + $type_tag = $this->getClassTypeTag($class_type); + + // Add class + $plant_uml = "\n $type_label $class_name $type_tag #$class_color {\n"; + + // Add properties + if (isset($code['properties']) && is_array($code['properties'])) + { + $plant_uml .= $this->generatePropertiesPlantUML($code['properties'], ' '); + } + + // Add methods + if (isset($code['methods']) && is_array($code['methods'])) + { + $plant_uml .= $this->generateBasicMethodsPlantUML($code['methods']); + } + + $plant_uml .= " }\n"; + + return $plant_uml; + } + + /** + * Get a class detailed diagram of a class + * + * @param array $power the class being built + * @param array $code the class code being built + * + * @return string + * @since 3.2.0 + */ + public function classDetailedDiagram(array $power, array $code): string + { + // Set some global values + $class_name = $power['name']; + $class_type = $power['type']; + + // set the class color + $class_color = $this->getClassColor($class_type); + + // set the class type label + $type_label = $this->getClassTypeLable($class_type); + + // set the class type tag + $type_tag = $this->getClassTypeTag($class_type); + + // Add class + $plant_uml = "\n$type_label $class_name $type_tag #$class_color {\n"; + + // Add properties + if (isset($code['properties']) && is_array($code['properties'])) + { + $plant_uml .= $this->generatePropertiesPlantUML($code['properties'], ' '); + } + + // Add methods + if (isset($code['methods']) && is_array($code['methods'])) + { + list($methods_plant_uml, $notes) = $this->generateDetailedMethodsPlantUML($code['methods'], $class_name); + $plant_uml .= $methods_plant_uml; + } + + $plant_uml .= "}\n"; + + if (!empty($notes)) + { + $plant_uml .= $this->generateNotesPlantUML($notes); + } + + return $plant_uml; + } + + /** + * Generate properties PlantUML + * + * @param array $properties + * @param string $space + * + * @return string + * @since 3.2.0 + */ + private function generatePropertiesPlantUML(array $properties, string $space): string + { + $plant_uml = ""; + + foreach ($properties as $property) + { + $access_sign = $this->getAccessSign($property['access']); + $static = $property['static'] ? '{static} ' : ''; + $type = $property['type'] ? $property['type'] . ' ' : ''; + $plant_uml .= "{$space}$access_sign $static{$type}{$property['name']}\n"; + } + + return $plant_uml; + } + + /** + * Generate detailed methods PlantUML + * + * @param array $methods + * @param string $class_name + * + * @return array + * @since 3.2.0 + */ + private function generateDetailedMethodsPlantUML(array $methods, string $class_name): array + { + $plant_uml = ""; + $notes = []; + + foreach ($methods as $method) + { + $notes = $this->generateMethodNotes($method, $class_name, $notes); + + $access_sign = $this->getAccessSign($method['access']); + + $arguments = ''; + if ($method['arguments']) + { + $arguments = $this->generateMethodArgumentsAndNotes( + $method['arguments'], $class_name, $method['name'], $notes); + + $arguments = implode(', ', $arguments); + } + + $static = $method['static'] ? '{static} ' : ''; + $abstract = $method['abstract'] ? '{abstract} ' : ''; + $return_type = $method['return_type'] ? " : {$method['return_type']}" : ''; + + $plant_uml .= " $access_sign {$abstract}$static{$method['name']}({$arguments})$return_type\n"; + } + + return [$plant_uml, $notes]; + } + + /** + * Generate basic methods PlantUML + * + * @param array $properties + * + * @return string + * @since 3.2.0 + */ + private function generateBasicMethodsPlantUML(array $methods): string + { + $plant_uml = ""; + + foreach ($methods as $method) + { + $access_sign = $this->getAccessSign($method['access']); + $static = $method['static'] ? '{static} ' : ''; + $abstract = $method['abstract'] ? '{abstract} ' : ''; + $return_type = $method['return_type'] ? " : {$method['return_type']}" : ''; + $plant_uml .= " $access_sign {$abstract}$static{$method['name']}()$return_type\n"; + } + + return $plant_uml; + } + + /** + * Generate method arguments and notes + * + * @param array $arguments + * @param string $class_name + * @param string $method_name + * @param array $notes + * + * @return array + * @since 3.2.0 + */ + private function generateMethodArgumentsAndNotes(array $arguments, string $class_name, + string $method_name, array &$notes): array + { + $formatted_arguments = []; + $notes_bucket = []; + $limit = 2; + + foreach ($arguments as $name => $arg) + { + $arg_type = $arg['type'] ? "{$arg['type']} " : ''; + $arg_default = $arg['default'] ? " = {$arg['default']}" : ''; + $arg_statment = "{$arg_type}$name{$arg_default}"; + + if ($limit == 0) + { + $formatted_arguments[] = "..."; + $limit = -1; + } + elseif ($limit > 0) + { + $formatted_arguments[] = $arg_statment; + $limit--; + } + + $notes_bucket[] = $arg_statment; + } + + if ($limit == -1) + { + $notes["{$class_name}::{$method_name}"][] = "\n arguments:\n " . implode("\n ", $notes_bucket); + } + + return $formatted_arguments; + } + + /** + * Generate method notes + * + * @param array $method + * @param string $class_name + * @param array $notes + * + * @return array + */ + private function generateMethodNotes(array $method, string $class_name, array &$notes): array + { + $notes_key = "{$class_name}::{$method['name']}"; + + if (is_string($method['comment']) && strlen($method['comment']) > 4) + { + $notes[$notes_key][] = trim(preg_replace("/^@.*[\r\n]*/m", '', $method['comment'])) . "\n"; + } + + if (is_string($method['since']) && strlen($method['since']) > 3) + { + $notes[$notes_key][] = "since: {$method['since']}"; + } + + if (is_string($method['return_type']) && strlen($method['return_type']) > 1) + { + $notes[$notes_key][] = "return: {$method['return_type']}"; + } + + if (is_string($method['deprecated']) && strlen($method['deprecated']) > 3) + { + $notes[$notes_key][] = "deprecated: {$method['deprecated']}"; + } + + return $notes; + } + + /** + * Generate notes PlantUML + * + * @param array $notes + * + * @return string + * @since 3.2.0 + */ + private function generateNotesPlantUML(array $notes): string + { + $plant_uml = ""; + $note_count = count($notes); + + $positions = ['right', 'left']; + $position_index = 0; + + foreach ($notes as $area => $note) + { + if ($note_count <= 7) + { + $position = 'right'; + } + else + { + $position = $positions[$position_index % 2]; + $position_index++; + } + + $plant_uml .= "\nnote $position of {$area}\n"; + $plant_uml .= " " . implode("\n ", $note) . "\n"; + $plant_uml .= "end note\n"; + } + + return $plant_uml; + } + + /** + * Get the access sign based on the access level. + * + * @param string $access The access level. + * + * @return string The corresponding access sign. + * @since 3.2.0 + */ + private function getAccessSign(string $access): string + { + switch ($access) + { + case 'private': + return '-'; + case 'protected': + return '#'; + case 'public': + return '+'; + case 'var': + return '+'; + default: + return ''; + } + } + + /** + * Get the correct class type. + * + * @param string $type The class type. + * + * @return string The correct class type label. + * @since 3.2.0 + */ + private function getClassTypeLable(string $type): string + { + $class_type_updater = [ + 'final class' => 'class', + 'abstract class' => 'abstract', + 'trait' => 'class' + ]; + + return $class_type_updater[$type] ?? $type; + } + + /** + * Get the extra class type tag. + * + * @param string $type The class type. + * + * @return string The correct class type label. + * @since 3.2.0 + */ + private function getClassTypeTag(string $type): string + { + $class_type_updater = [ + 'final class' => '<< (F,LightGreen) >>', + 'trait' => '<< (T,Orange) >>' + ]; + + return $class_type_updater[$type] ?? ''; + } + + /** + * Get class color based on class type. + * + * @param string $classType The class type. + * + * @return string The corresponding color. + * @since 3.2.0 + */ + private function getClassColor(string $classType): string + { + $class_colors = [ + 'class' => 'Gold', + 'final class' => 'RoyalBlue', + 'abstract class' => 'Orange', + 'interface' => 'Lavender', + 'trait' => 'Turquoise' + ]; + + return $class_colors[$classType] ?? 'Green'; + } + + /** + * Get namespace color based on namespace depth. + * + * @param int $namespaceDepth The depth of the namespace. + * + * @return string The corresponding color. + * @since 3.2.0 + */ + private function getNamespaceColor(int $namespaceDepth): string + { + $namespace_colors = [ + 'lightgrey', + 'Azure', + 'DarkCyan', + 'Olive', + 'LightGreen', + 'DeepSkyBlue', + 'Wheat', + 'Coral', + 'Beige', + 'DeepPink', + 'DeepSkyBlue' + ]; + + return $namespace_colors[$namespaceDepth % count($namespace_colors)] ?? 'lightgrey'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/Readme.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/Readme.php new file mode 100644 index 000000000..2da808e0a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/Readme.php @@ -0,0 +1,107 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power\Repo; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Power\Plantuml; + + +/** + * Compiler Power Repo Readme + * @since 3.2.0 + */ +class Readme +{ + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Powers Plantuml Builder + * + * @var Plantuml + * @since 3.2.0 + **/ + protected Plantuml $plantuml; + + /** + * Constructor. + * + * @param Power|null $power The power object. + * @param Plantuml|null $plantuml The powers plantuml builder object. + * + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Plantuml $plantuml = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->plantuml = $plantuml ?: Compiler::_('Power.Plantuml'); + } + + /** + * Get a Power Readme + * + * @param object $power A power details. + * + * @return string + * @since 3.2.0 + */ + public function get(object $power): string + { + // build readme + $readme = ["``` +██████╗ ██████╗ ██╗ ██╗███████╗██████╗ +██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗ +██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝ +██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗ +██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║ +╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝ +```"]; + // add the class diagram + $parsed_class_code = []; + if (isset($power->parsed_class_code) && is_array($power->parsed_class_code)) + { + $parsed_class_code = $power->parsed_class_code; + } + + $readme[] = "# " . $power->type . " " . $power->code_name . " (Details)"; + $readme[] = "> namespace: **" . $power->_namespace . "**"; + if ($power->extends != 0) + { + $readme[] = "> extends: **" . $power->extends_name . "**"; + } + $readme[] = "```uml\n@startuml" . $this->plantuml->classDetailedDiagram( + ['name' => $power->code_name, 'type' => $power->type], + $parsed_class_code + ) . " \n@enduml\n```"; + + // yes you can remove this, but why? + $readme[] = "\n---\n``` + ██╗ ██████╗██████╗ + ██║██╔════╝██╔══██╗ + ██║██║ ██████╔╝ +██ ██║██║ ██╔══██╗ +╚█████╔╝╚██████╗██████╔╝ + ╚════╝ ╚═════╝╚═════╝ +```\n> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)\n\n"; + + return implode("\n", $readme); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/Readme.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/Readme.php new file mode 100644 index 000000000..17446d68a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/Readme.php @@ -0,0 +1,353 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power\Repos; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Power\Plantuml; + + +/** + * Compiler Power Repos Readme + * @since 3.2.0 + */ +class Readme +{ + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Powers Plantuml Builder + * + * @var Plantuml + * @since 3.2.0 + **/ + protected Plantuml $plantuml; + + /** + * Constructor. + * + * @param Power|null $power The power object. + * @param Plantuml|null $plantuml The powers plantuml builder object. + * + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Plantuml $plantuml = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->plantuml = $plantuml ?: Compiler::_('Power.Plantuml'); + } + + /** + * Get Super Power Readme + * + * @param array $powers All powers of this super power. + * + * @return string + * @since 3.2.0 + */ + public function get(array $powers): string + { + // build readme + $readme = ["``` +███████╗██╗ ██╗██████╗ ███████╗██████╗ +██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗ +███████╗██║ ██║██████╔╝█████╗ ██████╔╝ +╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗ +███████║╚██████╔╝██║ ███████╗██║ ██║ +╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ +██████╗ ██████╗ ██╗ ██╗███████╗██████╗ ███████╗ +██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗██╔════╝ +██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝███████╗ +██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗╚════██║ +██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║███████║ +╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝╚══════╝ +```"]; + + // default description of super powers + $readme[] = "\n### What is JCB Super Powers?\nThe Joomla Component Builder (JCB) Super Power features are designed to enhance JCB's functionality and streamline the development process. These Super Powers enable developers to efficiently manage and share their custom powers across multiple JCB instances through repositories hosted on [https://git.vdm.dev/[username]/[repository-name]](https://git.vdm.dev). JCB Super Powers are managed using a combination of layers, events, tasks, methods, switches, and algorithms, which work together to provide powerful customization and extensibility options. More details on JCB Super Powers can be found in the [Super Powers Documentation](https://git.vdm.dev/joomla/super-powers/wiki).\n\nIn summary, JCB Super Powers offer a flexible and efficient way to manage and share functionalities between JCB instances. By utilizing a sophisticated system of layers, events, tasks, methods, switches, and algorithms, developers can seamlessly integrate JCB core powers and their custom powers. For more information on how to work with JCB Super Powers, refer to the [Super Powers User Guide](https://git.vdm.dev/joomla/super-powers/wiki).\n\n### What can I find here?\nThis repository contains an index (see below) of all the approved powers within the JCB GUI. During the compilation of a component, these powers are automatically added to the repository, ensuring a well-organized and accessible collection of functionalities.\n"; + + // get the readme body + $readme[] = $this->readmeBuilder($powers); + + // yes you can remove this, but why? + $readme[] = "\n---\n``` + ██╗ ██████╗ ██████╗ ███╗ ███╗██╗ █████╗ + ██║██╔═══██╗██╔═══██╗████╗ ████║██║ ██╔══██╗ + ██║██║ ██║██║ ██║██╔████╔██║██║ ███████║ +██ ██║██║ ██║██║ ██║██║╚██╔╝██║██║ ██╔══██║ +╚█████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║███████╗██║ ██║ + ╚════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ + ██████╗ ██████╗ ███╗ ███╗██████╗ ██████╗ ███╗ ██╗███████╗███╗ ██╗████████╗ +██╔════╝██╔═══██╗████╗ ████║██╔══██╗██╔═══██╗████╗ ██║██╔════╝████╗ ██║╚══██╔══╝ +██║ ██║ ██║██╔████╔██║██████╔╝██║ ██║██╔██╗ ██║█████╗ ██╔██╗ ██║ ██║ +██║ ██║ ██║██║╚██╔╝██║██╔═══╝ ██║ ██║██║╚██╗██║██╔══╝ ██║╚██╗██║ ██║ +╚██████╗╚██████╔╝██║ ╚═╝ ██║██║ ╚██████╔╝██║ ╚████║███████╗██║ ╚████║ ██║ + ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═══╝ ╚═╝ +██████╗ ██╗ ██╗██╗██╗ ██████╗ ███████╗██████╗ +██╔══██╗██║ ██║██║██║ ██╔══██╗██╔════╝██╔══██╗ +██████╔╝██║ ██║██║██║ ██║ ██║█████╗ ██████╔╝ +██╔══██╗██║ ██║██║██║ ██║ ██║██╔══╝ ██╔══██╗ +██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║ +╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝ +```\n> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)\n\n"; + + return implode("\n", $readme); + } + + /** + * The readme builder + * + * @param array $classes The powers. + * + * @return string + * @since 3.2.0 + */ + private function readmeBuilder(array &$powers): string + { + $classes = []; + foreach ($powers as $guid => $power) + { + // add to the sort bucket + $classes[] = [ + 'namespace' => $power['namespace'], + 'type' => $power['type'], + 'name' => $power['name'], + 'link' => $this->indexLinkPower($power) + ]; + } + + return $this->readmeModel($classes); + } + + /** + * Sort and model the readme classes + * + * @param array $classes The powers. + * + * @return string + * @since 3.2.0 + */ + private function readmeModel(array &$classes): string + { + $this->sortClasses($classes, $this->defineTypeOrder()); + + return $this->generateIndex($classes); + } + + /** + * Generate the index string for classes + * + * @param array $classes The sorted classes + * + * @return string The index string + */ + private function generateIndex(array &$classes): string + { + $result = "# Index of powers\n"; + $current_namespace = null; + + foreach ($classes as $class) + { + if ($class['namespace'] !== $current_namespace) + { + $current_namespace = $class['namespace']; + $result .= "\n- **Namespace**: [{$current_namespace}](#" . + strtolower(str_replace('\\', '-', $current_namespace)) . ")\n"; + } + + // Add the class details + $result .= "\n - " . $class['link']; + } + + return $result; + } + + /** + * Define the order of types for sorting purposes + * + * @return array The order of types + * @since 3.2.0 + */ + private function defineTypeOrder(): array + { + return [ + 'interface' => 1, + 'abstract' => 2, + 'abstract class' => 2, + 'final' => 3, + 'final class' => 3, + 'class' => 4, + 'trait' => 5 + ]; + } + + /** + * Sort the flattened array using a single sorting function + * + * @param array $classes The classes to sort + * @param array $typeOrder The order of types + * @since 3.2.0 + */ + private function sortClasses(array &$classes, array $typeOrder): void + { + usort($classes, function ($a, $b) use ($typeOrder) { + $namespaceDiff = $this->compareNamespace($a, $b); + + if ($namespaceDiff !== 0) + { + return $namespaceDiff; + } + + $typeDiff = $this->compareType($a, $b, $typeOrder); + + if ($typeDiff !== 0) + { + return $typeDiff; + } + + return $this->compareName($a, $b); + }); + } + + /** + * Compare the namespace of two classes + * + * @param array $a First class + * @param array $b Second class + * + * @return int Comparison result + * @since 3.2.0 + */ + private function compareNamespace(array $a, array $b): int + { + $namespaceDepthDiff = substr_count($a['namespace'], '\\') - substr_count($b['namespace'], '\\'); + + if ($namespaceDepthDiff === 0) + { + return strcmp($a['namespace'], $b['namespace']); + } + + return $namespaceDepthDiff; + } + + /** + * Compare the type of two classes + * + * @param array $a First class + * @param array $b Second class + * @param array $typeOrder The order of types + * + * @return int Comparison result + * @since 3.2.0 + */ + private function compareType(array $a, array $b, array $typeOrder): int + { + return $typeOrder[$a['type']] <=> $typeOrder[$b['type']]; + } + + /** + * Compare the name of two classes + * + * @param array $a First class + * @param array $b Second class + * + * @return int Comparison result + * @since 3.2.0 + */ + private function compareName(array $a, array $b): int + { + return strcmp($a['name'], $b['name']); + } + + /** + * Build the Link to the power in this repository + * + * @param array $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function indexLinkPower(array &$power): string + { + $type = $power['type'] ?? 'error'; + $name = $power['name'] ?? 'error'; + return '**' . $type . ' ' . $name . "** | " + . $this->linkPowerRepo($power) . ' | ' + . $this->linkPowerCode($power) . ' | ' + . $this->linkPowerSettings($power) . ' | ' + . $this->linkPowerSPK($power); + } + + /** + * Build the Link to the power in this repository + * + * @param array $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerRepo(array &$power): string + { + $path = $power['path'] ?? 'error'; + return '[Details](' . $path . ')'; + } + + /** + * Build the Link to the power settings in this repository + * + * @param array $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerCode(array &$power): string + { + $code = $power['code'] ?? 'error'; + return '[Code](' . $code . ')'; + } + + /** + * Build the Link to the power settings in this repository + * + * @param array $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerSettings(array &$power): string + { + $settings = $power['settings'] ?? 'error'; + return '[Settings](' . $settings . ')'; + } + + /** + * Get the SuperPowerKey (SPK) + * + * @param array $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerSPK(array &$power): string + { + $spk = $power['spk'] ?? 'error'; + return $spk; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php new file mode 100644 index 000000000..6178083d6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php @@ -0,0 +1,450 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; + + +/** + * Power Structure Builder Class + * + * @since 3.2.0 + */ +class Structure +{ + /** + * we track the creation of htaccess files + * + * @var array + * @since 3.2.0 + **/ + protected array $htaccess = []; + + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The compiler registry + * + * @var Registry + * @since 3.2.0 + */ + protected Registry $registry; + + /** + * Compiler Event + * + * @var EventInterface + * @since 3.2.0 + */ + protected EventInterface $event; + + /** + * Compiler Counter + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Compiler Utilities Paths + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * Compiler Utilities Folder + * + * @var Folder + * @since 3.2.0 + */ + protected Folder $folder; + + /** + * Compiler Utilities File + * + * @var File + * @since 3.2.0 + */ + protected File $file; + + /** + * Compiler Utilities Files + * + * @var Files + * @since 3.2.0 + */ + protected Files $files; + + /** + * Database object to query local DB + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor + * + * @param Power|null $power The power object. + * @param Config|null $config The compiler config object. + * @param Registry|null $registry The compiler registry object. + * @param EventInterface|null $event The compiler event api object. + * @param Counter|null $counter The compiler counter object. + * @param Paths|null $paths The compiler paths object. + * @param Folder|null $folder The compiler folder object. + * @param File|null $file The compiler file object. + * @param Files|null $files The compiler files object. + * @param CMSApplication|null $app The CMS Application object. + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Config $config = null, + ?Registry $registry = null, ?EventInterface $event = null, + ?Counter $counter = null, ?Paths $paths = null, ?Folder $folder = null, + ?File $file = null, ?Files $files = null, ?CMSApplication $app = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->config = $config ?: Compiler::_('Config'); + $this->registry = $registry ?: Compiler::_('Registry'); + $this->event = $event ?: Compiler::_('Event'); + $this->counter = $counter ?: Compiler::_('Utilities.Counter'); + $this->paths = $paths ?: Compiler::_('Utilities.Paths'); + $this->folder = $folder ?: Compiler::_('Utilities.Folder'); + $this->file = $file ?: Compiler::_('Utilities.File'); + $this->files = $files ?: Compiler::_('Utilities.Files'); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * Build the Powers files, folders + * + * @return void + * @since 3.2.0 + */ + public function build() + { + if (ArrayHelper::check($this->power->active)) + { + // for plugin event TODO change event api signatures + $powers = $this->power->active; + $component_context = $this->config->component_context; + // Trigger Event: jcb_ce_onBeforeSetModules + $this->event->trigger( + 'jcb_ce_onBeforeBuildPowers', + array(&$component_context, &$powers) + ); + // for plugin event TODO change event api signatures + $this->power->active = $powers; + + // set super power details + $this->setSuperPowerDetails(); + + foreach ($this->power->active as $power) + { + if (ObjectHelper::check($power) + && isset($power->path) + && StringHelper::check( + $power->path + )) + { + // activate dynamic folders + $this->setDynamicFolders(); + + // power path + $power->full_path = $this->paths->component_path . '/' + . $power->path; + $power->full_path_jcb = $this->paths->component_path . '/' + . $power->path_jcb; + $power->full_path_parent = $this->paths->component_path . '/' + . $power->path_parent; + + // set the power paths + $this->registry->set('dynamic_paths.' . $power->key, $power->full_path_parent); + + // create the power folder if it does not exist + // we do it like this to add html files to each part + $this->folder->create($power->full_path_jcb); + $this->folder->create($power->full_path_parent); + $this->folder->create($power->full_path); + + $bom = 'add_licensing_template == 2) + { + $bom = 'licensing_template; + } + + // set the main power php file + $this->createFile($bom . PHP_EOL . Placefix::_h('POWERCODE') . PHP_EOL, + $power->full_path, $power->file_name . '.php', $power->key); + + // set super power files + $this->setSuperPowerFiles($power, $bom); + + // set htaccess once per path + $this->setHtaccess($power); + } + } + } + } + + /** + * Create a file with optional custom content and save it to the given path. + * + * @param string $content The content. + * @param string $fullPath The full path to the destination folder. + * @param string $fileName The file name without the extension. + * @param string $key The key to append the file details. + * + * @return void + * @since 3.2.0 + */ + private function createFile(string $content, string $fullPath, string $fileName, string $key) + { + $file_details = [ + 'path' => $fullPath . '/' . $fileName, + 'name' => $fileName, + 'zip' => $fileName + ]; + + // Write the content to the file + $this->file->write($file_details['path'], $content); + + // Append the file details to the files array + $this->files->appendArray($key, $file_details); + + // Increment the file counter + $this->counter->file++; + } + + /** + * Set the .htaccess for this power path + * + * @param object $power The power object + * + * @return void + * @since 3.2.0 + */ + private function setHtaccess(object &$power) + { + if (!isset($this->htaccess[$power->path_jcb])) + { + // set the htaccess data + $data = '# Apache 2.4+' . PHP_EOL . + '' . PHP_EOL . + ' Require all denied' . PHP_EOL . + '' . PHP_EOL . PHP_EOL . + '# Apache 2.0-2.2' . PHP_EOL . + '' . PHP_EOL . + ' Deny from all' . PHP_EOL . + '' . PHP_EOL; + + // now we must add the .htaccess file + $fileDetails = array('path' => $power->full_path_jcb . '/.htaccess', + 'name' => '.htaccess', + 'zip' => '.htaccess'); + $this->file->write( + $fileDetails['path'], $data + ); + $this->files->appendArray($power->key, $fileDetails); + + // count the file created + $this->counter->file++; + + // now we must add the htaccess.txt file where the zip package my not get the [.] files + $fileDetails = array('path' => $power->full_path_jcb . '/htaccess.txt', + 'name' => 'htaccess.txt', + 'zip' => 'htaccess.txt'); + $this->file->write( + $fileDetails['path'], $data + ); + $this->files->appendArray($power->key, $fileDetails); + + // count the file created + $this->counter->file++; + + // now we must add the web.config file + $fileDetails = array('path' => $power->full_path_jcb . '/web.config', + 'name' => 'web.config', + 'zip' => 'web.config'); + $this->file->write( + $fileDetails['path'], + '' . PHP_EOL . + ' ' . PHP_EOL . + ' ' . PHP_EOL . + ' ' . PHP_EOL . + ' ' . PHP_EOL . + ' ' . PHP_EOL . + '' . PHP_EOL + ); + $this->files->appendArray($power->key, $fileDetails); + + // count the file created + $this->counter->file++; + + // we set these files only once + $this->htaccess[$power->path_jcb] = true; + } + } + + /** + * Add the dynamic folders + * + * @return void + * @since 3.2.0 + */ + private function setDynamicFolders() + { + // check if we should add the dynamic folder moving script to the installer script + if (!$this->registry->get('set_move_folders_install_script')) + { + // add the setDynamicF0ld3rs() method to the install script.php file + $this->registry->set('set_move_folders_install_script', true); + + // set message that this was done (will still add a tutorial link later) + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREEDYNAMIC_FOLDERS_WERE_DETECTEDHTHREE'), + 'Notice' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_A_METHOD_SETDYNAMICFZEROLDTHREERS_WAS_ADDED_TO_THE_INSTALL_BSCRIPTPHPB_OF_THIS_PACKAGE_TO_INSURE_THAT_THE_FOLDERS_ARE_COPIED_INTO_THE_CORRECT_PLACE_WHEN_THIS_COMPONENT_IS_INSTALLED'), + 'Notice' + ); + } + } + + /** + * Set the super powers details structure + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowerDetails() + { + if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) + { + foreach ($this->power->superpowers as $path => $powers) + { + // get existing files + $this->loadExistingSuperPower($path); + + // create the path if it does not exist + $this->folder->create($path, false); + + $key = StringHelper::safe($path); + + // set the super powers readme file + $this->createFile(Placefix::_h('POWERREADME'), + $path, 'README.md', $key); + + // set the super power index file + $this->createFile(Placefix::_h('POWERINDEX'), $path, + 'super-powers.json', $key); + } + } + } + + /** + * Set the super power file paths + * + * @param object $power The power object + * @param string $bom The bom for the top of the PHP files + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowerFiles(object &$power, string $bom) + { + if ($this->config->add_super_powers && is_array($power->super_power_paths) && $power->super_power_paths !== []) + { + foreach ($power->super_power_paths as $path) + { + // create the path if it does not exist + $this->folder->create($path, false); + + // set the super power php file + $this->createFile($bom . PHP_EOL . Placefix::_h('POWERCODE') . PHP_EOL, + $path, 'code.php', $power->key); + + // set the super power php RAW file + $this->createFile(Placefix::_h('CODEPOWER'), + $path, 'code.power', $power->key); + + // set the super power json file + $this->createFile(Placefix::_h('POWERLINKER'), $path, + 'settings.json', $power->key); + + // set the super power readme file + $this->createFile(Placefix::_h('POWERREADME'), $path, + 'README.md', $power->key); + } + } + } + + /** + * Set the super power file paths + * + * @param string $repository The super power repository + * + * @return void + * @since 3.2.0 + */ + private function loadExistingSuperPower(string $repository) + { + if (($content = FileHelper::getContent($repository . '/super-powers.json', null)) !== null && + JsonHelper::check($content)) + { + $this->power->old_superpowers[$repository] = json_decode($content, true); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Registry.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Registry.php new file mode 100644 index 000000000..eb6c3c36c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Registry.php @@ -0,0 +1,26 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler; + + +use VDM\Joomla\Componentbuilder\Abstraction\BaseRegistry; + + +/** + * Compiler Registry + * + * @since 3.2.0 + */ +class Registry extends BaseRegistry +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Adminview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Adminview.php new file mode 100644 index 000000000..5fb5dc36e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Adminview.php @@ -0,0 +1,96 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Adminview\Data as AdminviewData; +use VDM\Joomla\Componentbuilder\Compiler\Adminview\Permission; + + +/** + * Compiler Adminview + * + * @since 3.2.0 + */ +class Adminview implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(AdminviewData::class, 'Adminview.Data') + ->share('Adminview.Data', [$this, 'getAdminviewData'], true); + + $container->alias(Permission::class, 'Adminview.Permission') + ->share('Adminview.Permission', [$this, 'getAdminviewPermission'], true); + } + + /** + * Get the Compiler Adminview Data + * + * @param Container $container The DI container. + * + * @return AdminviewData + * @since 3.2.0 + */ + public function getAdminviewData(Container $container): AdminviewData + { + return new AdminviewData( + $container->get('Config'), + $container->get('Event'), + $container->get('Placeholder'), + $container->get('Customcode.Dispenser'), + $container->get('Model.Customtabs'), + $container->get('Model.Tabs'), + $container->get('Model.Fields'), + $container->get('Model.Historyadminview'), + $container->get('Model.Permissions'), + $container->get('Model.Conditions'), + $container->get('Model.Relations'), + $container->get('Model.Linkedviews'), + $container->get('Model.Javascriptadminview'), + $container->get('Model.Cssadminview'), + $container->get('Model.Phpadminview'), + $container->get('Model.Custombuttons'), + $container->get('Model.Customimportscripts'), + $container->get('Model.Ajaxadmin'), + $container->get('Model.Customalias'), + $container->get('Model.Sql'), + $container->get('Model.Mysqlsettings'), + $container->get('Compiler.Builder.Site.Edit.View') + ); + } + + /** + * Get the Compiler Adminview Permission + * + * @param Container $container The DI container. + * + * @return Permission + * @since 3.2.0 + */ + public function getAdminviewPermission(Container $container): Permission + { + return new Permission( + $container->get('Compiler.Builder.Has.Permissions') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Builder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Builder.php new file mode 100644 index 000000000..8e5f73592 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Builder.php @@ -0,0 +1,1550 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitchList; +use VDM\Joomla\Componentbuilder\Compiler\Builder\AdminFilterType; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Alias; +use VDM\Joomla\Componentbuilder\Compiler\Builder\BaseSixFour; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Category; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CategoryCode; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CategoryOtherName; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CheckBox; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ComponentFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomAlias; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomFieldLinks; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomList; +use VDM\Joomla\Componentbuilder\Compiler\Builder\CustomTabs; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseKeys; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseTables; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseUniqueGuid; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DatabaseUniqueKeys; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DoNotEscape; +use VDM\Joomla\Componentbuilder\Compiler\Builder\DynamicFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ExtensionCustomFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldGroupControl; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldNames; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FieldRelations; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Filter; +use VDM\Joomla\Componentbuilder\Compiler\Builder\FootableScripts; +use VDM\Joomla\Componentbuilder\Compiler\Builder\GetAsLookup; +use VDM\Joomla\Componentbuilder\Compiler\Builder\GetModule; +use VDM\Joomla\Componentbuilder\Compiler\Builder\GoogleChart; +use VDM\Joomla\Componentbuilder\Compiler\Builder\HasPermissions; +use VDM\Joomla\Componentbuilder\Compiler\Builder\HiddenFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\History; +use VDM\Joomla\Componentbuilder\Compiler\Builder\IntegerFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ItemsMethodEximportString; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ItemsMethodListString; +use VDM\Joomla\Componentbuilder\Compiler\Builder\JsonItem; +use VDM\Joomla\Componentbuilder\Compiler\Builder\JsonItemArray; +use VDM\Joomla\Componentbuilder\Compiler\Builder\JsonString; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Layout; +use VDM\Joomla\Componentbuilder\Compiler\Builder\LayoutData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\LibraryManager; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListFieldClass; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListHeadOverride; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ListJoin; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Lists; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MainTextField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MetaData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelBasicField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelExpertField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelExpertFieldInitiator; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelMediumField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ModelWhmcsField; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MovedPublishingFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\MysqlTableSetting; +use VDM\Joomla\Componentbuilder\Compiler\Builder\NewPublishingFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OrderZero; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OtherFilter; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OtherGroup; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OtherJoin; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OtherOrder; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OtherQuery; +use VDM\Joomla\Componentbuilder\Compiler\Builder\OtherWhere; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionAction; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionComponent; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionCore; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionDashboard; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionGlobalAction; +use VDM\Joomla\Componentbuilder\Compiler\Builder\PermissionViews; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ScriptMediaSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\ScriptUserSwitch; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Search; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SelectionTranslation; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteDecrypt; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteDynamicGet; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteEditView; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFieldData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFieldDecodeFilter; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteFields; +use VDM\Joomla\Componentbuilder\Compiler\Builder\SiteMainGet; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Sort; +use VDM\Joomla\Componentbuilder\Compiler\Builder\TabCounter; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Tags; +use VDM\Joomla\Componentbuilder\Compiler\Builder\TemplateData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Title; +use VDM\Joomla\Componentbuilder\Compiler\Builder\UikitComp; +use VDM\Joomla\Componentbuilder\Compiler\Builder\UpdateMysql; + + +/** + * Builder Service Provider + * + * @since 3.2.0 + */ +class Builder implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(AccessSwitch::class, 'Compiler.Builder.Access.Switch') + ->share('Compiler.Builder.Access.Switch', [$this, 'getAccessSwitch'], true); + + $container->alias(AccessSwitchList::class, 'Compiler.Builder.Access.Switch.List') + ->share('Compiler.Builder.Access.Switch.List', [$this, 'getAccessSwitchList'], true); + + $container->alias(AdminFilterType::class, 'Compiler.Builder.Admin.Filter.Type') + ->share('Compiler.Builder.Admin.Filter.Type', [$this, 'getAdminFilterType'], true); + + $container->alias(Alias::class, 'Compiler.Builder.Alias') + ->share('Compiler.Builder.Alias', [$this, 'getAlias'], true); + + $container->alias(BaseSixFour::class, 'Compiler.Builder.Base.Six.Four') + ->share('Compiler.Builder.Base.Six.Four', [$this, 'getBaseSixFour'], true); + + $container->alias(Category::class, 'Compiler.Builder.Category') + ->share('Compiler.Builder.Category', [$this, 'getCategory'], true); + + $container->alias(CategoryCode::class, 'Compiler.Builder.Category.Code') + ->share('Compiler.Builder.Category.Code', [$this, 'getCategoryCode'], true); + + $container->alias(CategoryOtherName::class, 'Compiler.Builder.Category.Other.Name') + ->share('Compiler.Builder.Category.Other.Name', [$this, 'getCategoryOtherName'], true); + + $container->alias(CheckBox::class, 'Compiler.Builder.Check.Box') + ->share('Compiler.Builder.Check.Box', [$this, 'getCheckBox'], true); + + $container->alias(ComponentFields::class, 'Compiler.Builder.Component.Fields') + ->share('Compiler.Builder.Component.Fields', [$this, 'getComponentFields'], true); + + $container->alias(ContentMulti::class, 'Compiler.Builder.Content.Multi') + ->share('Compiler.Builder.Content.Multi', [$this, 'getContentMulti'], true); + + $container->alias(ContentOne::class, 'Compiler.Builder.Content.One') + ->share('Compiler.Builder.Content.One', [$this, 'getContentOne'], true); + + $container->alias(CustomAlias::class, 'Compiler.Builder.Custom.Alias') + ->share('Compiler.Builder.Custom.Alias', [$this, 'getCustomAlias'], true); + + $container->alias(CustomField::class, 'Compiler.Builder.Custom.Field') + ->share('Compiler.Builder.Custom.Field', [$this, 'getCustomField'], true); + + $container->alias(CustomFieldLinks::class, 'Compiler.Builder.Custom.Field.Links') + ->share('Compiler.Builder.Custom.Field.Links', [$this, 'getCustomFieldLinks'], true); + + $container->alias(CustomList::class, 'Compiler.Builder.Custom.List') + ->share('Compiler.Builder.Custom.List', [$this, 'getCustomList'], true); + + $container->alias(CustomTabs::class, 'Compiler.Builder.Custom.Tabs') + ->share('Compiler.Builder.Custom.Tabs', [$this, 'getCustomTabs'], true); + + $container->alias(DatabaseKeys::class, 'Compiler.Builder.Database.Keys') + ->share('Compiler.Builder.Database.Keys', [$this, 'getDatabaseKeys'], true); + + $container->alias(DatabaseTables::class, 'Compiler.Builder.Database.Tables') + ->share('Compiler.Builder.Database.Tables', [$this, 'getDatabaseTables'], true); + + $container->alias(DatabaseUniqueGuid::class, 'Compiler.Builder.Database.Unique.Guid') + ->share('Compiler.Builder.Database.Unique.Guid', [$this, 'getDatabaseUniqueGuid'], true); + + $container->alias(DatabaseUniqueKeys::class, 'Compiler.Builder.Database.Unique.Keys') + ->share('Compiler.Builder.Database.Unique.Keys', [$this, 'getDatabaseUniqueKeys'], true); + + $container->alias(DoNotEscape::class, 'Compiler.Builder.Do.Not.Escape') + ->share('Compiler.Builder.Do.Not.Escape', [$this, 'getDoNotEscape'], true); + + $container->alias(DynamicFields::class, 'Compiler.Builder.Dynamic.Fields') + ->share('Compiler.Builder.Dynamic.Fields', [$this, 'getDynamicFields'], true); + + $container->alias(ExtensionCustomFields::class, 'Compiler.Builder.Extension.Custom.Fields') + ->share('Compiler.Builder.Extension.Custom.Fields', [$this, 'getExtensionCustomFields'], true); + + $container->alias(FieldGroupControl::class, 'Compiler.Builder.Field.Group.Control') + ->share('Compiler.Builder.Field.Group.Control', [$this, 'getFieldGroupControl'], true); + + $container->alias(FieldNames::class, 'Compiler.Builder.Field.Names') + ->share('Compiler.Builder.Field.Names', [$this, 'getFieldNames'], true); + + $container->alias(FieldRelations::class, 'Compiler.Builder.Field.Relations') + ->share('Compiler.Builder.Field.Relations', [$this, 'getFieldRelations'], true); + + $container->alias(Filter::class, 'Compiler.Builder.Filter') + ->share('Compiler.Builder.Filter', [$this, 'getFilter'], true); + + $container->alias(FootableScripts::class, 'Compiler.Builder.Footable.Scripts') + ->share('Compiler.Builder.Footable.Scripts', [$this, 'getFootableScripts'], true); + + $container->alias(GetAsLookup::class, 'Compiler.Builder.Get.As.Lookup') + ->share('Compiler.Builder.Get.As.Lookup', [$this, 'getGetAsLookup'], true); + + $container->alias(GetModule::class, 'Compiler.Builder.Get.Module') + ->share('Compiler.Builder.Get.Module', [$this, 'getGetModule'], true); + + $container->alias(GoogleChart::class, 'Compiler.Builder.Google.Chart') + ->share('Compiler.Builder.Google.Chart', [$this, 'getGoogleChart'], true); + + $container->alias(HasPermissions::class, 'Compiler.Builder.Has.Permissions') + ->share('Compiler.Builder.Has.Permissions', [$this, 'getHasPermissions'], true); + + $container->alias(HiddenFields::class, 'Compiler.Builder.Hidden.Fields') + ->share('Compiler.Builder.Hidden.Fields', [$this, 'getHiddenFields'], true); + + $container->alias(History::class, 'Compiler.Builder.History') + ->share('Compiler.Builder.History', [$this, 'getHistory'], true); + + $container->alias(IntegerFields::class, 'Compiler.Builder.Integer.Fields') + ->share('Compiler.Builder.Integer.Fields', [$this, 'getIntegerFields'], true); + + $container->alias(ItemsMethodEximportString::class, 'Compiler.Builder.Items.Method.Eximport.String') + ->share('Compiler.Builder.Items.Method.Eximport.String', [$this, 'getItemsMethodEximportString'], true); + + $container->alias(ItemsMethodListString::class, 'Compiler.Builder.Items.Method.List.String') + ->share('Compiler.Builder.Items.Method.List.String', [$this, 'getItemsMethodListString'], true); + + $container->alias(JsonItem::class, 'Compiler.Builder.Json.Item') + ->share('Compiler.Builder.Json.Item', [$this, 'getJsonItem'], true); + + $container->alias(JsonItemArray::class, 'Compiler.Builder.Json.Item.Array') + ->share('Compiler.Builder.Json.Item.Array', [$this, 'getJsonItemArray'], true); + + $container->alias(JsonString::class, 'Compiler.Builder.Json.String') + ->share('Compiler.Builder.Json.String', [$this, 'getJsonString'], true); + + $container->alias(Layout::class, 'Compiler.Builder.Layout') + ->share('Compiler.Builder.Layout', [$this, 'getLayout'], true); + + $container->alias(LayoutData::class, 'Compiler.Builder.Layout.Data') + ->share('Compiler.Builder.Layout.Data', [$this, 'getLayoutData'], true); + + $container->alias(LibraryManager::class, 'Compiler.Builder.Library.Manager') + ->share('Compiler.Builder.Library.Manager', [$this, 'getLibraryManager'], true); + + $container->alias(ListFieldClass::class, 'Compiler.Builder.List.Field.Class') + ->share('Compiler.Builder.List.Field.Class', [$this, 'getListFieldClass'], true); + + $container->alias(ListHeadOverride::class, 'Compiler.Builder.List.Head.Override') + ->share('Compiler.Builder.List.Head.Override', [$this, 'getListHeadOverride'], true); + + $container->alias(ListJoin::class, 'Compiler.Builder.List.Join') + ->share('Compiler.Builder.List.Join', [$this, 'getListJoin'], true); + + $container->alias(Lists::class, 'Compiler.Builder.Lists') + ->share('Compiler.Builder.Lists', [$this, 'getLists'], true); + + $container->alias(MainTextField::class, 'Compiler.Builder.Main.Text.Field') + ->share('Compiler.Builder.Main.Text.Field', [$this, 'getMainTextField'], true); + + $container->alias(MetaData::class, 'Compiler.Builder.Meta.Data') + ->share('Compiler.Builder.Meta.Data', [$this, 'getMetaData'], true); + + $container->alias(ModelBasicField::class, 'Compiler.Builder.Model.Basic.Field') + ->share('Compiler.Builder.Model.Basic.Field', [$this, 'getModelBasicField'], true); + + $container->alias(ModelExpertField::class, 'Compiler.Builder.Model.Expert.Field') + ->share('Compiler.Builder.Model.Expert.Field', [$this, 'getModelExpertField'], true); + + $container->alias(ModelExpertFieldInitiator::class, 'Compiler.Builder.Model.Expert.Field.Initiator') + ->share('Compiler.Builder.Model.Expert.Field.Initiator', [$this, 'getModelExpertFieldInitiator'], true); + + $container->alias(ModelMediumField::class, 'Compiler.Builder.Model.Medium.Field') + ->share('Compiler.Builder.Model.Medium.Field', [$this, 'getModelMediumField'], true); + + $container->alias(ModelWhmcsField::class, 'Compiler.Builder.Model.Whmcs.Field') + ->share('Compiler.Builder.Model.Whmcs.Field', [$this, 'getModelWhmcsField'], true); + + $container->alias(MovedPublishingFields::class, 'Compiler.Builder.Moved.Publishing.Fields') + ->share('Compiler.Builder.Moved.Publishing.Fields', [$this, 'getMovedPublishingFields'], true); + + $container->alias(MysqlTableSetting::class, 'Compiler.Builder.Mysql.Table.Setting') + ->share('Compiler.Builder.Mysql.Table.Setting', [$this, 'getMysqlTableSetting'], true); + + $container->alias(NewPublishingFields::class, 'Compiler.Builder.New.Publishing.Fields') + ->share('Compiler.Builder.New.Publishing.Fields', [$this, 'getNewPublishingFields'], true); + + $container->alias(OrderZero::class, 'Compiler.Builder.Order.Zero') + ->share('Compiler.Builder.Order.Zero', [$this, 'getOrderZero'], true); + + $container->alias(OtherFilter::class, 'Compiler.Builder.Other.Filter') + ->share('Compiler.Builder.Other.Filter', [$this, 'getOtherFilter'], true); + + $container->alias(OtherGroup::class, 'Compiler.Builder.Other.Group') + ->share('Compiler.Builder.Other.Group', [$this, 'getOtherGroup'], true); + + $container->alias(OtherJoin::class, 'Compiler.Builder.Other.Join') + ->share('Compiler.Builder.Other.Join', [$this, 'getOtherJoin'], true); + + $container->alias(OtherOrder::class, 'Compiler.Builder.Other.Order') + ->share('Compiler.Builder.Other.Order', [$this, 'getOtherOrder'], true); + + $container->alias(OtherQuery::class, 'Compiler.Builder.Other.Query') + ->share('Compiler.Builder.Other.Query', [$this, 'getOtherQuery'], true); + + $container->alias(OtherWhere::class, 'Compiler.Builder.Other.Where') + ->share('Compiler.Builder.Other.Where', [$this, 'getOtherWhere'], true); + + $container->alias(PermissionAction::class, 'Compiler.Builder.Permission.Action') + ->share('Compiler.Builder.Permission.Action', [$this, 'getPermissionAction'], true); + + $container->alias(PermissionComponent::class, 'Compiler.Builder.Permission.Component') + ->share('Compiler.Builder.Permission.Component', [$this, 'getPermissionComponent'], true); + + $container->alias(PermissionCore::class, 'Compiler.Builder.Permission.Core') + ->share('Compiler.Builder.Permission.Core', [$this, 'getPermissionCore'], true); + + $container->alias(PermissionDashboard::class, 'Compiler.Builder.Permission.Dashboard') + ->share('Compiler.Builder.Permission.Dashboard', [$this, 'getPermissionDashboard'], true); + + $container->alias(PermissionGlobalAction::class, 'Compiler.Builder.Permission.Global.Action') + ->share('Compiler.Builder.Permission.Global.Action', [$this, 'getPermissionGlobalAction'], true); + + $container->alias(PermissionViews::class, 'Compiler.Builder.Permission.Views') + ->share('Compiler.Builder.Permission.Views', [$this, 'getPermissionViews'], true); + + $container->alias(ScriptMediaSwitch::class, 'Compiler.Builder.Script.Media.Switch') + ->share('Compiler.Builder.Script.Media.Switch', [$this, 'getScriptMediaSwitch'], true); + + $container->alias(ScriptUserSwitch::class, 'Compiler.Builder.Script.User.Switch') + ->share('Compiler.Builder.Script.User.Switch', [$this, 'getScriptUserSwitch'], true); + + $container->alias(Search::class, 'Compiler.Builder.Search') + ->share('Compiler.Builder.Search', [$this, 'getSearch'], true); + + $container->alias(SelectionTranslation::class, 'Compiler.Builder.Selection.Translation') + ->share('Compiler.Builder.Selection.Translation', [$this, 'getSelectionTranslation'], true); + + $container->alias(SiteDecrypt::class, 'Compiler.Builder.Site.Decrypt') + ->share('Compiler.Builder.Site.Decrypt', [$this, 'getSiteDecrypt'], true); + + $container->alias(SiteDynamicGet::class, 'Compiler.Builder.Site.Dynamic.Get') + ->share('Compiler.Builder.Site.Dynamic.Get', [$this, 'getSiteDynamicGet'], true); + + $container->alias(SiteEditView::class, 'Compiler.Builder.Site.Edit.View') + ->share('Compiler.Builder.Site.Edit.View', [$this, 'getSiteEditView'], true); + + $container->alias(SiteFieldData::class, 'Compiler.Builder.Site.Field.Data') + ->share('Compiler.Builder.Site.Field.Data', [$this, 'getSiteFieldData'], true); + + $container->alias(SiteFieldDecodeFilter::class, 'Compiler.Builder.Site.Field.Decode.Filter') + ->share('Compiler.Builder.Site.Field.Decode.Filter', [$this, 'getSiteFieldDecodeFilter'], true); + + $container->alias(SiteFields::class, 'Compiler.Builder.Site.Fields') + ->share('Compiler.Builder.Site.Fields', [$this, 'getSiteFields'], true); + + $container->alias(SiteMainGet::class, 'Compiler.Builder.Site.Main.Get') + ->share('Compiler.Builder.Site.Main.Get', [$this, 'getSiteMainGet'], true); + + $container->alias(Sort::class, 'Compiler.Builder.Sort') + ->share('Compiler.Builder.Sort', [$this, 'getSort'], true); + + $container->alias(TabCounter::class, 'Compiler.Builder.Tab.Counter') + ->share('Compiler.Builder.Tab.Counter', [$this, 'getTabCounter'], true); + + $container->alias(Tags::class, 'Compiler.Builder.Tags') + ->share('Compiler.Builder.Tags', [$this, 'getTags'], true); + + $container->alias(TemplateData::class, 'Compiler.Builder.Template.Data') + ->share('Compiler.Builder.Template.Data', [$this, 'getTemplateData'], true); + + $container->alias(Title::class, 'Compiler.Builder.Title') + ->share('Compiler.Builder.Title', [$this, 'getTitle'], true); + + $container->alias(UikitComp::class, 'Compiler.Builder.Uikit.Comp') + ->share('Compiler.Builder.Uikit.Comp', [$this, 'getUikitComp'], true); + + $container->alias(UpdateMysql::class, 'Compiler.Builder.Update.Mysql') + ->share('Compiler.Builder.Update.Mysql', [$this, 'getUpdateMysql'], true); + } + + /** + * Get The AccessSwitch Class. + * + * @param Container $container The DI container. + * + * @return AccessSwitch + * @since 3.2.0 + */ + public function getAccessSwitch(Container $container): AccessSwitch + { + return new AccessSwitch(); + } + + /** + * Get The AccessSwitchList Class. + * + * @param Container $container The DI container. + * + * @return AccessSwitchList + * @since 3.2.0 + */ + public function getAccessSwitchList(Container $container): AccessSwitchList + { + return new AccessSwitchList(); + } + + /** + * Get The AdminFilterType Class. + * + * @param Container $container The DI container. + * + * @return AdminFilterType + * @since 3.2.0 + */ + public function getAdminFilterType(Container $container): AdminFilterType + { + return new AdminFilterType(); + } + + /** + * Get The Alias Class. + * + * @param Container $container The DI container. + * + * @return Alias + * @since 3.2.0 + */ + public function getAlias(Container $container): Alias + { + return new Alias(); + } + + /** + * Get The BaseSixFour Class. + * + * @param Container $container The DI container. + * + * @return BaseSixFour + * @since 3.2.0 + */ + public function getBaseSixFour(Container $container): BaseSixFour + { + return new BaseSixFour(); + } + + /** + * Get The Category Class. + * + * @param Container $container The DI container. + * + * @return Category + * @since 3.2.0 + */ + public function getCategory(Container $container): Category + { + return new Category(); + } + + /** + * Get The CategoryCode Class. + * + * @param Container $container The DI container. + * + * @return CategoryCode + * @since 3.2.0 + */ + public function getCategoryCode(Container $container): CategoryCode + { + return new CategoryCode(); + } + + /** + * Get The CategoryOtherName Class. + * + * @param Container $container The DI container. + * + * @return CategoryOtherName + * @since 3.2.0 + */ + public function getCategoryOtherName(Container $container): CategoryOtherName + { + return new CategoryOtherName(); + } + + /** + * Get The CheckBox Class. + * + * @param Container $container The DI container. + * + * @return CheckBox + * @since 3.2.0 + */ + public function getCheckBox(Container $container): CheckBox + { + return new CheckBox(); + } + + /** + * Get The ComponentFields Class. + * + * @param Container $container The DI container. + * + * @return ComponentFields + * @since 3.2.0 + */ + public function getComponentFields(Container $container): ComponentFields + { + return new ComponentFields(); + } + + /** + * Get The ContentMulti Class. + * + * @param Container $container The DI container. + * + * @return ContentMulti + * @since 3.2.0 + */ + public function getContentMulti(Container $container): ContentMulti + { + return new ContentMulti(); + } + + /** + * Get The ContentOne Class. + * + * @param Container $container The DI container. + * + * @return ContentOne + * @since 3.2.0 + */ + public function getContentOne(Container $container): ContentOne + { + return new ContentOne(); + } + + /** + * Get The CustomAlias Class. + * + * @param Container $container The DI container. + * + * @return CustomAlias + * @since 3.2.0 + */ + public function getCustomAlias(Container $container): CustomAlias + { + return new CustomAlias(); + } + + /** + * Get The CustomField Class. + * + * @param Container $container The DI container. + * + * @return CustomField + * @since 3.2.0 + */ + public function getCustomField(Container $container): CustomField + { + return new CustomField(); + } + + /** + * Get The CustomFieldLinks Class. + * + * @param Container $container The DI container. + * + * @return CustomFieldLinks + * @since 3.2.0 + */ + public function getCustomFieldLinks(Container $container): CustomFieldLinks + { + return new CustomFieldLinks(); + } + + /** + * Get The CustomList Class. + * + * @param Container $container The DI container. + * + * @return CustomList + * @since 3.2.0 + */ + public function getCustomList(Container $container): CustomList + { + return new CustomList(); + } + + /** + * Get The CustomTabs Class. + * + * @param Container $container The DI container. + * + * @return CustomTabs + * @since 3.2.0 + */ + public function getCustomTabs(Container $container): CustomTabs + { + return new CustomTabs(); + } + + /** + * Get The DatabaseKeys Class. + * + * @param Container $container The DI container. + * + * @return DatabaseKeys + * @since 3.2.0 + */ + public function getDatabaseKeys(Container $container): DatabaseKeys + { + return new DatabaseKeys(); + } + + /** + * Get The DatabaseTables Class. + * + * @param Container $container The DI container. + * + * @return DatabaseTables + * @since 3.2.0 + */ + public function getDatabaseTables(Container $container): DatabaseTables + { + return new DatabaseTables(); + } + + /** + * Get The DatabaseUniqueGuid Class. + * + * @param Container $container The DI container. + * + * @return DatabaseUniqueGuid + * @since 3.2.0 + */ + public function getDatabaseUniqueGuid(Container $container): DatabaseUniqueGuid + { + return new DatabaseUniqueGuid(); + } + + /** + * Get The DatabaseUniqueKeys Class. + * + * @param Container $container The DI container. + * + * @return DatabaseUniqueKeys + * @since 3.2.0 + */ + public function getDatabaseUniqueKeys(Container $container): DatabaseUniqueKeys + { + return new DatabaseUniqueKeys(); + } + + /** + * Get The DoNotEscape Class. + * + * @param Container $container The DI container. + * + * @return DoNotEscape + * @since 3.2.0 + */ + public function getDoNotEscape(Container $container): DoNotEscape + { + return new DoNotEscape(); + } + + /** + * Get The DynamicFields Class. + * + * @param Container $container The DI container. + * + * @return DynamicFields + * @since 3.2.0 + */ + public function getDynamicFields(Container $container): DynamicFields + { + return new DynamicFields(); + } + + /** + * Get The ExtensionCustomFields Class. + * + * @param Container $container The DI container. + * + * @return ExtensionCustomFields + * @since 3.2.0 + */ + public function getExtensionCustomFields(Container $container): ExtensionCustomFields + { + return new ExtensionCustomFields(); + } + + /** + * Get The FieldGroupControl Class. + * + * @param Container $container The DI container. + * + * @return FieldGroupControl + * @since 3.2.0 + */ + public function getFieldGroupControl(Container $container): FieldGroupControl + { + return new FieldGroupControl(); + } + + /** + * Get The FieldNames Class. + * + * @param Container $container The DI container. + * + * @return FieldNames + * @since 3.2.0 + */ + public function getFieldNames(Container $container): FieldNames + { + return new FieldNames(); + } + + /** + * Get The FieldRelations Class. + * + * @param Container $container The DI container. + * + * @return FieldRelations + * @since 3.2.0 + */ + public function getFieldRelations(Container $container): FieldRelations + { + return new FieldRelations(); + } + + /** + * Get The Filter Class. + * + * @param Container $container The DI container. + * + * @return Filter + * @since 3.2.0 + */ + public function getFilter(Container $container): Filter + { + return new Filter(); + } + + /** + * Get The FootableScripts Class. + * + * @param Container $container The DI container. + * + * @return FootableScripts + * @since 3.2.0 + */ + public function getFootableScripts(Container $container): FootableScripts + { + return new FootableScripts(); + } + + /** + * Get The GetAsLookup Class. + * + * @param Container $container The DI container. + * + * @return GetAsLookup + * @since 3.2.0 + */ + public function getGetAsLookup(Container $container): GetAsLookup + { + return new GetAsLookup(); + } + + /** + * Get The GetModule Class. + * + * @param Container $container The DI container. + * + * @return GetModule + * @since 3.2.0 + */ + public function getGetModule(Container $container): GetModule + { + return new GetModule(); + } + + /** + * Get The GoogleChart Class. + * + * @param Container $container The DI container. + * + * @return GoogleChart + * @since 3.2.0 + */ + public function getGoogleChart(Container $container): GoogleChart + { + return new GoogleChart(); + } + + /** + * Get The HasPermissions Class. + * + * @param Container $container The DI container. + * + * @return HasPermissions + * @since 3.2.0 + */ + public function getHasPermissions(Container $container): HasPermissions + { + return new HasPermissions(); + } + + /** + * Get The HiddenFields Class. + * + * @param Container $container The DI container. + * + * @return HiddenFields + * @since 3.2.0 + */ + public function getHiddenFields(Container $container): HiddenFields + { + return new HiddenFields(); + } + + /** + * Get The History Class. + * + * @param Container $container The DI container. + * + * @return History + * @since 3.2.0 + */ + public function getHistory(Container $container): History + { + return new History(); + } + + /** + * Get The IntegerFields Class. + * + * @param Container $container The DI container. + * + * @return IntegerFields + * @since 3.2.0 + */ + public function getIntegerFields(Container $container): IntegerFields + { + return new IntegerFields(); + } + + /** + * Get The ItemsMethodEximportString Class. + * + * @param Container $container The DI container. + * + * @return ItemsMethodEximportString + * @since 3.2.0 + */ + public function getItemsMethodEximportString(Container $container): ItemsMethodEximportString + { + return new ItemsMethodEximportString(); + } + + /** + * Get The ItemsMethodListString Class. + * + * @param Container $container The DI container. + * + * @return ItemsMethodListString + * @since 3.2.0 + */ + public function getItemsMethodListString(Container $container): ItemsMethodListString + { + return new ItemsMethodListString(); + } + + /** + * Get The JsonItem Class. + * + * @param Container $container The DI container. + * + * @return JsonItem + * @since 3.2.0 + */ + public function getJsonItem(Container $container): JsonItem + { + return new JsonItem(); + } + + /** + * Get The JsonItemArray Class. + * + * @param Container $container The DI container. + * + * @return JsonItemArray + * @since 3.2.0 + */ + public function getJsonItemArray(Container $container): JsonItemArray + { + return new JsonItemArray(); + } + + /** + * Get The JsonString Class. + * + * @param Container $container The DI container. + * + * @return JsonString + * @since 3.2.0 + */ + public function getJsonString(Container $container): JsonString + { + return new JsonString(); + } + + /** + * Get The Layout Class. + * + * @param Container $container The DI container. + * + * @return Layout + * @since 3.2.0 + */ + public function getLayout(Container $container): Layout + { + return new Layout(); + } + + /** + * Get The LayoutData Class. + * + * @param Container $container The DI container. + * + * @return LayoutData + * @since 3.2.0 + */ + public function getLayoutData(Container $container): LayoutData + { + return new LayoutData(); + } + + /** + * Get The LibraryManager Class. + * + * @param Container $container The DI container. + * + * @return LibraryManager + * @since 3.2.0 + */ + public function getLibraryManager(Container $container): LibraryManager + { + return new LibraryManager(); + } + + /** + * Get The ListFieldClass Class. + * + * @param Container $container The DI container. + * + * @return ListFieldClass + * @since 3.2.0 + */ + public function getListFieldClass(Container $container): ListFieldClass + { + return new ListFieldClass(); + } + + /** + * Get The ListHeadOverride Class. + * + * @param Container $container The DI container. + * + * @return ListHeadOverride + * @since 3.2.0 + */ + public function getListHeadOverride(Container $container): ListHeadOverride + { + return new ListHeadOverride(); + } + + /** + * Get The ListJoin Class. + * + * @param Container $container The DI container. + * + * @return ListJoin + * @since 3.2.0 + */ + public function getListJoin(Container $container): ListJoin + { + return new ListJoin(); + } + + /** + * Get The Lists Class. + * + * @param Container $container The DI container. + * + * @return Lists + * @since 3.2.0 + */ + public function getLists(Container $container): Lists + { + return new Lists(); + } + + /** + * Get The MainTextField Class. + * + * @param Container $container The DI container. + * + * @return MainTextField + * @since 3.2.0 + */ + public function getMainTextField(Container $container): MainTextField + { + return new MainTextField(); + } + + /** + * Get The MetaData Class. + * + * @param Container $container The DI container. + * + * @return MetaData + * @since 3.2.0 + */ + public function getMetaData(Container $container): MetaData + { + return new MetaData(); + } + + /** + * Get The ModelBasicField Class. + * + * @param Container $container The DI container. + * + * @return ModelBasicField + * @since 3.2.0 + */ + public function getModelBasicField(Container $container): ModelBasicField + { + return new ModelBasicField(); + } + + /** + * Get The ModelExpertField Class. + * + * @param Container $container The DI container. + * + * @return ModelExpertField + * @since 3.2.0 + */ + public function getModelExpertField(Container $container): ModelExpertField + { + return new ModelExpertField(); + } + + /** + * Get The ModelExpertFieldInitiator Class. + * + * @param Container $container The DI container. + * + * @return ModelExpertFieldInitiator + * @since 3.2.0 + */ + public function getModelExpertFieldInitiator(Container $container): ModelExpertFieldInitiator + { + return new ModelExpertFieldInitiator(); + } + + /** + * Get The ModelMediumField Class. + * + * @param Container $container The DI container. + * + * @return ModelMediumField + * @since 3.2.0 + */ + public function getModelMediumField(Container $container): ModelMediumField + { + return new ModelMediumField(); + } + + /** + * Get The ModelWhmcsField Class. + * + * @param Container $container The DI container. + * + * @return ModelWhmcsField + * @since 3.2.0 + */ + public function getModelWhmcsField(Container $container): ModelWhmcsField + { + return new ModelWhmcsField(); + } + + /** + * Get The MovedPublishingFields Class. + * + * @param Container $container The DI container. + * + * @return MovedPublishingFields + * @since 3.2.0 + */ + public function getMovedPublishingFields(Container $container): MovedPublishingFields + { + return new MovedPublishingFields(); + } + + /** + * Get The MysqlTableSetting Class. + * + * @param Container $container The DI container. + * + * @return MysqlTableSetting + * @since 3.2.0 + */ + public function getMysqlTableSetting(Container $container): MysqlTableSetting + { + return new MysqlTableSetting(); + } + + /** + * Get The NewPublishingFields Class. + * + * @param Container $container The DI container. + * + * @return NewPublishingFields + * @since 3.2.0 + */ + public function getNewPublishingFields(Container $container): NewPublishingFields + { + return new NewPublishingFields(); + } + + /** + * Get The OrderZero Class. + * + * @param Container $container The DI container. + * + * @return OrderZero + * @since 3.2.0 + */ + public function getOrderZero(Container $container): OrderZero + { + return new OrderZero(); + } + + /** + * Get The OtherFilter Class. + * + * @param Container $container The DI container. + * + * @return OtherFilter + * @since 3.2.0 + */ + public function getOtherFilter(Container $container): OtherFilter + { + return new OtherFilter(); + } + + /** + * Get The OtherGroup Class. + * + * @param Container $container The DI container. + * + * @return OtherGroup + * @since 3.2.0 + */ + public function getOtherGroup(Container $container): OtherGroup + { + return new OtherGroup(); + } + + /** + * Get The OtherJoin Class. + * + * @param Container $container The DI container. + * + * @return OtherJoin + * @since 3.2.0 + */ + public function getOtherJoin(Container $container): OtherJoin + { + return new OtherJoin(); + } + + /** + * Get The OtherOrder Class. + * + * @param Container $container The DI container. + * + * @return OtherOrder + * @since 3.2.0 + */ + public function getOtherOrder(Container $container): OtherOrder + { + return new OtherOrder(); + } + + /** + * Get The OtherQuery Class. + * + * @param Container $container The DI container. + * + * @return OtherQuery + * @since 3.2.0 + */ + public function getOtherQuery(Container $container): OtherQuery + { + return new OtherQuery(); + } + + /** + * Get The OtherWhere Class. + * + * @param Container $container The DI container. + * + * @return OtherWhere + * @since 3.2.0 + */ + public function getOtherWhere(Container $container): OtherWhere + { + return new OtherWhere(); + } + + /** + * Get The PermissionAction Class. + * + * @param Container $container The DI container. + * + * @return PermissionAction + * @since 3.2.0 + */ + public function getPermissionAction(Container $container): PermissionAction + { + return new PermissionAction(); + } + + /** + * Get The PermissionComponent Class. + * + * @param Container $container The DI container. + * + * @return PermissionComponent + * @since 3.2.0 + */ + public function getPermissionComponent(Container $container): PermissionComponent + { + return new PermissionComponent(); + } + + /** + * Get The PermissionCore Class. + * + * @param Container $container The DI container. + * + * @return PermissionCore + * @since 3.2.0 + */ + public function getPermissionCore(Container $container): PermissionCore + { + return new PermissionCore(); + } + + /** + * Get The PermissionDashboard Class. + * + * @param Container $container The DI container. + * + * @return PermissionDashboard + * @since 3.2.0 + */ + public function getPermissionDashboard(Container $container): PermissionDashboard + { + return new PermissionDashboard(); + } + + /** + * Get The PermissionGlobalAction Class. + * + * @param Container $container The DI container. + * + * @return PermissionGlobalAction + * @since 3.2.0 + */ + public function getPermissionGlobalAction(Container $container): PermissionGlobalAction + { + return new PermissionGlobalAction(); + } + + /** + * Get The PermissionViews Class. + * + * @param Container $container The DI container. + * + * @return PermissionViews + * @since 3.2.0 + */ + public function getPermissionViews(Container $container): PermissionViews + { + return new PermissionViews(); + } + + /** + * Get The ScriptMediaSwitch Class. + * + * @param Container $container The DI container. + * + * @return ScriptMediaSwitch + * @since 3.2.0 + */ + public function getScriptMediaSwitch(Container $container): ScriptMediaSwitch + { + return new ScriptMediaSwitch(); + } + + /** + * Get The ScriptUserSwitch Class. + * + * @param Container $container The DI container. + * + * @return ScriptUserSwitch + * @since 3.2.0 + */ + public function getScriptUserSwitch(Container $container): ScriptUserSwitch + { + return new ScriptUserSwitch(); + } + + /** + * Get The Search Class. + * + * @param Container $container The DI container. + * + * @return Search + * @since 3.2.0 + */ + public function getSearch(Container $container): Search + { + return new Search(); + } + + /** + * Get The SelectionTranslation Class. + * + * @param Container $container The DI container. + * + * @return SelectionTranslation + * @since 3.2.0 + */ + public function getSelectionTranslation(Container $container): SelectionTranslation + { + return new SelectionTranslation(); + } + + /** + * Get The SiteDecrypt Class. + * + * @param Container $container The DI container. + * + * @return SiteDecrypt + * @since 3.2.0 + */ + public function getSiteDecrypt(Container $container): SiteDecrypt + { + return new SiteDecrypt(); + } + + /** + * Get The SiteDynamicGet Class. + * + * @param Container $container The DI container. + * + * @return SiteDynamicGet + * @since 3.2.0 + */ + public function getSiteDynamicGet(Container $container): SiteDynamicGet + { + return new SiteDynamicGet(); + } + + /** + * Get The SiteEditView Class. + * + * @param Container $container The DI container. + * + * @return SiteEditView + * @since 3.2.0 + */ + public function getSiteEditView(Container $container): SiteEditView + { + return new SiteEditView(); + } + + /** + * Get The SiteFieldData Class. + * + * @param Container $container The DI container. + * + * @return SiteFieldData + * @since 3.2.0 + */ + public function getSiteFieldData(Container $container): SiteFieldData + { + return new SiteFieldData(); + } + + /** + * Get The SiteFieldDecodeFilter Class. + * + * @param Container $container The DI container. + * + * @return SiteFieldDecodeFilter + * @since 3.2.0 + */ + public function getSiteFieldDecodeFilter(Container $container): SiteFieldDecodeFilter + { + return new SiteFieldDecodeFilter(); + } + + /** + * Get The SiteFields Class. + * + * @param Container $container The DI container. + * + * @return SiteFields + * @since 3.2.0 + */ + public function getSiteFields(Container $container): SiteFields + { + return new SiteFields(); + } + + /** + * Get The SiteMainGet Class. + * + * @param Container $container The DI container. + * + * @return SiteMainGet + * @since 3.2.0 + */ + public function getSiteMainGet(Container $container): SiteMainGet + { + return new SiteMainGet(); + } + + /** + * Get The Sort Class. + * + * @param Container $container The DI container. + * + * @return Sort + * @since 3.2.0 + */ + public function getSort(Container $container): Sort + { + return new Sort(); + } + + /** + * Get The TabCounter Class. + * + * @param Container $container The DI container. + * + * @return TabCounter + * @since 3.2.0 + */ + public function getTabCounter(Container $container): TabCounter + { + return new TabCounter(); + } + + /** + * Get The Tags Class. + * + * @param Container $container The DI container. + * + * @return Tags + * @since 3.2.0 + */ + public function getTags(Container $container): Tags + { + return new Tags(); + } + + /** + * Get The TemplateData Class. + * + * @param Container $container The DI container. + * + * @return TemplateData + * @since 3.2.0 + */ + public function getTemplateData(Container $container): TemplateData + { + return new TemplateData(); + } + + /** + * Get The Title Class. + * + * @param Container $container The DI container. + * + * @return Title + * @since 3.2.0 + */ + public function getTitle(Container $container): Title + { + return new Title(); + } + + /** + * Get The UikitComp Class. + * + * @param Container $container The DI container. + * + * @return UikitComp + * @since 3.2.0 + */ + public function getUikitComp(Container $container): UikitComp + { + return new UikitComp(); + } + + /** + * Get The UpdateMysql Class. + * + * @param Container $container The DI container. + * + * @return UpdateMysql + * @since 3.2.0 + */ + public function getUpdateMysql(Container $container): UpdateMysql + { + return new UpdateMysql(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Compiler.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Compiler.php new file mode 100644 index 000000000..479a2cc18 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Compiler.php @@ -0,0 +1,90 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Registry; +use VDM\Joomla\Componentbuilder\Table; + + +/** + * Compiler Service Provider + * + * @since 3.2.0 + */ +class Compiler implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Config::class, 'Config') + ->share('Config', [$this, 'getConfig'], true); + + $container->alias(Registry::class, 'Registry') + ->share('Registry', [$this, 'getRegistry'], true); + + $container->alias(Table::class, 'Table') + ->share('Table', [$this, 'getTable'], true); + } + + /** + * Get the Compiler Configurations + * + * @param Container $container The DI container. + * + * @return Config + * @since 3.2.0 + */ + public function getConfig(Container $container): Config + { + return new Config(); + } + + /** + * Get the Compiler Registry + * + * @param Container $container The DI container. + * + * @return Registry + * @since 3.2.0 + */ + public function getRegistry(Container $container): Registry + { + return new Registry(); + } + + /** + * Get the Table + * + * @param Container $container The DI container. + * + * @return Table + * @since 3.2.0 + */ + public function getTable(Container $container): Table + { + return new Table(); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Component.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Component.php new file mode 100644 index 000000000..b6e9b6759 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Component.php @@ -0,0 +1,232 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Component as CompilerComponent; +use VDM\Joomla\Componentbuilder\Compiler\Component\Settings; +use VDM\Joomla\Componentbuilder\Compiler\Component\Dashboard; +use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder; +use VDM\Joomla\Componentbuilder\Compiler\Component\Data; +use VDM\Joomla\Componentbuilder\Compiler\Component\Structure; +use VDM\Joomla\Componentbuilder\Compiler\Component\Structuresingle; +use VDM\Joomla\Componentbuilder\Compiler\Component\Structuremultiple; + + +/** + * Component Service Provider + * + * @since 3.2.0 + */ +class Component implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(CompilerComponent::class, 'Component') + ->share('Component', [$this, 'getComponent'], true); + + $container->alias(Settings::class, 'Component.Settings') + ->share('Component.Settings', [$this, 'getSettings'], true); + + $container->alias(Dashboard::class, 'Component.Dashboard') + ->share('Component.Dashboard', [$this, 'getDashboard'], true); + + $container->alias(Placeholder::class, 'Component.Placeholder') + ->share('Component.Placeholder', [$this, 'getPlaceholder'], true); + + $container->alias(Data::class, 'Component.Data') + ->share('Component.Data', [$this, 'getData'], true); + + $container->alias(Structure::class, 'Component.Structure') + ->share('Component.Structure', [$this, 'getStructure'], true); + + $container->alias(Structuresingle::class, 'Component.Structure.Single') + ->share('Component.Structure.Single', [$this, 'getStructuresingle'], true); + + $container->alias(Structuremultiple::class, 'Component.Structure.Multiple') + ->share('Component.Structure.Multiple', [$this, 'getStructuremultiple'], true); + } + + /** + * Get the Component + * + * @param Container $container The DI container. + * + * @return CompilerComponent + * @since 3.2.0 + */ + public function getComponent(Container $container): CompilerComponent + { + return new CompilerComponent( + $container->get('Component.Data') + ); + } + + /** + * Get the Compiler Component (version) Settings + * + * @param Container $container The DI container. + * + * @return Settings + * @since 3.2.0 + */ + public function getSettings(Container $container): Settings + { + return new Settings( + $container->get('Config'), + $container->get('Registry'), + $container->get('Event'), + $container->get('Placeholder'), + $container->get('Component'), + $container->get('Utilities.Paths'), + $container->get('Utilities.Dynamicpath'), + $container->get('Utilities.Pathfix') + ); + } + + /** + * Get the Compiler Component Dynamic Dashboard + * + * @param Container $container The DI container. + * + * @return Dashboard + * @since 3.2.0 + */ + public function getDashboard(Container $container): Dashboard + { + return new Dashboard( + $container->get('Registry'), + $container->get('Component') + ); + } + + /** + * Get the Component Placeholders + * + * @param Container $container The DI container. + * + * @return Placeholder + * @since 3.2.0 + */ + public function getPlaceholder(Container $container): Placeholder + { + return new Placeholder( + $container->get('Config') + ); + } + + /** + * Get the Component Data + * + * @param Container $container The DI container. + * + * @return Data + * @since 3.2.0 + */ + public function getData(Container $container): Data + { + return new Data( + $container->get('Config'), + $container->get('Event'), + $container->get('Placeholder'), + $container->get('Component.Placeholder'), + $container->get('Customcode.Dispenser'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Field'), + $container->get('Field.Name'), + $container->get('Field.Unique.Name'), + $container->get('Model.Filesfolders'), + $container->get('Model.Historycomponent'), + $container->get('Model.Whmcs'), + $container->get('Model.Sqltweaking'), + $container->get('Model.Adminviews'), + $container->get('Model.Siteviews'), + $container->get('Model.Customadminviews'), + $container->get('Model.Updateserver'), + $container->get('Model.Joomlamodules'), + $container->get('Model.Joomlaplugins') + ); + } + + /** + * Get the Compiler Structure + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getStructure(Container $container): Structure + { + return new Structure( + $container->get('Component.Settings'), + $container->get('Utilities.Paths'), + $container->get('Utilities.Folder') + ); + } + + /** + * Get the Compiler Structure Single + * + * @param Container $container The DI container. + * + * @return Structuresingle + * @since 3.2.0 + */ + public function getStructuresingle(Container $container): Structuresingle + { + return new Structuresingle( + $container->get('Config'), + $container->get('Registry'), + $container->get('Component.Settings'), + $container->get('Component'), + $container->get('Compiler.Builder.Content.One'), + $container->get('Utilities.Counter'), + $container->get('Utilities.Paths'), + $container->get('Utilities.Files') + ); + } + + /** + * Get the Compiler Structure Multiple + * + * @param Container $container The DI container. + * + * @return Structuremultiple + * @since 3.2.0 + */ + public function getStructuremultiple(Container $container): Structuremultiple + { + return new Structuremultiple( + $container->get('Config'), + $container->get('Registry'), + $container->get('Component.Settings'), + $container->get('Component'), + $container->get('Model.Createdate'), + $container->get('Model.Modifieddate'), + $container->get('Utilities.Structure') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Creator.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Creator.php new file mode 100644 index 000000000..67b743786 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Creator.php @@ -0,0 +1,435 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Builders; +use VDM\Joomla\Componentbuilder\Compiler\Creator\CustomFieldTypeFile; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Layout; +use VDM\Joomla\Componentbuilder\Compiler\Creator\Permission; +use VDM\Joomla\Componentbuilder\Compiler\Creator\SiteFieldData; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetString; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetXML; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetDynamic; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldXML; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldString; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldDynamic; +use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldAsString; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldtypeinterface as FieldType; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Creator\Fieldsetinterface as Fieldset; + + +/** + * Creator Service Provider + * + * @since 3.2.0 + */ +class Creator implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Builders::class, 'Compiler.Creator.Builders') + ->share('Compiler.Creator.Builders', [$this, 'getBuilders'], true); + + $container->alias(CustomFieldTypeFile::class, 'Compiler.Creator.Custom.Field.Type.File') + ->share('Compiler.Creator.Custom.Field.Type.File', [$this, 'getCustomFieldTypeFile'], true); + + $container->alias(Layout::class, 'Compiler.Creator.Layout') + ->share('Compiler.Creator.Layout', [$this, 'getLayout'], true); + + $container->alias(Permission::class, 'Compiler.Creator.Permission') + ->share('Compiler.Creator.Permission', [$this, 'getPermission'], true); + + $container->alias(SiteFieldData::class, 'Compiler.Creator.Site.Field.Data') + ->share('Compiler.Creator.Site.Field.Data', [$this, 'getSiteFieldData'], true); + + $container->alias(FieldsetString::class, 'Compiler.Creator.Fieldset.String') + ->share('Compiler.Creator.Fieldset.String', [$this, 'getFieldsetString'], true); + + $container->alias(FieldsetXML::class, 'Compiler.Creator.Fieldset.XML') + ->share('Compiler.Creator.Fieldset.XML', [$this, 'getFieldsetXML'], true); + + $container->alias(FieldsetDynamic::class, 'Compiler.Creator.Fieldset.Dynamic') + ->share('Compiler.Creator.Fieldset.Dynamic', [$this, 'getFieldsetDynamic'], true); + + $container->alias(FieldXML::class, 'Compiler.Creator.Field.XML') + ->share('Compiler.Creator.Field.XML', [$this, 'getFieldXML'], true); + + $container->alias(FieldString::class, 'Compiler.Creator.Field.String') + ->share('Compiler.Creator.Field.String', [$this, 'getFieldString'], true); + + $container->alias(FieldDynamic::class, 'Compiler.Creator.Field.Dynamic') + ->share('Compiler.Creator.Field.Dynamic', [$this, 'getFieldDynamic'], true); + + $container->alias(FieldAsString::class, 'Compiler.Creator.Field.As.String') + ->share('Compiler.Creator.Field.As.String', [$this, 'getFieldAsString'], true); + + $container->alias(FieldType::class, 'Compiler.Creator.Field.Type') + ->share('Compiler.Creator.Field.Type', [$this, 'getFieldType'], true); + + $container->alias(Fieldset::class, 'Compiler.Creator.Fieldset') + ->share('Compiler.Creator.Fieldset', [$this, 'getFieldset'], true); + } + + /** + * Get The Builders Class. + * + * @param Container $container The DI container. + * + * @return Builders + * @since 3.2.0 + */ + public function getBuilders(Container $container): Builders + { + return new Builders( + $container->get('Config'), + $container->get('Language'), + $container->get('Placeholder'), + $container->get('Compiler.Creator.Layout'), + $container->get('Compiler.Creator.Site.Field.Data'), + $container->get('Compiler.Builder.Tags'), + $container->get('Compiler.Builder.Database.Tables'), + $container->get('Compiler.Builder.Database.Unique.Keys'), + $container->get('Compiler.Builder.Database.Keys'), + $container->get('Compiler.Builder.Database.Unique.Guid'), + $container->get('Compiler.Builder.List.Join'), + $container->get('Compiler.Builder.History'), + $container->get('Compiler.Builder.Alias'), + $container->get('Compiler.Builder.Title'), + $container->get('Compiler.Builder.Category.Other.Name'), + $container->get('Compiler.Builder.Lists'), + $container->get('Compiler.Builder.Custom.List'), + $container->get('Compiler.Builder.Field.Relations'), + $container->get('Compiler.Builder.Hidden.Fields'), + $container->get('Compiler.Builder.Integer.Fields'), + $container->get('Compiler.Builder.Dynamic.Fields'), + $container->get('Compiler.Builder.Main.Text.Field'), + $container->get('Compiler.Builder.Custom.Field'), + $container->get('Compiler.Builder.Custom.Field.Links'), + $container->get('Compiler.Builder.Script.User.Switch'), + $container->get('Compiler.Builder.Script.Media.Switch'), + $container->get('Compiler.Builder.Category'), + $container->get('Compiler.Builder.Category.Code'), + $container->get('Compiler.Builder.Check.Box'), + $container->get('Compiler.Builder.Json.String'), + $container->get('Compiler.Builder.Base.Six.Four'), + $container->get('Compiler.Builder.Model.Basic.Field'), + $container->get('Compiler.Builder.Model.Whmcs.Field'), + $container->get('Compiler.Builder.Model.Medium.Field'), + $container->get('Compiler.Builder.Model.Expert.Field.Initiator'), + $container->get('Compiler.Builder.Model.Expert.Field'), + $container->get('Compiler.Builder.Json.Item'), + $container->get('Compiler.Builder.Items.Method.List.String'), + $container->get('Compiler.Builder.Json.Item.Array'), + $container->get('Compiler.Builder.Items.Method.Eximport.String'), + $container->get('Compiler.Builder.Selection.Translation'), + $container->get('Compiler.Builder.Admin.Filter.Type'), + $container->get('Compiler.Builder.Sort'), + $container->get('Compiler.Builder.Search'), + $container->get('Compiler.Builder.Filter'), + $container->get('Compiler.Builder.Component.Fields') + ); + } + + /** + * Get The CustomFieldTypeFile Class. + * + * @param Container $container The DI container. + * + * @return CustomFieldTypeFile + * @since 3.2.0 + */ + public function getCustomFieldTypeFile(Container $container): CustomFieldTypeFile + { + return new CustomFieldTypeFile( + $container->get('Config'), + $container->get('Compiler.Builder.Content.One'), + $container->get('Compiler.Builder.Content.Multi'), + $container->get('Compiler.Builder.Site.Field.Data'), + $container->get('Placeholder'), + $container->get('Language'), + $container->get('Component.Placeholder'), + $container->get('Utilities.Structure'), + $container->get('Field.Input.Button'), + $container->get('Compiler.Builder.Field.Group.Control'), + $container->get('Compiler.Builder.Extension.Custom.Fields') + ); + } + + /** + * Get The Layout Class. + * + * @param Container $container The DI container. + * + * @return Layout + * @since 3.2.0 + */ + public function getLayout(Container $container): Layout + { + return new Layout( + $container->get('Config'), + $container->get('Compiler.Builder.Order.Zero'), + $container->get('Compiler.Builder.Tab.Counter'), + $container->get('Compiler.Builder.Layout'), + $container->get('Compiler.Builder.Moved.Publishing.Fields'), + $container->get('Compiler.Builder.New.Publishing.Fields') + ); + } + + /** + * Get The Permission Class. + * + * @param Container $container The DI container. + * + * @return Permission + * @since 3.2.0 + */ + public function getPermission(Container $container): Permission + { + return new Permission( + $container->get('Config'), + $container->get('Compiler.Builder.Permission.Core'), + $container->get('Compiler.Builder.Permission.Views'), + $container->get('Compiler.Builder.Permission.Action'), + $container->get('Compiler.Builder.Permission.Component'), + $container->get('Compiler.Builder.Permission.Global.Action'), + $container->get('Compiler.Builder.Permission.Dashboard'), + $container->get('Utilities.Counter'), + $container->get('Language') + ); + } + + /** + * Get The SiteFieldData Class. + * + * @param Container $container The DI container. + * + * @return SiteFieldData + * @since 3.2.0 + */ + public function getSiteFieldData(Container $container): SiteFieldData + { + return new SiteFieldData( + $container->get('Config'), + $container->get('Compiler.Builder.Site.Fields'), + $container->get('Compiler.Builder.Site.Field.Data') + ); + } + + /** + * Get The FieldsetString Class. + * + * @param Container $container The DI container. + * + * @return FieldsetString + * @since 3.2.0 + */ + public function getFieldsetString(Container $container): FieldsetString + { + return new FieldsetString( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Language.Fieldset'), + $container->get('Event'), + $container->get('Adminview.Permission'), + $container->get('Compiler.Creator.Field.Dynamic'), + $container->get('Compiler.Builder.Field.Names'), + $container->get('Compiler.Builder.Access.Switch'), + $container->get('Compiler.Builder.Meta.Data'), + $container->get('Compiler.Creator.Layout'), + $container->get('Utilities.Counter') + ); + } + + /** + * Get The FieldsetXML Class. + * + * @param Container $container The DI container. + * + * @return FieldsetXML + * @since 3.2.0 + */ + public function getFieldsetXML(Container $container): FieldsetXML + { + return new FieldsetXML( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Language.Fieldset'), + $container->get('Event'), + $container->get('Adminview.Permission'), + $container->get('Compiler.Creator.Field.Dynamic'), + $container->get('Compiler.Builder.Field.Names'), + $container->get('Compiler.Builder.Access.Switch'), + $container->get('Compiler.Builder.Meta.Data'), + $container->get('Compiler.Creator.Layout'), + $container->get('Utilities.Counter'), + $container->get('Utilities.Xml') + ); + } + + /** + * Get The FieldsetDynamic Class. + * + * @param Container $container The DI container. + * + * @return FieldsetDynamic + * @since 3.2.0 + */ + public function getFieldsetDynamic(Container $container): FieldsetDynamic + { + return new FieldsetDynamic( + $container->get('Compiler.Creator.Field.As.String') + ); + } + + /** + * Get The FieldXML Class. + * + * @param Container $container The DI container. + * + * @return FieldXML + * @since 3.2.0 + */ + public function getFieldXML(Container $container): FieldXML + { + return new FieldXML( + $container->get('Config'), + $container->get('Language'), + $container->get('Field'), + $container->get('Field.Groups'), + $container->get('Field.Name'), + $container->get('Field.Type.Name'), + $container->get('Field.Attributes'), + $container->get('Utilities.Xml'), + $container->get('Compiler.Creator.Custom.Field.Type.File'), + $container->get('Utilities.Counter') + ); + } + + /** + * Get The FieldString Class. + * + * @param Container $container The DI container. + * + * @return FieldString + * @since 3.2.0 + */ + public function getFieldString(Container $container): FieldString + { + return new FieldString( + $container->get('Config'), + $container->get('Language'), + $container->get('Field'), + $container->get('Field.Groups'), + $container->get('Field.Name'), + $container->get('Field.Type.Name'), + $container->get('Field.Attributes'), + $container->get('Compiler.Creator.Custom.Field.Type.File'), + $container->get('Utilities.Counter') + ); + } + + /** + * Get The FieldDynamic Class. + * + * @param Container $container The DI container. + * + * @return FieldDynamic + * @since 3.2.0 + */ + public function getFieldDynamic(Container $container): FieldDynamic + { + return new FieldDynamic( + $container->get('Field.Name'), + $container->get('Field.Type.Name'), + $container->get('Field.Attributes'), + $container->get('Field.Groups'), + $container->get('Compiler.Builder.Field.Names'), + $container->get('Compiler.Creator.Field.Type'), + $container->get('Compiler.Creator.Builders'), + $container->get('Compiler.Creator.Layout') + ); + } + + /** + * Get The FieldAsString Class. + * + * @param Container $container The DI container. + * + * @return FieldAsString + * @since 3.2.0 + */ + public function getFieldAsString(Container $container): FieldAsString + { + return new FieldAsString( + $container->get('Compiler.Creator.Field.Dynamic'), + $container->get('Utilities.Xml') + ); + } + + /** + * Get The Fieldtypeinterface Class. + * + * @param Container $container The DI container. + * + * @return FieldType + * @since 3.2.0 + */ + public function getFieldType(Container $container): FieldType + { + // check what type of field builder to use + if ($container->get('Config')->get('field_builder_type', 2) == 1) + { + // build field set using string manipulation + return $container->get('Compiler.Creator.Field.String'); + } + else + { + // build field set with simpleXMLElement class + return $container->get('Compiler.Creator.Field.XML'); + } + } + + /** + * Get The Fieldsetinterface Class. + * + * @param Container $container The DI container. + * + * @return Fieldset + * @since 3.2.0 + */ + public function getFieldset(Container $container): Fieldset + { + // check what type of field builder to use + if ($container->get('Config')->get('field_builder_type', 2) == 1) + { + // build field set using string manipulation + return $container->get('Compiler.Creator.Fieldset.String'); + } + else + { + // build field set with simpleXMLElement class + return $container->get('Compiler.Creator.Fieldset.XML'); + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php new file mode 100644 index 000000000..f33011fb6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php @@ -0,0 +1,209 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Customcode as CompilerCustomcode; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\CustomcodeInterface; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\External; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Hash; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\LockBase; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Customcode\Extractor\Paths; + + +/** + * Compiler Custom Code Service Provider + * + * @since 3.2.0 + */ +class Customcode implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(CompilerCustomcode::class, 'Customcode') + ->share('Customcode', [$this, 'getCustomcode'], true); + + $container->alias(External::class, 'Customcode.External') + ->share('Customcode.External', [$this, 'getExternal'], true); + + $container->alias(Gui::class, 'Customcode.Gui') + ->share('Customcode.Gui', [$this, 'getGui'], true); + + $container->alias(Hash::class, 'Customcode.Hash') + ->share('Customcode.Hash', [$this, 'getHash'], true); + + $container->alias(LockBase::class, 'Customcode.LockBase') + ->share('Customcode.LockBase', [$this, 'getLockBase'], true); + + $container->alias(Dispenser::class, 'Customcode.Dispenser') + ->share('Customcode.Dispenser', [$this, 'getDispenser'], true); + + $container->alias(Paths::class, 'Customcode.Extractor.Paths') + ->share('Customcode.Extractor.Paths', [$this, 'getPaths'], true); + + $container->alias(Extractor::class, 'Customcode.Extractor') + ->share('Customcode.Extractor', [$this, 'getExtractor'], true); + } + + /** + * Get the Compiler Customcode + * + * @param Container $container The DI container. + * + * @return CustomcodeInterface + * @since 3.2.0 + */ + public function getCustomcode(Container $container): CustomcodeInterface + { + return new CompilerCustomcode( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Language.Extractor'), + $container->get('Power.Extractor'), + $container->get('Customcode.External') + ); + } + + /** + * Get the Compiler Customcode External + * + * @param Container $container The DI container. + * + * @return External + * @since 3.2.0 + */ + public function getExternal(Container $container): External + { + return new External( + $container->get('Placeholder') + ); + } + + /** + * Get the Compiler Customcode Gui + * + * @param Container $container The DI container. + * + * @return Gui + * @since 3.2.0 + */ + public function getGui(Container $container): Gui + { + return new Gui( + $container->get('Config'), + $container->get('Placeholder.Reverse') + ); + } + + /** + * Get the Customcode Hash + * + * @param Container $container The DI container. + * + * @return Hash + * @since 3.2.0 + */ + public function getHash(Container $container): Hash + { + return new Hash( + $container->get('Placeholder') + ); + } + + /** + * Get the Customcode LockBase64 + * + * @param Container $container The DI container. + * + * @return LockBase + * @since 3.2.0 + */ + public function getLockBase(Container $container): LockBase + { + return new LockBase( + $container->get('Placeholder') + ); + } + + /** + * Get the Customcode Dispenser + * + * @param Container $container The DI container. + * + * @return Dispenser + * @since 3.2.0 + */ + public function getDispenser(Container $container): Dispenser + { + return new Dispenser( + $container->get('Placeholder'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Customcode.Hash'), + $container->get('Customcode.LockBase') + ); + } + + /** + * Get the Customcode Extractor Paths + * + * @param Container $container The DI container. + * + * @return Paths + * @since 3.2.0 + */ + public function getPaths(Container $container): Paths + { + return new Paths( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Component.Placeholder'), + $container->get('Customcode'), + $container->get('Language.Extractor') + ); + } + + /** + * Get the Customcode Extractor + * + * @param Container $container The DI container. + * + * @return Extractor + * @since 3.2.0 + */ + public function getExtractor(Container $container): Extractor + { + return new Extractor( + $container->get('Config'), + $container->get('Customcode.Gui'), + $container->get('Customcode.Extractor.Paths'), + $container->get('Placeholder.Reverse'), + $container->get('Component.Placeholder'), + $container->get('Utilities.Pathfix') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customview.php new file mode 100644 index 000000000..349b31f2d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customview.php @@ -0,0 +1,114 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Customview\Data as CustomviewData; +use VDM\Joomla\Componentbuilder\Compiler\Dynamicget\Data as DynamicgetData; +use VDM\Joomla\Componentbuilder\Compiler\Dynamicget\Selection as DynamicgetSelection; + + +/** + * Compiler Customview + * + * @since 3.2.0 + */ +class Customview implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(CustomviewData::class, 'Customview.Data') + ->share('Customview.Data', [$this, 'getCustomviewData'], true); + + $container->alias(DynamicgetData::class, 'Dynamicget.Data') + ->share('Dynamicget.Data', [$this, 'getDynamicgetData'], true); + + $container->alias(DynamicgetSelection::class, 'Dynamicget.Selection') + ->share('Dynamicget.Selection', [$this, 'getDynamicgetSelection'], true); + } + + /** + * Get the Compiler Customview Data + * + * @param Container $container The DI container. + * + * @return CustomviewData + * @since 3.2.0 + */ + public function getCustomviewData(Container $container): CustomviewData + { + return new CustomviewData( + $container->get('Config'), + $container->get('Event'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Model.Libraries'), + $container->get('Templatelayout.Data'), + $container->get('Dynamicget.Data'), + $container->get('Model.Loader'), + $container->get('Model.Javascriptcustomview'), + $container->get('Model.Csscustomview'), + $container->get('Model.Phpcustomview'), + $container->get('Model.Ajaxcustomview'), + $container->get('Model.Custombuttons') + ); + } + + /** + * Get the Compiler Dynamicget Data + * + * @param Container $container The DI container. + * + * @return DynamicgetData + * @since 3.2.0 + */ + public function getDynamicgetData(Container $container): DynamicgetData + { + return new DynamicgetData( + $container->get('Config'), + $container->get('Registry'), + $container->get('Event'), + $container->get('Customcode'), + $container->get('Customcode.Dispenser'), + $container->get('Customcode.Gui'), + $container->get('Model.Dynamicget') + ); + } + + /** + * Get the Compiler Dynamicget Selection + * + * @param Container $container The DI container. + * + * @return DynamicgetSelection + * @since 3.2.0 + */ + public function getDynamicgetSelection(Container $container): DynamicgetSelection + { + return new DynamicgetSelection( + $container->get('Config'), + $container->get('Compiler.Builder.Get.As.Lookup'), + $container->get('Compiler.Builder.Site.Fields') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Event.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Event.php new file mode 100644 index 000000000..091f7c2ea --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Event.php @@ -0,0 +1,86 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use Joomla\CMS\Version; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; +use VDM\Joomla\Componentbuilder\Compiler\JoomlaThree\Event as J3Event; + + +/** + * Event Service Provider + * + * @since 3.2.0 + */ +class Event implements ServiceProviderInterface +{ + /** + * Current Joomla Version We are IN + * + * @var int + * @since 3.2.0 + **/ + protected $currentVersion; + + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(J3Event::class, 'J3.Event') + ->share('J3.Event', [$this, 'getJ3Event'], true); + + $container->alias(EventInterface::class, 'Event') + ->share('Event', [$this, 'getEvent'], true); + } + + /** + * Get the Event + * + * @param Container $container The DI container. + * + * @return EventInterface + * @since 3.2.0 + */ + public function getEvent(Container $container): EventInterface + { + if (empty($this->currentVersion)) + { + $this->currentVersion = Version::MAJOR_VERSION; + } + + return $container->get('J' . $this->currentVersion . '.Event'); + } + + /** + * Get the Joomla 3 Event + * + * @param Container $container The DI container. + * + * @return J3Event + * @since 3.2.0 + */ + public function getJ3Event(Container $container): J3Event + { + return new J3Event(); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Extension.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Extension.php new file mode 100644 index 000000000..50d751bae --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Extension.php @@ -0,0 +1,85 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\GetScriptInterface; +use VDM\Joomla\Componentbuilder\Compiler\Extension\JoomlaThree\InstallScript as J3InstallScript; + + +/** + * Extension Script Service Provider + * + * @since 3.2.0 + */ +class Extension implements ServiceProviderInterface +{ + /** + * Current Joomla Version Being Build + * + * @var int + * @since 3.2.0 + **/ + protected $targetVersion; + + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(GetScriptInterface::class, 'Extension.InstallScript') + ->share('Extension.InstallScript', [$this, 'getExtensionInstallScript'], true); + + $container->alias(J3InstallScript::class, 'J3.Extension.InstallScript') + ->share('J3.Extension.InstallScript', [$this, 'getJ3ExtensionInstallScript'], true); + } + + /** + * Get the Joomla 3 Extension Install Script + * + * @param Container $container The DI container. + * + * @return J3InstallScript + * @since 3.2.0 + */ + public function getJ3ExtensionInstallScript(Container $container): J3InstallScript + { + return new J3InstallScript(); + } + + /** + * Get the Joomla Extension Install Script + * + * @param Container $container The DI container. + * + * @return GetScriptInterface + * @since 3.2.0 + */ + public function getExtensionInstallScript(Container $container): GetScriptInterface + { + if (empty($this->targetVersion)) + { + $this->targetVersion = $container->get('Config')->joomla_version; + } + + return $container->get('J' . $this->targetVersion . '.Extension.InstallScript'); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Field.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Field.php new file mode 100644 index 000000000..e3ba24db5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Field.php @@ -0,0 +1,314 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Field as CompilerField; +use VDM\Joomla\Componentbuilder\Compiler\Field\Data; +use VDM\Joomla\Componentbuilder\Compiler\Field\Groups; +use VDM\Joomla\Componentbuilder\Compiler\Field\Attributes; +use VDM\Joomla\Componentbuilder\Compiler\Field\Name; +use VDM\Joomla\Componentbuilder\Compiler\Field\TypeName; +use VDM\Joomla\Componentbuilder\Compiler\Field\UniqueName; +use VDM\Joomla\Componentbuilder\Compiler\Field\Validation; +use VDM\Joomla\Componentbuilder\Compiler\Field\Customcode; +use VDM\Joomla\Componentbuilder\Compiler\Field\DatabaseName; +use VDM\Joomla\Componentbuilder\Compiler\Field\InputButton; +use VDM\Joomla\Componentbuilder\Compiler\Field\JoomlaThree\CoreValidation as J3CoreValidation; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Field\CoreValidationInterface; + + +/** + * Compiler Field + * + * @since 3.2.0 + */ +class Field implements ServiceProviderInterface +{ + /** + * Current Joomla Version Being Build + * + * @var int + * @since 3.2.0 + **/ + protected $targetVersion; + + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(CompilerField::class, 'Field') + ->share('Field', [$this, 'getField'], true); + + $container->alias(Data::class, 'Field.Data') + ->share('Field.Data', [$this, 'getData'], true); + + $container->alias(Groups::class, 'Field.Groups') + ->share('Field.Groups', [$this, 'getGroups'], true); + + $container->alias(Attributes::class, 'Field.Attributes') + ->share('Field.Attributes', [$this, 'getAttributes'], true); + + $container->alias(Validation::class, 'Field.Validation') + ->share('Field.Validation', [$this, 'getValidation'], true); + + $container->alias(J3CoreValidation::class, 'J3.Field.Core.Validation') + ->share('J3.Field.Core.Validation', [$this, 'getJ3CoreValidation'], true); + + $container->alias(CoreValidationInterface::class, 'Field.Core.Validation') + ->share('Field.Core.Validation', [$this, 'getCoreValidation'], true); + + $container->alias(Customcode::class, 'Field.Customcode') + ->share('Field.Customcode', [$this, 'getCustomcode'], true); + + $container->alias(Name::class, 'Field.Name') + ->share('Field.Name', [$this, 'getFieldName'], true); + + $container->alias(TypeName::class, 'Field.Type.Name') + ->share('Field.Type.Name', [$this, 'getFieldTypeName'], true); + + $container->alias(UniqueName::class, 'Field.Unique.Name') + ->share('Field.Unique.Name', [$this, 'getFieldUniqueName'], true); + + $container->alias(DatabaseName::class, 'Field.Database.Name') + ->share('Field.Database.Name', [$this, 'getFieldDatabaseName'], true); + + $container->alias(InputButton::class, 'Field.Input.Button') + ->share('Field.Input.Button', [$this, 'getInputButton'], true); + } + + /** + * Get the Compiler Field + * + * @param Container $container The DI container. + * + * @return CompilerField + * @since 3.2.0 + */ + public function getField(Container $container): CompilerField + { + return new CompilerField( + $container->get('Field.Data'), + $container->get('Field.Name'), + $container->get('Field.Type.Name'), + $container->get('Field.Unique.Name') + ); + } + + /** + * Get the Compiler Field Data + * + * @param Container $container The DI container. + * + * @return Data + * @since 3.2.0 + */ + public function getData(Container $container): Data + { + return new Data( + $container->get('Config'), + $container->get('Event'), + $container->get('History'), + $container->get('Placeholder'), + $container->get('Customcode'), + $container->get('Field.Customcode'), + $container->get('Field.Validation') + ); + } + + /** + * Get the Compiler Field Groups + * + * @param Container $container The DI container. + * + * @return Groups + * @since 3.2.0 + */ + public function getGroups(Container $container): Groups + { + return new Groups(); + } + + /** + * Get the Compiler Field Attributes + * + * @param Container $container The DI container. + * + * @return Attributes + * @since 3.2.0 + */ + public function getAttributes(Container $container): Attributes + { + return new Attributes( + $container->get('Config'), + $container->get('Registry'), + $container->get('Compiler.Builder.List.Field.Class'), + $container->get('Compiler.Builder.Do.Not.Escape'), + $container->get('Placeholder'), + $container->get('Customcode'), + $container->get('Language'), + $container->get('Field.Groups') + ); + } + + /** + * Get the Compiler Field Validation + * + * @param Container $container The DI container. + * + * @return Validation + * @since 3.2.0 + */ + public function getValidation(Container $container): Validation + { + return new Validation( + $container->get('Registry'), + $container->get('Customcode.Gui'), + $container->get('Placeholder'), + $container->get('Customcode'), + $container->get('Field.Core.Validation') + ); + } + + /** + * Get the Compiler Field Joomla 3 Validation + * + * @param Container $container The DI container. + * + * @return J3CoreValidation + * @since 3.2.0 + */ + public function getJ3CoreValidation(Container $container): J3CoreValidation + { + return new J3CoreValidation(); + } + + /** + * Get the Compiler Field Core Validation + * + * @param Container $container The DI container. + * + * @return CoreValidationInterface + * @since 3.2.0 + */ + public function getCoreValidation(Container $container): CoreValidationInterface + { + if (empty($this->targetVersion)) + { + $this->targetVersion = $container->get('Config')->joomla_version; + } + + return $container->get('J' . $this->targetVersion . '.Field.Core.Validation'); + } + + /** + * Get the Compiler Field Customcode + * + * @param Container $container The DI container. + * + * @return Customcode + * @since 3.2.0 + */ + public function getCustomcode(Container $container): Customcode + { + return new Customcode( + $container->get('Customcode.Dispenser') + ); + } + + /** + * Get the Compiler Field Name + * + * @param Container $container The DI container. + * + * @return Name + * @since 3.2.0 + */ + public function getFieldName(Container $container): Name + { + return new Name( + $container->get('Placeholder'), + $container->get('Field.Unique.Name'), + $container->get('Compiler.Builder.Category.Other.Name') + ); + } + + /** + * Get the Compiler Field Type Name + * + * @param Container $container The DI container. + * + * @return TypeName + * @since 3.2.0 + */ + public function getFieldTypeName(Container $container): TypeName + { + return new TypeName(); + } + + /** + * Get the Compiler Field Unique Name + * + * @param Container $container The DI container. + * + * @return UniqueName + * @since 3.2.0 + */ + public function getFieldUniqueName(Container $container): UniqueName + { + return new UniqueName( + $container->get('Registry') + ); + } + + /** + * Get the Compiler Field Database Name + * + * @param Container $container The DI container. + * + * @return DatabaseName + * @since 3.2.0 + */ + public function getFieldDatabaseName(Container $container): DatabaseName + { + return new DatabaseName( + $container->get('Compiler.Builder.Lists'), + $container->get('Registry') + ); + } + + /** + * Get The InputButton Class. + * + * @param Container $container The DI container. + * + * @return InputButton + * @since 3.2.0 + */ + public function getInputButton(Container $container): InputButton + { + return new InputButton( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Compiler.Creator.Permission') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/History.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/History.php new file mode 100644 index 000000000..7b3a67d4e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/History.php @@ -0,0 +1,88 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use Joomla\CMS\Version; +use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HistoryInterface; +use VDM\Joomla\Componentbuilder\Compiler\JoomlaThree\History as J3History; + + +/** + * History Service Provider + * + * @since 3.2.0 + */ +class History implements ServiceProviderInterface +{ + /** + * Current Joomla Version We are IN + * + * @var int + * @since 3.2.0 + **/ + protected $currentVersion; + + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(J3History::class, 'J3.History') + ->share('J3.History', [$this, 'getJ3History'], true); + + $container->alias(HistoryInterface::class, 'History') + ->share('History', [$this, 'getHistory'], true); + } + + /** + * Get the History + * + * @param Container $container The DI container. + * + * @return HistoryInterface + * @since 3.2.0 + */ + public function getHistory(Container $container): HistoryInterface + { + if (empty($this->currentVersion)) + { + $this->currentVersion = Version::MAJOR_VERSION; + } + + return $container->get('J' . $this->currentVersion . '.History'); + } + + /** + * Get the Joomla 3 History + * + * @param Container $container The DI container. + * + * @return J3History + * @since 3.2.0 + */ + public function getJ3History(Container $container): J3History + { + return new J3History( + $container->get('Config') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Joomlamodule.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Joomlamodule.php new file mode 100644 index 000000000..1aaccae64 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Joomlamodule.php @@ -0,0 +1,95 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Joomlamodule\Data; +use VDM\Joomla\Componentbuilder\Compiler\Joomlamodule\Structure; + + +/** + * Joomla Module Service Provider + * + * @since 3.2.0 + */ +class Joomlamodule implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Data::class, 'Joomlamodule.Data') + ->share('Joomlamodule.Data', [$this, 'getData'], true); + + $container->alias(Structure::class, 'Joomlamodule.Structure') + ->share('Joomlamodule.Structure', [$this, 'getStructure'], true); + } + + /** + * Get The Data Class. + * + * @param Container $container The DI container. + * + * @return Data + * @since 3.2.0 + */ + public function getData(Container $container): Data + { + return new Data( + $container->get('Config'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Placeholder'), + $container->get('Language'), + $container->get('Field'), + $container->get('Field.Name'), + $container->get('Model.Filesfolders'), + $container->get('Model.Libraries'), + $container->get('Dynamicget.Data'), + $container->get('Templatelayout.Data') + ); + } + + /** + * Get The Structure Class. + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getStructure(Container $container): Structure + { + return new Structure( + $container->get('Joomlamodule.Data'), + $container->get('Component'), + $container->get('Config'), + $container->get('Registry'), + $container->get('Customcode.Dispenser'), + $container->get('Event'), + $container->get('Utilities.Counter'), + $container->get('Utilities.Folder'), + $container->get('Utilities.File'), + $container->get('Utilities.Files'), + $container->get('Compiler.Builder.Template.Data') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Joomlaplugin.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Joomlaplugin.php new file mode 100644 index 000000000..a8343f1c3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Joomlaplugin.php @@ -0,0 +1,92 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Data; +use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Structure; + + +/** + * Joomla Plugin Service Provider + * + * @since 3.2.0 + */ +class Joomlaplugin implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Data::class, 'Joomlaplugin.Data') + ->share('Joomlaplugin.Data', [$this, 'getData'], true); + + $container->alias(Structure::class, 'Joomlaplugin.Structure') + ->share('Joomlaplugin.Structure', [$this, 'getStructure'], true); + } + + /** + * Get the Joomla Plugin Data + * + * @param Container $container The DI container. + * + * @return Data + * @since 3.2.0 + */ + public function getData(Container $container): Data + { + return new Data( + $container->get('Config'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Placeholder'), + $container->get('Language'), + $container->get('Field'), + $container->get('Field.Name'), + $container->get('Model.Filesfolders') + ); + } + + /** + * Get the Joomla Plugin Structure Builder + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getStructure(Container $container): Structure + { + return new Structure( + $container->get('Joomlaplugin.Data'), + $container->get('Component'), + $container->get('Config'), + $container->get('Registry'), + $container->get('Customcode.Dispenser'), + $container->get('Event'), + $container->get('Utilities.Counter'), + $container->get('Utilities.Folder'), + $container->get('Utilities.File'), + $container->get('Utilities.Files') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Language.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Language.php new file mode 100644 index 000000000..0fc4e7eab --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Language.php @@ -0,0 +1,99 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Language as CompilerLanguage; +use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Language\Fieldset; + + +/** + * Compiler Language Service Provider + * + * @since 3.2.0 + */ +class Language implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(CompilerLanguage::class, 'Language') + ->share('Language', [$this, 'getCompilerLanguage'], true); + + $container->alias(Extractor::class, 'Language.Extractor') + ->share('Language.Extractor', [$this, 'getExtractor'], true); + + $container->alias(Fieldset::class, 'Language.Fieldset') + ->share('Language.Fieldset', [$this, 'getFieldset'], true); + } + + /** + * Get The Language Class. + * + * @param Container $container The DI container. + * + * @return CompilerLanguage + * @since 3.2.0 + */ + public function getCompilerLanguage(Container $container): CompilerLanguage + { + return new CompilerLanguage( + $container->get('Config') + ); + } + + /** + * Get The Extractor Class. + * + * @param Container $container The DI container. + * + * @return Extractor + * @since 3.2.0 + */ + public function getExtractor(Container $container): Extractor + { + return new Extractor( + $container->get('Config'), + $container->get('Language'), + $container->get('Placeholder') + ); + } + + /** + * Get The Fieldset Class. + * + * @param Container $container The DI container. + * + * @return Fieldset + * @since 3.2.0 + */ + public function getFieldset(Container $container): Fieldset + { + return new Fieldset( + $container->get('Language'), + $container->get('Compiler.Builder.Meta.Data'), + $container->get('Compiler.Builder.Access.Switch'), + $container->get('Compiler.Builder.Access.Switch.List') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Library.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Library.php new file mode 100644 index 000000000..31824f643 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Library.php @@ -0,0 +1,89 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Library\Data; +use VDM\Joomla\Componentbuilder\Compiler\Library\Structure; + + +/** + * Compiler Library + * + * @since 3.2.0 + */ +class Library implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Data::class, 'Library.Data') + ->share('Library.Data', [$this, 'getData'], true); + + $container->alias(Structure::class, 'Library.Structure') + ->share('Library.Structure', [$this, 'getStructure'], true); + } + + /** + * Get the Compiler Library Data + * + * @param Container $container The DI container. + * + * @return Data + * @since 3.2.0 + */ + public function getData(Container $container): Data + { + return new Data( + $container->get('Config'), + $container->get('Registry'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Field.Data'), + $container->get('Model.Filesfolders') + ); + } + + /** + * Get the Compiler Library Structure Builder + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getStructure(Container $container): Structure + { + return new Structure( + $container->get('Config'), + $container->get('Registry'), + $container->get('Event'), + $container->get('Component'), + $container->get('Compiler.Builder.Content.One'), + $container->get('Utilities.Counter'), + $container->get('Utilities.Paths'), + $container->get('Utilities.Folder'), + $container->get('Utilities.File') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php new file mode 100644 index 000000000..fe9caea63 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php @@ -0,0 +1,817 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Server\Model\Load as ServerLoad; +use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlaplugins; +use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlamodules; +use VDM\Joomla\Componentbuilder\Compiler\Model\Historycomponent; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customadminviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Ajaxcustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Javascriptcustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Csscustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Phpcustomview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Dynamicget; +use VDM\Joomla\Componentbuilder\Compiler\Model\Libraries; +use VDM\Joomla\Componentbuilder\Compiler\Model\Siteviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Permissions; +use VDM\Joomla\Componentbuilder\Compiler\Model\Historyadminview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Mysqlsettings; +use VDM\Joomla\Componentbuilder\Compiler\Model\Sql; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customalias; +use VDM\Joomla\Componentbuilder\Compiler\Model\Ajaxadmin; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customimportscripts; +use VDM\Joomla\Componentbuilder\Compiler\Model\Custombuttons; +use VDM\Joomla\Componentbuilder\Compiler\Model\Loader; +use VDM\Joomla\Componentbuilder\Compiler\Model\Phpadminview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Cssadminview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Javascriptadminview; +use VDM\Joomla\Componentbuilder\Compiler\Model\Linkedviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Relations; +use VDM\Joomla\Componentbuilder\Compiler\Model\Conditions; +use VDM\Joomla\Componentbuilder\Compiler\Model\Fields; +use VDM\Joomla\Componentbuilder\Compiler\Model\Updatesql; +use VDM\Joomla\Componentbuilder\Compiler\Model\Tabs; +use VDM\Joomla\Componentbuilder\Compiler\Model\Customtabs; +use VDM\Joomla\Componentbuilder\Compiler\Model\Adminviews; +use VDM\Joomla\Componentbuilder\Compiler\Model\Sqltweaking; +use VDM\Joomla\Componentbuilder\Compiler\Model\Sqldump; +use VDM\Joomla\Componentbuilder\Compiler\Model\Whmcs; +use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders; +use VDM\Joomla\Componentbuilder\Compiler\Model\Modifieddate; +use VDM\Joomla\Componentbuilder\Compiler\Model\Createdate; +use VDM\Joomla\Componentbuilder\Compiler\Model\Updateserver; + + +/** + * Model Service Provider + * + * @since 3.2.0 + */ +class Model implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Joomlaplugins::class, 'Model.Joomlaplugins') + ->share('Model.Joomlaplugins', [$this, 'getModelJoomlaplugins'], true); + + $container->alias(Joomlamodules::class, 'Model.Joomlamodules') + ->share('Model.Joomlamodules', [$this, 'getModelJoomlamodules'], true); + + $container->alias(Historycomponent::class, 'Model.Historycomponent') + ->share('Model.Historycomponent', [$this, 'getModelHistorycomponent'], true); + + $container->alias(Customadminviews::class, 'Model.Customadminviews') + ->share('Model.Customadminviews', [$this, 'getModelCustomadminviews'], true); + + $container->alias(Ajaxcustomview::class, 'Model.Ajaxcustomview') + ->share('Model.Ajaxcustomview', [$this, 'getModelAjaxcustomview'], true); + + $container->alias(Javascriptcustomview::class, 'Model.Javascriptcustomview') + ->share('Model.Javascriptcustomview', [$this, 'getModelJavascriptcustomview'], true); + + $container->alias(Csscustomview::class, 'Model.Csscustomview') + ->share('Model.Csscustomview', [$this, 'getModelCsscustomview'], true); + + $container->alias(Phpcustomview::class, 'Model.Phpcustomview') + ->share('Model.Phpcustomview', [$this, 'getModelPhpcustomview'], true); + + $container->alias(Dynamicget::class, 'Model.Dynamicget') + ->share('Model.Dynamicget', [$this, 'getModelDynamicget'], true); + + $container->alias(Libraries::class, 'Model.Libraries') + ->share('Model.Libraries', [$this, 'getModelLibraries'], true); + + $container->alias(Siteviews::class, 'Model.Siteviews') + ->share('Model.Siteviews', [$this, 'getModelSiteviews'], true); + + $container->alias(Permissions::class, 'Model.Permissions') + ->share('Model.Permissions', [$this, 'getModelPermissions'], true); + + $container->alias(Historyadminview::class, 'Model.Historyadminview') + ->share('Model.Historyadminview', [$this, 'getModelHistoryadminview'], true); + + $container->alias(Mysqlsettings::class, 'Model.Mysqlsettings') + ->share('Model.Mysqlsettings', [$this, 'getModelMysqlsettings'], true); + + $container->alias(Sql::class, 'Model.Sql') + ->share('Model.Sql', [$this, 'getModelSql'], true); + + $container->alias(Customalias::class, 'Model.Customalias') + ->share('Model.Customalias', [$this, 'getModelCustomalias'], true); + + $container->alias(Ajaxadmin::class, 'Model.Ajaxadmin') + ->share('Model.Ajaxadmin', [$this, 'getModelAjaxadmin'], true); + + $container->alias(Customimportscripts::class, 'Model.Customimportscripts') + ->share('Model.Customimportscripts', [$this, 'getModelCustomimportscripts'], true); + + $container->alias(Custombuttons::class, 'Model.Custombuttons') + ->share('Model.Custombuttons', [$this, 'getModelCustombuttons'], true); + + $container->alias(Loader::class, 'Model.Loader') + ->share('Model.Loader', [$this, 'getModelLoader'], true); + + $container->alias(Phpadminview::class, 'Model.Phpadminview') + ->share('Model.Phpadminview', [$this, 'getModelPhpadminview'], true); + + $container->alias(Cssadminview::class, 'Model.Cssadminview') + ->share('Model.Cssadminview', [$this, 'getModelCssadminview'], true); + + $container->alias(Javascriptadminview::class, 'Model.Javascriptadminview') + ->share('Model.Javascriptadminview', [$this, 'getModelJavascriptadminview'], true); + + $container->alias(Linkedviews::class, 'Model.Linkedviews') + ->share('Model.Linkedviews', [$this, 'getModelLinkedviews'], true); + + $container->alias(Relations::class, 'Model.Relations') + ->share('Model.Relations', [$this, 'getModelRelations'], true); + + $container->alias(Conditions::class, 'Model.Conditions') + ->share('Model.Conditions', [$this, 'getModelConditions'], true); + + $container->alias(Fields::class, 'Model.Fields') + ->share('Model.Fields', [$this, 'getModelFields'], true); + + $container->alias(Updatesql::class, 'Model.Updatesql') + ->share('Model.Updatesql', [$this, 'getModelUpdatesql'], true); + + $container->alias(Tabs::class, 'Model.Tabs') + ->share('Model.Tabs', [$this, 'getModelTabs'], true); + + $container->alias(Customtabs::class, 'Model.Customtabs') + ->share('Model.Customtabs', [$this, 'getModelCustomtabs'], true); + + $container->alias(Adminviews::class, 'Model.Adminviews') + ->share('Model.Adminviews', [$this, 'getModelAdminviews'], true); + + $container->alias(Sqltweaking::class, 'Model.Sqltweaking') + ->share('Model.Sqltweaking', [$this, 'getModelSqltweaking'], true); + + $container->alias(Sqldump::class, 'Model.Sqldump') + ->share('Model.Sqldump', [$this, 'getModelSqldump'], true); + + $container->alias(Whmcs::class, 'Model.Whmcs') + ->share('Model.Whmcs', [$this, 'getModelWhmcs'], true); + + $container->alias(Modifieddate::class, 'Model.Modifieddate') + ->share('Model.Modifieddate', [$this, 'getModifieddate'], true); + + $container->alias(Createdate::class, 'Model.Createdate') + ->share('Model.Createdate', [$this, 'getCreatedate'], true); + + $container->alias(Updateserver::class, 'Model.Updateserver') + ->share('Model.Updateserver', [$this, 'getUpdateserver'], true); + + $container->alias(Filesfolders::class, 'Model.Filesfolders') + ->share('Model.Filesfolders', [$this, 'getModelFilesfolders'], true); + + $container->alias(ServerLoad::class, 'Model.Server.Load') + ->share('Model.Server.Load', [$this, 'getServerLoad'], true); + } + + /** + * Get the Joomla plugins Model + * + * @param Container $container The DI container. + * + * @return Joomlaplugins + * @since 3.2.0 + */ + public function getModelJoomlaplugins(Container $container): Joomlaplugins + { + return new Joomlaplugins( + $container->get('Joomlaplugin.Data') + ); + } + + /** + * Get the Joomla modules Model + * + * @param Container $container The DI container. + * + * @return Joomlamodules + * @since 3.2.0 + */ + public function getModelJoomlamodules(Container $container): Joomlamodules + { + return new Joomlamodules( + $container->get('Joomlamodule.Data') + ); + } + + /** + * Get the history component Model + * + * @param Container $container The DI container. + * + * @return Historycomponent + * @since 3.2.0 + */ + public function getModelHistorycomponent(Container $container): Historycomponent + { + return new Historycomponent( + $container->get('Config'), + $container->get('History'), + $container->get('Model.Updatesql') + ); + } + + /** + * Get the custom admin views Model + * + * @param Container $container The DI container. + * + * @return Customadminviews + * @since 3.2.0 + */ + public function getModelCustomadminviews(Container $container): Customadminviews + { + return new Customadminviews( + $container->get('Customview.Data'), + $container->get('Config') + ); + } + + /** + * Get the ajax custom view Model + * + * @param Container $container The DI container. + * + * @return Ajaxcustomview + * @since 3.2.0 + */ + public function getModelAjaxcustomview(Container $container): Ajaxcustomview + { + return new Ajaxcustomview( + $container->get('Config'), + $container->get('Customcode.Dispenser') + ); + } + + /** + * Get the javascript custom view Model + * + * @param Container $container The DI container. + * + * @return Javascriptcustomview + * @since 3.2.0 + */ + public function getModelJavascriptcustomview(Container $container): Javascriptcustomview + { + return new Javascriptcustomview( + $container->get('Customcode'), + $container->get('Customcode.Gui') + ); + } + + /** + * Get the css custom view Model + * + * @param Container $container The DI container. + * + * @return Csscustomview + * @since 3.2.0 + */ + public function getModelCsscustomview(Container $container): Csscustomview + { + return new Csscustomview( + $container->get('Customcode') + ); + } + + /** + * Get the php custom view Model + * + * @param Container $container The DI container. + * + * @return Phpcustomview + * @since 3.2.0 + */ + public function getModelPhpcustomview(Container $container): Phpcustomview + { + return new Phpcustomview( + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Model.Loader'), + $container->get('Templatelayout.Data') + ); + } + + /** + * Get the dynamic get Model + * + * @param Container $container The DI container. + * + * @return Dynamicget + * @since 3.2.0 + */ + public function getModelDynamicget(Container $container): Dynamicget + { + return new Dynamicget( + $container->get('Config'), + $container->get('Compiler.Builder.Site.Dynamic.Get'), + $container->get('Compiler.Builder.Site.Main.Get'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Placeholder'), + $container->get('Dynamicget.Selection') + ); + } + + /** + * Get the libraries Model + * + * @param Container $container The DI container. + * + * @return Libraries + * @since 3.2.0 + */ + public function getModelLibraries(Container $container): Libraries + { + return new Libraries( + $container->get('Config'), + $container->get('Compiler.Builder.Library.Manager'), + $container->get('Library.Data') + ); + } + + /** + * Get the site views Model + * + * @param Container $container The DI container. + * + * @return Siteviews + * @since 3.2.0 + */ + public function getModelSiteviews(Container $container): Siteviews + { + return new Siteviews( + $container->get('Customview.Data'), + $container->get('Config') + ); + } + + /** + * Get the permissions Model + * + * @param Container $container The DI container. + * + * @return Permissions + * @since 3.2.0 + */ + public function getModelPermissions(Container $container): Permissions + { + return new Permissions(); + } + + /** + * Get the admin view history Model + * + * @param Container $container The DI container. + * + * @return Historyadminview + * @since 3.2.0 + */ + public function getModelHistoryadminview(Container $container): Historyadminview + { + return new Historyadminview( + $container->get('Config'), + $container->get('History'), + $container->get('Model.Updatesql') + ); + } + + /** + * Get the MySQL settings Model + * + * @param Container $container The DI container. + * + * @return Mysqlsettings + * @since 3.2.0 + */ + public function getModelMysqlsettings(Container $container): Mysqlsettings + { + return new Mysqlsettings( + $container->get('Config'), + $container->get('Compiler.Builder.Mysql.Table.Setting') + ); + } + + /** + * Get the Sql Model + * + * @param Container $container The DI container. + * + * @return Sql + * @since 3.2.0 + */ + public function getModelSql(Container $container): Sql + { + return new Sql( + $container->get('Customcode.Dispenser'), + $container->get('Model.Sqldump') + ); + } + + /** + * Get the custom alias Model + * + * @param Container $container The DI container. + * + * @return Customalias + * @since 3.2.0 + */ + public function getModelCustomalias(Container $container): Customalias + { + return new Customalias( + $container->get('Compiler.Builder.Custom.Alias'), + $container->get('Field.Name') + ); + } + + /** + * Get the Admin Ajax Model + * + * @param Container $container The DI container. + * + * @return Ajaxadmin + * @since 3.2.0 + */ + public function getModelAjaxadmin(Container $container): Ajaxadmin + { + return new Ajaxadmin( + $container->get('Config'), + $container->get('Compiler.Builder.Site.Edit.View'), + $container->get('Customcode.Dispenser') + ); + } + + /** + * Get the custom import scripts Model + * + * @param Container $container The DI container. + * + * @return Customimportscripts + * @since 3.2.0 + */ + public function getModelCustomimportscripts(Container $container): Customimportscripts + { + return new Customimportscripts( + $container->get('Customcode.Dispenser') + ); + } + + /** + * Get the custom import scripts Model + * + * @param Container $container The DI container. + * + * @return Custombuttons + * @since 3.2.0 + */ + public function getModelCustombuttons(Container $container): Custombuttons + { + return new Custombuttons( + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Templatelayout.Data') + ); + } + + /** + * Get The Model Loader Class. + * + * @param Container $container The DI container. + * + * @return Loader + * @since 3.2.0 + */ + public function getModelLoader(Container $container): Loader + { + return new Loader( + $container->get('Config'), + $container->get('Compiler.Builder.Footable.Scripts'), + $container->get('Compiler.Builder.Google.Chart'), + $container->get('Compiler.Builder.Get.Module'), + $container->get('Compiler.Builder.Uikit.Comp') + ); + } + + /** + * Get the php admin view Model + * + * @param Container $container The DI container. + * + * @return Phpadminview + * @since 3.2.0 + */ + public function getModelPhpadminview(Container $container): Phpadminview + { + return new Phpadminview( + $container->get('Customcode.Dispenser'), + $container->get('Templatelayout.Data') + ); + } + + /** + * Get the Css Adminview Model + * + * @param Container $container The DI container. + * + * @return Cssadminview + * @since 3.2.0 + */ + public function getModelCssadminview(Container $container): Cssadminview + { + return new Cssadminview( + $container->get('Customcode.Dispenser') + ); + } + + /** + * Get the Javascript Adminview Model + * + * @param Container $container The DI container. + * + * @return Javascriptadminview + * @since 3.2.0 + */ + public function getModelJavascriptadminview(Container $container): Javascriptadminview + { + return new Javascriptadminview( + $container->get('Customcode.Dispenser') + ); + } + + /** + * Get the linked views Model + * + * @param Container $container The DI container. + * + * @return Linkedviews + * @since 3.2.0 + */ + public function getModelLinkedviews(Container $container): Linkedviews + { + return new Linkedviews( + $container->get('Registry') + ); + } + + /** + * Get the relations Model + * + * @param Container $container The DI container. + * + * @return Relations + * @since 3.2.0 + */ + public function getModelRelations(Container $container): Relations + { + return new Relations( + $container->get('Config'), + $container->get('Language'), + $container->get('Customcode'), + $container->get('Compiler.Builder.List.Join'), + $container->get('Compiler.Builder.List.Head.Override'), + $container->get('Compiler.Builder.Field.Relations') + ); + } + + /** + * Get the conditions Model + * + * @param Container $container The DI container. + * + * @return Conditions + * @since 3.2.0 + */ + public function getModelConditions(Container $container): Conditions + { + return new Conditions( + $container->get('Field.Type.Name'), + $container->get('Field.Name'), + $container->get('Field.Groups') + ); + } + + /** + * Get the fields Model + * + * @param Container $container The DI container. + * + * @return Fields + * @since 3.2.0 + */ + public function getModelFields(Container $container): Fields + { + return new Fields( + $container->get('Config'), + $container->get('Registry'), + $container->get('History'), + $container->get('Customcode'), + $container->get('Field'), + $container->get('Field.Name'), + $container->get('Field.Groups'), + $container->get('Model.Updatesql') + ); + } + + /** + * Get the update sql Model + * + * @param Container $container The DI container. + * + * @return Updatesql + * @since 3.2.0 + */ + public function getModelUpdatesql(Container $container): Updatesql + { + return new Updatesql( + $container->get('Registry') + ); + } + + /** + * Get the tabs Model + * + * @param Container $container The DI container. + * + * @return Updatesql + * @since 3.2.0 + */ + public function getModelTabs(Container $container): Tabs + { + return new Tabs(); + } + + /** + * Get the custom tabs Model + * + * @param Container $container The DI container. + * + * @return Customtabs + * @since 3.2.0 + */ + public function getModelCustomtabs(Container $container): Customtabs + { + return new Customtabs( + $container->get('Config'), + $container->get('Compiler.Builder.Custom.Tabs'), + $container->get('Language'), + $container->get('Placeholder'), + $container->get('Customcode') + ); + } + + /** + * Get the admin views Model + * + * @param Container $container The DI container. + * + * @return Adminviews + * @since 3.2.0 + */ + public function getModelAdminviews(Container $container): Adminviews + { + return new Adminviews( + $container->get('Config'), + $container->get('Adminview.Data'), + $container->get('Compiler.Builder.Site.Edit.View'), + $container->get('Compiler.Builder.Admin.Filter.Type') + ); + } + + /** + * Get the SQL tweaking Model + * + * @param Container $container The DI container. + * + * @return Sqltweaking + * @since 3.2.0 + */ + public function getModelSqltweaking(Container $container): Sqltweaking + { + return new Sqltweaking( + $container->get('Registry') + ); + } + + /** + * Get the SQL dump Model + * + * @param Container $container The DI container. + * + * @return Sqldump + * @since 3.2.0 + */ + public function getModelSqldump(Container $container): Sqldump + { + return new Sqldump( + $container->get('Registry') + ); + } + + /** + * Get the whmcs Model + * + * @param Container $container The DI container. + * + * @return Whmcs + * @since 3.2.0 + */ + public function getModelWhmcs(Container $container): Whmcs + { + return new Whmcs(); + } + + /** + * Get the modified date Model + * + * @param Container $container The DI container. + * + * @return Modifieddate + * @since 3.2.0 + */ + public function getModifieddate(Container $container): Modifieddate + { + return new Modifieddate(); + } + + /** + * Get the create date Model + * + * @param Container $container The DI container. + * + * @return Createdate + * @since 3.2.0 + */ + public function getCreatedate(Container $container): Createdate + { + return new Createdate(); + } + + /** + * Get the update server Model + * + * @param Container $container The DI container. + * + * @return Updateserver + * @since 3.2.0 + */ + public function getUpdateserver(Container $container): Updateserver + { + return new Updateserver(); + } + + /** + * Get the files folders Model + * + * @param Container $container The DI container. + * + * @return Filesfolders + * @since 3.2.0 + */ + public function getModelFilesfolders(Container $container): Filesfolders + { + return new Filesfolders(); + } + + /** + * Get the Server Model Server Loader class + * + * @param Container $container The DI container. + * + * @return ServerLoad + * @since 3.2.0 + */ + public function getServerLoad(Container $container): ServerLoad + { + return new ServerLoad( + $container->get('Crypt'), + $container->get('Table') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php new file mode 100644 index 000000000..4561b63c7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php @@ -0,0 +1,79 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder as CompilerPlaceholder; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder\Reverse; + + +/** + * Compiler Placeholder Service Provider + * + * @since 3.2.0 + */ +class Placeholder implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(CompilerPlaceholder::class, 'Placeholder') + ->share('Placeholder', [$this, 'getPlaceholder'], true); + + $container->alias(Reverse::class, 'Placeholder.Reverse') + ->share('Placeholder.Reverse', [$this, 'getPlaceholderReverse'], true); + } + + /** + * Get the Compiler Placeholder + * + * @param Container $container The DI container. + * + * @return CompilerPlaceholder + * @since 3.2.0 + */ + public function getPlaceholder(Container $container): CompilerPlaceholder + { + return new CompilerPlaceholder( + $container->get('Config') + ); + } + + /** + * Get the Compiler Placeholder Reverse + * + * @param Container $container The DI container. + * + * @return Worker + * @since 3.2.0 + */ + public function getPlaceholderReverse(Container $container): Reverse + { + return new Reverse( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Language'), + $container->get('Language.Extractor'), + $container->get('Power.Extractor') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php new file mode 100644 index 000000000..b03acb72a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php @@ -0,0 +1,349 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Power as Powers; +use VDM\Joomla\Componentbuilder\Power\Grep; +use VDM\Joomla\Componentbuilder\Power\Super as Superpower; +use VDM\Joomla\Componentbuilder\Compiler\Power\Infusion; +use VDM\Joomla\Componentbuilder\Compiler\Power\Autoloader; +use VDM\Joomla\Componentbuilder\Compiler\Power\Structure; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Compiler\Power\Plantuml; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repo\Readme as RepoReadme; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repos\Readme as ReposReadme; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Injector; +use VDM\Joomla\Componentbuilder\Power\Model\Upsert; +use VDM\Joomla\Componentbuilder\Power\Database\Insert; +use VDM\Joomla\Componentbuilder\Power\Database\Update; + + +/** + * Compiler Power Service Provider + * + * @since 3.2.0 + */ +class Power implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Powers::class, 'Power') + ->share('Power', [$this, 'getPowers'], true); + + $container->alias(Superpower::class, 'Superpower') + ->share('Superpower', [$this, 'getSuperpower'], true); + + $container->alias(Grep::class, 'Power.Grep') + ->share('Power.Grep', [$this, 'getGrep'], true); + + $container->alias(Autoloader::class, 'Power.Autoloader') + ->share('Power.Autoloader', [$this, 'getAutoloader'], true); + + $container->alias(Infusion::class, 'Power.Infusion') + ->share('Power.Infusion', [$this, 'getInfusion'], true); + + $container->alias(Structure::class, 'Power.Structure') + ->share('Power.Structure', [$this, 'getStructure'], true); + + $container->alias(Parser::class, 'Power.Parser') + ->share('Power.Parser', [$this, 'getParser'], true); + + $container->alias(Plantuml::class, 'Power.Plantuml') + ->share('Power.Plantuml', [$this, 'getPlantuml'], true); + + $container->alias(RepoReadme::class, 'Power.Repo.Readme') + ->share('Power.Repo.Readme', [$this, 'getRepoReadme'], true); + + $container->alias(ReposReadme::class, 'Power.Repos.Readme') + ->share('Power.Repos.Readme', [$this, 'getReposReadme'], true); + + $container->alias(Extractor::class, 'Power.Extractor') + ->share('Power.Extractor', [$this, 'getExtractor'], true); + + $container->alias(Injector::class, 'Power.Injector') + ->share('Power.Injector', [$this, 'getInjector'], true); + + $container->alias(Upsert::class, 'Power.Model.Upsert') + ->share('Power.Model.Upsert', [$this, 'getModelUpsert'], true); + + $container->alias(Insert::class, 'Power.Insert') + ->share('Power.Insert', [$this, 'getInsert'], true); + + $container->alias(Update::class, 'Power.Update') + ->share('Power.Update', [$this, 'getUpdate'], true); + } + + /** + * Get the Powers + * + * @param Container $container The DI container. + * + * @return Powers + * @since 3.2.0 + */ + public function getPowers(Container $container): Powers + { + return new Powers( + $container->get('Config'), + $container->get('Placeholder'), + $container->get('Customcode'), + $container->get('Customcode.Gui') + ); + } + + /** + * Get the Superpower + * + * @param Container $container The DI container. + * + * @return Superpower + * @since 3.2.0 + */ + public function getSuperpower(Container $container): Superpower + { + return new Superpower( + $container->get('Power.Grep'), + $container->get('Power.Insert'), + $container->get('Power.Update') + ); + } + + /** + * Get the Grep + * + * @param Container $container The DI container. + * + * @return Grep + * @since 3.2.0 + */ + public function getGrep(Container $container): Grep + { + return new Grep( + $container->get('Config')->local_powers_repository_path, + $container->get('Config')->approved_paths, + $container->get('Gitea.Repository.Contents') + ); + } + + /** + * Get the Compiler Autoloader + * + * @param Container $container The DI container. + * + * @return Autoloader + * @since 3.2.0 + */ + public function getAutoloader(Container $container): Autoloader + { + return new Autoloader( + $container->get('Power'), + $container->get('Config'), + $container->get('Compiler.Builder.Content.One') + ); + } + + /** + * Get the Compiler Power Infusion + * + * @param Container $container The DI container. + * + * @return Infusion + * @since 3.2.0 + */ + public function getInfusion(Container $container): Infusion + { + return new Infusion( + $container->get('Config'), + $container->get('Power'), + $container->get('Compiler.Builder.Content.One'), + $container->get('Compiler.Builder.Content.Multi'), + $container->get('Power.Autoloader'), + $container->get('Power.Parser'), + $container->get('Power.Repo.Readme'), + $container->get('Power.Repos.Readme'), + $container->get('Placeholder'), + $container->get('Event') + ); + } + + /** + * Get the Compiler Power Structure Builder + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getStructure(Container $container): Structure + { + return new Structure( + $container->get('Power'), + $container->get('Config'), + $container->get('Registry'), + $container->get('Event'), + $container->get('Utilities.Counter'), + $container->get('Utilities.Paths'), + $container->get('Utilities.Folder'), + $container->get('Utilities.File'), + $container->get('Utilities.Files') + ); + } + + /** + * Get the Compiler Power Parser + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getParser(Container $container): Parser + { + return new Parser(); + } + + /** + * Get the Compiler Power Plantuml Builder + * + * @param Container $container The DI container. + * + * @return Plantuml + * @since 3.2.0 + */ + public function getPlantuml(Container $container): Plantuml + { + return new Plantuml(); + } + + /** + * Get the Compiler Power Repo Readme Builder + * + * @param Container $container The DI container. + * + * @return RepoReadme + * @since 3.2.0 + */ + public function getRepoReadme(Container $container): RepoReadme + { + return new RepoReadme( + $container->get('Power'), + $container->get('Power.Plantuml') + ); + } + + /** + * Get the Compiler Power Repos Readme Builder + * + * @param Container $container The DI container. + * + * @return ReposReadme + * @since 3.2.0 + */ + public function getReposReadme(Container $container): ReposReadme + { + return new ReposReadme( + $container->get('Power'), + $container->get('Power.Plantuml') + ); + } + + /** + * Get the Compiler Power Extractor + * + * @param Container $container The DI container. + * + * @return Extractor + * @since 3.2.0 + */ + public function getExtractor(Container $container): Extractor + { + return new Extractor(); + } + + /** + * Get the Compiler Power Injector + * + * @param Container $container The DI container. + * + * @return Injector + * @since 3.2.0 + */ + public function getInjector(Container $container): Injector + { + return new Injector( + $container->get('Power'), + $container->get('Power.Extractor'), + $container->get('Power.Parser'), + $container->get('Placeholder') + ); + } + + /** + * Get the Power Model Upsert + * + * @param Container $container The DI container. + * + * @return Upsert + * @since 3.2.0 + */ + public function getModelUpsert(Container $container): Upsert + { + return new Upsert( + $container->get('Table') + ); + } + + /** + * Get the Power Insert + * + * @param Container $container The DI container. + * + * @return Insert + * @since 3.2.0 + */ + public function getInsert(Container $container): Insert + { + return new Insert( + $container->get('Power.Model.Upsert'), + $container->get('Insert') + ); + } + + /** + * Get the Power Update + * + * @param Container $container The DI container. + * + * @return Update + * @since 3.2.0 + */ + public function getUpdate(Container $container): Update + { + return new Update( + $container->get('Power.Model.Upsert'), + $container->get('Update') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Templatelayout.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Templatelayout.php new file mode 100644 index 000000000..e066bff43 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Templatelayout.php @@ -0,0 +1,83 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Templatelayout\Data as TemplatelayoutData; +use VDM\Joomla\Componentbuilder\Compiler\Alias\Data as AliasData; + + +/** + * Compiler Templatelayout + * + * @since 3.2.0 + */ +class Templatelayout implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(TemplatelayoutData::class, 'Templatelayout.Data') + ->share('Templatelayout.Data', [$this, 'getTemplatelayoutData'], true); + + $container->alias(AliasData::class, 'Alias.Data') + ->share('Alias.Data', [$this, 'getAliasData'], true); + } + + /** + * Get The Data Class. + * + * @param Container $container The DI container. + * + * @return TemplatelayoutData + * @since 3.2.0 + */ + public function getTemplatelayoutData(Container $container): TemplatelayoutData + { + return new TemplatelayoutData( + $container->get('Config'), + $container->get('Compiler.Builder.Layout.Data'), + $container->get('Compiler.Builder.Template.Data'), + $container->get('Alias.Data') + ); + } + + /** + * Get The Data Class. + * + * @param Container $container The DI container. + * + * @return AliasData + * @since 3.2.0 + */ + public function getAliasData(Container $container): AliasData + { + return new AliasData( + $container->get('Config'), + $container->get('Registry'), + $container->get('Customcode'), + $container->get('Customcode.Gui'), + $container->get('Model.Loader'), + $container->get('Model.Libraries') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Utilities.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Utilities.php new file mode 100644 index 000000000..40d4d3625 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Utilities.php @@ -0,0 +1,229 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; +use VDM\Joomla\Componentbuilder\Utilities\Constantpaths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Dynamicpath; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Pathfix; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Xml; + + +/** + * Utilities Service Provider + * + * @since 3.2.0 + */ +class Utilities implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Folder::class, 'Utilities.Folder') + ->share('Utilities.Folder', [$this, 'getFolder'], true); + + $container->alias(File::class, 'Utilities.File') + ->share('Utilities.File', [$this, 'getFile'], true); + + $container->alias(Counter::class, 'Utilities.Counter') + ->share('Utilities.Counter', [$this, 'getCounter'], true); + + $container->alias(Paths::class, 'Utilities.Paths') + ->share('Utilities.Paths', [$this, 'getPaths'], true); + + $container->alias(Files::class, 'Utilities.Files') + ->share('Utilities.Files', [$this, 'getFiles'], true); + + $container->alias(Constantpaths::class, 'Utilities.Constantpaths') + ->share('Utilities.Constantpaths', [$this, 'getConstantpaths'], true); + + $container->alias(Dynamicpath::class, 'Utilities.Dynamicpath') + ->share('Utilities.Dynamicpath', [$this, 'getDynamicpath'], true); + + $container->alias(Pathfix::class, 'Utilities.Pathfix') + ->share('Utilities.Pathfix', [$this, 'getPathfix'], true); + + $container->alias(Structure::class, 'Utilities.Structure') + ->share('Utilities.Structure', [$this, 'getStructure'], true); + + $container->alias(Xml::class, 'Utilities.Xml') + ->share('Utilities.Xml', [$this, 'getXml'], true); + } + + /** + * Get the Compiler Folder + * + * @param Container $container The DI container. + * + * @return Folder + * @since 3.2.0 + */ + public function getFolder(Container $container): Folder + { + return new Folder( + $container->get('Utilities.Counter'), + $container->get('Utilities.File') + ); + } + + /** + * Get the Compiler File + * + * @param Container $container The DI container. + * + * @return File + * @since 3.2.0 + */ + public function getFile(Container $container): File + { + return new File( + $container->get('Utilities.Counter') + ); + } + + /** + * Get the Compiler Counter + * + * @param Container $container The DI container. + * + * @return Counter + * @since 3.2.0 + */ + public function getCounter(Container $container): Counter + { + return new Counter( + $container->get('Compiler.Builder.Content.One') + ); + } + + /** + * Get the Compiler Paths + * + * @param Container $container The DI container. + * + * @return Paths + * @since 3.2.0 + */ + public function getPaths(Container $container): Paths + { + return new Paths( + $container->get('Config'), + $container->get('Component') + ); + } + + /** + * Get the Compiler Files Bucket + * + * @param Container $container The DI container. + * + * @return Files + * @since 3.2.0 + */ + public function getFiles(Container $container): Files + { + return new Files(); + } + + /** + * Get the Constant Paths + * + * @param Container $container The DI container. + * + * @return Constantpaths + * @since 3.2.0 + */ + public function getConstantpaths(Container $container): Constantpaths + { + return new Constantpaths(); + } + + /** + * Get the Compiler Dynamic Path + * + * @param Container $container The DI container. + * + * @return Dynamicpath + * @since 3.2.0 + */ + public function getDynamicpath(Container $container): Dynamicpath + { + return new Dynamicpath( + $container->get('Placeholder'), + $container->get('Utilities.Constantpaths') + ); + } + + /** + * Get the Compiler Path Fixer + * + * @param Container $container The DI container. + * + * @return Pathfix + * @since 3.2.0 + */ + public function getPathfix(Container $container): Pathfix + { + return new Pathfix(); + } + + /** + * Get the Compiler Structure Dynamic Builder + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getStructure(Container $container): Structure + { + return new Structure( + $container->get('Component.Settings'), + $container->get('Utilities.Paths'), + $container->get('Utilities.Counter'), + $container->get('Utilities.File'), + $container->get('Utilities.Files') + ); + } + + /** + * Get the Compiler Xml Helper + * + * @param Container $container The DI container. + * + * @return Xml + * @since 3.2.0 + */ + public function getXml(Container $container): Xml + { + return new Xml( + $container->get('Config') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Templatelayout/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Templatelayout/Data.php new file mode 100644 index 000000000..f0cca1754 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Templatelayout/Data.php @@ -0,0 +1,241 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Templatelayout; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Builder\LayoutData; +use VDM\Joomla\Componentbuilder\Compiler\Builder\TemplateData; +use VDM\Joomla\Componentbuilder\Compiler\Alias\Data as Aliasdata; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Template Layout Data Class + * + * @since 3.2.0 + */ +class Data +{ + /** + * The Config Class. + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * The LayoutData Class. + * + * @var LayoutData + * @since 3.2.0 + */ + protected LayoutData $layoutdata; + + /** + * The TemplateData Class. + * + * @var TemplateData + * @since 3.2.0 + */ + protected TemplateData $templatedata; + + /** + * The Data Class. + * + * @var Aliasdata + * @since 3.2.0 + */ + protected Aliasdata $aliasdata; + + /** + * Constructor. + * + * @param Config $config The Config Class. + * @param LayoutData $layoutdata The LayoutData Class. + * @param TemplateData $templatedata The TemplateData Class. + * @param Aliasdata $aliasdata The AliasData Class. + * + * @since 3.2.0 + */ + public function __construct(Config $config, LayoutData $layoutdata, TemplateData $templatedata, Aliasdata $aliasdata) + { + $this->config = $config; + $this->layoutdata = $layoutdata; + $this->templatedata = $templatedata; + $this->aliasdata = $aliasdata; + } + + /** + * Set Template and Layout Data + * + * @param string $content The content to check + * @param string $view The view code name + * @param bool $found The proof that something was found + * @param array $templates The option to pass templates keys (to avoid search) + * @param array $layouts The option to pass layout keys (to avoid search) + * + * @return bool if something was found true + * @since 3.2.0 + */ + public function set(string $content, string $view, bool $found = false, + array $templates = [], array $layouts = []): bool + { + // to check inside the templates + $again = []; + + // check if template keys were passed + if (!ArrayHelper::check($templates)) + { + // set the Template data + $temp1 = GetHelper::allBetween( + $content, "\$this->loadTemplate('", "')" + ); + $temp2 = GetHelper::allBetween( + $content, '$this->loadTemplate("', '")' + ); + if (ArrayHelper::check($temp1) + && ArrayHelper::check($temp2)) + { + $templates = array_merge($temp1, $temp2); + } + else + { + if (ArrayHelper::check($temp1)) + { + $templates = $temp1; + } + elseif (ArrayHelper::check($temp2)) + { + $templates = $temp2; + } + } + } + + // check if we found templates + if (ArrayHelper::check($templates, true)) + { + foreach ($templates as $template) + { + if (!$this->templatedata-> + exists($this->config->build_target . '.' . $view . '.' . $template)) + { + $data = $this->aliasdata->get( + $template, 'template', $view + ); + if (ArrayHelper::check($data)) + { + // load it to the template data array + $this->templatedata-> + set($this->config->build_target . '.' . $view . '.' . $template, $data); + // call self to get child data + $again[] = ['content' => $data['html'], 'view' => $view]; + $again[] = ['content' => $data['php_view'], 'view' => $view]; + } + } + + // check if we have the template set (and nothing yet found) + if (!$found && $this->templatedata-> + exists($this->config->build_target . '.' . $view . '.' . $template, null)) + { + // something was found + $found = true; + } + } + } + + // check if layout keys were passed + if (!ArrayHelper::check($layouts)) + { + // set the Layout data + $lay1 = GetHelper::allBetween( + $content, "JLayoutHelper::render('", "'," + ); + $lay2 = GetHelper::allBetween( + $content, 'JLayoutHelper::render("', '",' + ); + if (ArrayHelper::check($lay1) + && ArrayHelper::check($lay2)) + { + $layouts = array_merge($lay1, $lay2); + } + else + { + if (ArrayHelper::check($lay1)) + { + $layouts = $lay1; + } + elseif (ArrayHelper::check($lay2)) + { + $layouts = $lay2; + } + } + } + + // check if we found layouts + if (ArrayHelper::check($layouts, true)) + { + // get the other target if both + $_target = null; + if ($this->config->lang_target === 'both') + { + $_target = ($this->config->build_target === 'admin') ? 'site' : 'admin'; + } + + foreach ($layouts as $layout) + { + if (!$this->layoutdata->exists($this->config->build_target . '.' . $layout)) + { + $data = $this->aliasdata->get($layout, 'layout', $view); + if (ArrayHelper::check($data)) + { + // load it to the layout data array + $this->layoutdata-> + set($this->config->build_target . '.' . $layout, $data); + // check if other target is set + if ($this->config->lang_target === 'both' && $_target) + { + $this->layoutdata->set($_target . '.' . $layout, $data); + } + // call self to get child data + $again[] = ['content' => $data['html'], 'view' => $view]; + $again[] = ['content' => $data['php_view'], 'view' => $view]; + } + } + + // check if we have the layout set (and nothing yet found) + if (!$found && $this->layoutdata->exists($this->config->build_target . '.' . $layout)) + { + // something was found + $found = true; + } + } + } + + // check again + if (ArrayHelper::check($again)) + { + foreach ($again as $go) + { + $found = $this->set( + $go['content'], $go['view'], $found + ); + } + } + + // return the proof that something was found + return $found; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Templatelayout/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Templatelayout/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Templatelayout/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Counter.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Counter.php new file mode 100644 index 000000000..a16dd6358 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Counter.php @@ -0,0 +1,409 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content; + + +/** + * Compiler Utilities Counter + * + * @since 3.2.0 + */ +class Counter +{ + /** + * The folder counter + * + * @var int + * @since 3.2.0 + */ + public int $folder = 0; + + /** + * The file counter + * + * @var int + * @since 3.2.0 + */ + public int $file = 0; + + /** + * The page counter + * + * @var int + * @since 3.2.0 + */ + public int $page = 0; + + /** + * The line counter + * + * @var int + * @since 3.2.0 + */ + public int $line = 0; + + /** + * The field counter + * + * @var int + * @since 3.2.0 + */ + public int $field = 0; + + /** + * The access size + * + * @var int + * @since 3.2.0 + */ + public int $accessSize = 0; + + /** + * The seconds counter + * + * @var int + * @since 3.2.0 + */ + protected int $seconds = 0; + + /** + * The actual seconds counter + * + * @var float + * @since 3.2.0 + */ + protected float $actualSeconds = 0; + + /** + * The folder seconds counter + * + * @var int + * @since 3.2.0 + */ + protected int $folderSeconds = 0; + + /** + * The file seconds counter + * + * @var int + * @since 3.2.0 + */ + protected int $fileSeconds = 0; + + /** + * The line seconds counter + * + * @var int + * @since 3.2.0 + */ + protected int $lineSeconds = 0; + + /** + * The seconds debugging counter + * + * @var float + * @since 3.2.0 + */ + protected float $secondsDebugging = 0; + + /** + * The seconds planning counter + * + * @var float + * @since 3.2.0 + */ + protected float $secondsPlanning = 0; + + /** + * The seconds mapping counter + * + * @var float + * @since 3.2.0 + */ + protected float $secondsMapping = 0; + + /** + * The seconds office counter + * + * @var float + * @since 3.2.0 + */ + protected float $secondsOffice = 0; + + /** + * The total hours counter + * + * @var int + * @since 3.2.0 + */ + protected int $totalHours = 0; + + /** + * The debugging hours counter + * + * @var int + * @since 3.2.0 + */ + protected int $debuggingHours = 0; + + /** + * The planning hours counter + * + * @var int + * @since 3.2.0 + */ + protected int $planningHours = 0; + + /** + * The mapping hours counter + * + * @var int + * @since 3.2.0 + */ + protected int $mappingHours = 0; + + /** + * The office hours counter + * + * @var int + * @since 3.2.0 + */ + protected int $officeHours = 0; + + /** + * The actual Total Hours counter + * + * @var int + * @since 3.2.0 + */ + protected int $actualTotalHours = 0; + + /** + * The actual hours spent counter + * + * @var int + * @since 3.2.0 + */ + protected int $actualHoursSpent = 0; + + /** + * The actual days spent counter + * + * @var int + * @since 3.2.0 + */ + protected int $actualDaysSpent = 0; + + /** + * The total days counter + * + * @var int + * @since 3.2.0 + */ + protected int $totalDays = 0; + + /** + * The actual Total Days counter + * + * @var int + * @since 3.2.0 + */ + protected int $actualTotalDays = 0; + + /** + * The project week time counter + * + * @var float + * @since 3.2.0 + */ + protected float $projectWeekTime = 0; + + /** + * The project month time counter + * + * @var float + * @since 3.2.0 + */ + protected float $projectMonthTime = 0; + + /** + * The compiler start timer + * + * @var float + * @since 3.2.0 + */ + protected float $start = 0; + + /** + * The compiler end timer + * + * @var float + * @since 3.2.0 + */ + protected float $end = 0; + + /** + * The compiler timer + * + * @var float + * @since 3.2.0 + */ + protected float $timer = 0; + + /** + * The ContentOne Class. + * + * @var Content + * @since 3.2.0 + */ + protected Content $content; + + /** + * Constructor. + * + * @param Content $content The ContentOne Class. + * + * @since 3.2.0 + */ + public function __construct(Content $content) + { + $this->content = $content; + } + + /** + * Start the timer + * + * @return void + * @since 3.2.0 + */ + public function start() + { + $this->start = microtime(true); + } + + /** + * End the timer + * + * @return void + * @since 3.2.0 + */ + public function end() + { + $this->end = microtime(true); + + // calculate the lenght + $this->timer = $this->end - $this->start; + + // compiler time + $this->content->set('COMPILER_TIMER_END', $this->end); + $this->content->set('COMPILER_TIMER', $this->timer); + } + + /** + * Set all the time values + * + * @return void + * @since 3.2.0 + */ + public function set() + { + // calculate all the values + $this->calculate(); + + // set some defaults + $this->content->set('LINE_COUNT', $this->line); + $this->content->set('FIELD_COUNT', $this->field); + $this->content->set('FILE_COUNT', $this->file); + $this->content->set('FOLDER_COUNT', $this->folder); + $this->content->set('PAGE_COUNT', $this->page); + $this->content->set('folders', $this->folderSeconds); + $this->content->set('foldersSeconds', $this->folderSeconds); + $this->content->set('files', $this->fileSeconds); + $this->content->set('filesSeconds', $this->fileSeconds); + $this->content->set('lines', $this->lineSeconds); + $this->content->set('linesSeconds', $this->lineSeconds); + $this->content->set('seconds', $this->actualSeconds); + $this->content->set('actualSeconds', $this->actualSeconds); + $this->content->set('totalHours', $this->totalHours); + $this->content->set('totalDays', $this->totalDays); + $this->content->set('debugging', $this->secondsDebugging); + $this->content->set('secondsDebugging', $this->secondsDebugging); + $this->content->set('planning', $this->secondsPlanning); + $this->content->set('secondsPlanning', $this->secondsPlanning); + $this->content->set('mapping', $this->secondsMapping); + $this->content->set('secondsMapping', $this->secondsMapping); + $this->content->set('office', $this->secondsOffice); + $this->content->set('secondsOffice', $this->secondsOffice); + $this->content->set('actualTotalHours', $this->actualTotalHours); + $this->content->set('actualTotalDays', $this->actualTotalDays); + $this->content->set('debuggingHours', $this->debuggingHours); + $this->content->set('planningHours', $this->planningHours); + $this->content->set('mappingHours', $this->mappingHours); + $this->content->set('officeHours', $this->officeHours); + $this->content->set('actualHoursSpent', $this->actualHoursSpent); + $this->content->set('actualDaysSpent', $this->actualDaysSpent); + $this->content->set('projectWeekTime', $this->projectWeekTime); + $this->content->set('projectMonthTime', $this->projectMonthTime); + + // compiler time + $this->content->set('COMPILER_TIMER_START', $this->start); + } + + /** + * Calculate all the time values + * + * @return void + * @since 3.2.0 + */ + protected function calculate() + { + // what is the size in terms of an A4 book + $this->page = round($this->line / 56); + + // setup the unrealistic numbers + $this->folderSeconds = $this->folder * 5; + $this->fileSeconds = $this->file * 5; + $this->lineSeconds = $this->line * 10; + $this->seconds = $this->folderSeconds + $this->fileSeconds + + $this->lineSeconds; + $this->totalHours = round($this->seconds / 3600); + $this->totalDays = round($this->totalHours / 8); + + // setup the more realistic numbers + $this->secondsDebugging = $this->seconds / 4; + $this->secondsPlanning = $this->seconds / 7; + $this->secondsMapping = $this->seconds / 10; + $this->secondsOffice = $this->seconds / 6; + $this->actualSeconds = $this->folderSeconds + $this->fileSeconds + + $this->lineSeconds + $this->secondsDebugging + + $this->secondsPlanning + $this->secondsMapping + + $this->secondsOffice; + $this->actualTotalHours = round($this->actualSeconds / 3600); + $this->actualTotalDays = round($this->actualTotalHours / 8); + $this->debuggingHours = round($this->secondsDebugging / 3600); + $this->planningHours = round($this->secondsPlanning / 3600); + $this->mappingHours = round($this->secondsMapping / 3600); + $this->officeHours = round($this->secondsOffice / 3600); + + // the actual time spent + $this->actualHoursSpent = $this->actualTotalHours - $this->totalHours; + $this->actualDaysSpent = $this->actualTotalDays - $this->totalDays; + + // calculate the projects actual time frame of completion + $this->projectWeekTime = round($this->actualTotalDays / 5, 1); + $this->projectMonthTime = round($this->actualTotalDays / 24, 1); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Dynamicpath.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Dynamicpath.php new file mode 100644 index 000000000..0a56aaf07 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Dynamicpath.php @@ -0,0 +1,78 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; +use VDM\Joomla\Componentbuilder\Utilities\Constantpaths; + + +/** + * Compiler Utilities Dynamic Path + * + * @since 3.2.0 + */ +class Dynamicpath +{ + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + **/ + protected Placeholder $placeholder; + + /** + * Constant Paths + * + * @var array + * @since 3.2.0 + **/ + protected array $paths; + + /** + * Constructor. + * + * @param Placeholder|null $placeholder The Compiler Placeholder object. + * @param Constantpaths|null $paths The Constant Paths object. + * + * @since 3.2.0 + */ + public function __construct(?Placeholder $placeholder = null, ?Constantpaths $paths = null) + { + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + $paths = $paths ?: Compiler::_('Utilities.Constantpaths'); + + // load the constant paths + $this->paths = $paths->get(); + } + + /** + * Update path with dynamic value + * + * @param string $path The path to update + * + * @return string The updated path + * @since 3.2.0 + */ + public function update(string $path): string + { + return $this->placeholder->update_( + $this->placeholder->update( + $path, $this->paths + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/FieldHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/FieldHelper.php new file mode 100644 index 000000000..52f217659 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/FieldHelper.php @@ -0,0 +1,53 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\Base64Helper; + + +/** + * The Field Helper + * + * @since 3.2.0 + */ +abstract class FieldHelper +{ + /** + * Get a field value from the XML stored string + * + * @param string $xml The xml string of the field + * @param string $get The value key to get from the string + * @param string $confirmation The value to confirm found value + * + * @return string The field value from xml + * @since 3.2.0 + */ + public static function getValue(&$xml, string &$get, string $confirmation = ''): string + { + if (StringHelper::check($xml)) + { + // if we have a PHP value, we must base64 decode it + if (strpos($get, 'type_php') !== false) + { + return Base64Helper::open(GetHelper::between($xml, $get . '="', '"', $confirmation)); + } + + return GetHelper::between($xml, $get . '="', '"', $confirmation); + } + + return $confirmation; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/File.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/File.php new file mode 100644 index 000000000..a6046dafa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/File.php @@ -0,0 +1,109 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use Joomla\CMS\Filesystem\File as JoomlaFile; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Utilities\FileHelper; + + +/** + * File helper + * + * @since 3.2.0 + */ +class File +{ + /** + * Compiler Utilities Counter + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Compiler Utilities Paths + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * Constructor + * + * @param Counter|null $counter The compiler counter object. + * @param Paths|null $paths The compiler paths object. + * + * @since 3.2.0 + */ + public function __construct(?Counter $counter = null, ?Paths $paths = null) + { + $this->counter = $counter ?: Compiler::_('Utilities.Counter'); + $this->paths = $paths ?: Compiler::_('Utilities.Paths'); + } + + /** + * set HTML blank file to a path + * + * @param string $path The path to where to set the blank html file + * @param string $root The root path + * + * @return void + */ + public function html(string $path = '', string $root = 'component') + { + if ('component' === $root) + { + $root = $this->paths->component_path . '/'; + } + + // use path if exist + if (strlen($path) > 0) + { + JoomlaFile::copy( + $this->paths->template_path . '/index.html', + $root . $path . '/index.html' + ); + } + else + { + JoomlaFile::copy( + $this->paths->template_path . '/index.html', + $root . '/index.html' + ); + } + + // count the file created + $this->counter->file++; + } + + /** + * Create a file on the server if it does not exist, or Overwrite existing files + * + * @param string $path The path and file name where to safe the data + * @param string $data The data to safe + * + * @return bool true On success + * @since 3.2.0 + */ + public function write(string $path, string $data): bool + { + return FileHelper::write($path, $data); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Files.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Files.php new file mode 100644 index 000000000..a9d9809cf --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Files.php @@ -0,0 +1,26 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Componentbuilder\Abstraction\BaseRegistry; + + +/** + * Compiler Utilities Files Bucket + * + * @since 3.2.0 + */ +class Files extends BaseRegistry +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php new file mode 100644 index 000000000..4313f08e0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php @@ -0,0 +1,170 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use Joomla\CMS\Filesystem\Folder as JoomlaFolder; +use Joomla\CMS\Filesystem\File as JoomlaFile; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Folder helper + * + * @since 3.2.0 + */ +class Folder +{ + /** + * Compiler Counter + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Compiler Utilities File + * + * @var File + * @since 3.2.0 + */ + protected File $file; + + /** + * Constructor + * + * @param Counter|null $counter The compiler counter object. + * @param File|null $file The compiler file object. + * + * @since 3.2.0 + */ + public function __construct(?Counter $counter = null, ?File $file = null) + { + $this->counter = $counter ?: Compiler::_('Utilities.Counter'); + $this->file = $file ?: Compiler::_('Utilities.File'); + } + + /** + * Create Path if not exist + * + * @param string $path The path to folder to create + * @param bool $addHtml The the switch to add the HTML + * + * @return void + * @since 3.2.0 + */ + public function create(string $path, bool $addHtml = true) + { + // check if the path exist + if (!JoomlaFolder::exists($path)) + { + // create the path + JoomlaFolder::create( + $path + ); + + // count the folder created + $this->counter->folder++; + + if ($addHtml) + { + // add index.html (boring I know) + $this->file->html( + $path, '' + ); + } + } + } + + /** + * Remove folders with files + * + * @param string $path The path to folder to remove + * @param array|null $ignore The folders and files to ignore and not remove + * + * @return boolean True if all are removed + * @since 3.2.0 + */ + public function remove(string $path, ?array $ignore = null): bool + { + if (!JoomlaFolder::exists($path)) + { + return false; + } + + $it = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); + $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); + + // Prepare a base path without trailing slash for comparison + $basePath = rtrim($path, '/'); + + foreach ($files as $fileinfo) + { + $filePath = $fileinfo->getRealPath(); + + if ($this->shouldIgnore($basePath, $filePath, $ignore)) + { + continue; + } + + if ($fileinfo->isDir()) + { + JoomlaFolder::delete($filePath); + } + else + { + JoomlaFile::delete($filePath); + } + } + + // Delete the root folder if ignore not set + if (!ArrayHelper::check($ignore)) + { + return JoomlaFolder::delete($path); + } + + return true; + } + + /** + * Check if the current path should be ignored. + * + * @param string $basePath The base directory path + * @param string $filePath The current file or directory path + * @param array|null $ignore List of items to ignore + * + * @return boolean True if the path should be ignored + * @since 3.2.0 + */ + protected function shouldIgnore(string $basePath, string $filePath, ?array $ignore = null): bool + { + if (!$ignore || !ArrayHelper::check($ignore)) + { + return false; + } + + foreach ($ignore as $item) + { + if (strpos($filePath, $basePath . '/' . $item) !== false) + { + return true; + } + } + + return false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Indent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Indent.php new file mode 100644 index 000000000..6f6af75e3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Indent.php @@ -0,0 +1,90 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; + + +/** + * The Indentation Factory + * + * @since 3.2.0 + */ +abstract class Indent +{ + /** + * Spacer bucket (to speed-up the build) + * + * @var array + * @since 3.2.0 + */ + private static array $bucket = []; + + /** + * The indentation string + * + * @var string + * @since 3.2.0 + */ + private static string $indent; + + /** + * Set the space + * + * @param int $nr The number of spaces + * + * @return string + * @since 3.2.0 + */ + public static function _(int $nr): string + { + // check if we already have the string + if (!isset(self::$bucket[$nr])) + { + // get the string + self::$bucket[$nr] = str_repeat(self::indent(), (int) $nr); + } + // return stored indentation + return self::$bucket[$nr]; + } + + /** + * Get the indentation string + * + * @return string + * @since 3.2.0 + */ + private static function indent(): string + { + if (empty(self::$indent)) + { + self::init(); + } + + return self::$indent; + } + + /** + * The constructor for indent + * + * @return void + * @since 3.2.0 + */ + private static function init() + { + // the default is TAB + self::$indent = Compiler::_('Config')->indentation_value; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Line.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Line.php new file mode 100644 index 000000000..45bdf9527 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Line.php @@ -0,0 +1,79 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; + + +/** + * The Debug Line Number Factory + * + * @since 3.2.0 + */ +abstract class Line +{ + /** + * Should we add debug lines + * + * @since 3.2.0 + **/ + private static $add = 'check'; + + /** + * Set the line number in comments + * + * @param int $nr The line number + * @param string $class The class name + * + * @return string + * @since 3.2.0 + */ + public static function _(int $nr, string $class): string + { + if (self::add()) + { + return ' [' . $class . ' ' . $nr . ']'; + } + + return ''; + } + + /** + * Check if we should add the line number + * + * @return bool + * @since 3.2.0 + */ + private static function add(): bool + { + if (!is_bool(self::$add)) + { + self::init(); + } + + return self::$add; + } + + /** + * The constructor for add + * + * @return void + * @since 3.2.0 + */ + private static function init() + { + self::$add = Compiler::_('Config')->debug_line_nr; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Minify.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Minify.php new file mode 100644 index 000000000..b6b4daacd --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Minify.php @@ -0,0 +1,91 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Minify\Css; +use VDM\Minify\JavaScript; + + +/** + * Compiler Minifier + * + * @since 3.2.0 + */ +abstract class Minify +{ + /** + * Minify JavaScript Class + * + * @var JavaScript + * @since 3.2.0 + */ + public static JavaScript $js; + + /** + * Minify Css Class + * + * @var Css + * @since 3.2.0 + */ + public static Css $css; + + /** + * Minify JavaScript + * + * @param string $data + * + * @return string + * @since 3.2.0 + */ + public static function js(string $data): string + { + // check if instance already set + if (empty(self::$js)) + { + // set instanceof on JavaScript + self::$js = new JavaScript; + } + + // add the data + self::$js->add($data); + + // return minified + return self::$js->minify(); + } + + /** + * Minify Css + * + * @param string $data + * + * @return string + * @since 3.2.0 + */ + public static function css(string $data): string + { + // check if instance already set + if (empty(self::$css)) + { + // set instanceof on Css + self::$css = new Css; + } + + // add the data + self::$css->add($data); + + // return minified + return self::$css->minify(); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Pathfix.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Pathfix.php new file mode 100644 index 000000000..e2208f7ec --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Pathfix.php @@ -0,0 +1,61 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Compiler Path Fix + * + * @since 3.2.0 + */ +class Pathfix +{ + /** + * Fix the path to work in the JCB script <-- (main issue here) + * Since we need / slash in all paths, for the JCB script even if it is Windows + * and since MS works with both forward and back slashes + * we just convert all slashes to forward slashes + * + * THIS is just my hack (fix) if you know a better way! speak-up! + * + * @param mixed $values the array of paths or the path as a string + * @param array $targets paths to target + * + * @return void + * @since 3.2.0 + */ + public function set(&$values, array $targets = []) + { + // if multiple to gets searched and fixed + if (ArrayHelper::check($values) && ArrayHelper::check($targets)) + { + foreach ($targets as $target) + { + if (isset($values[$target])) + { + $this->set($values[$target], $targets); + } + } + } + // if just a string + elseif (StringHelper::check($values) && strpos((string) $values, '\\') !== false) + { + $values = str_replace('\\', '/', (string) $values); + } + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Paths.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Paths.php new file mode 100644 index 000000000..f4a710478 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Paths.php @@ -0,0 +1,188 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Componentbuilder\Compiler\Component; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Compiler Utilities Paths + * + * @since 3.2.0 + */ +class Paths extends Registry +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + **/ + protected Config $config; + + /** + * Compiler Component + * + * @var Component + * @since 3.2.0 + **/ + protected Component $component; + + /** + * Constructor + * + * @param Config $config The compiler config object. + * @param Component $component The component class. + * + * @since 3.2.0 + */ + public function __construct(Config $config = null, Component $component = null) + { + $this->config = $config; + $this->component = $component; + + // set the template path + $this->setTemplatePath(); + + // set component sales name + $this->setComponentSalesName(); + + // set component backup name + $this->setComponentBackupName(); + + // set component folder name + $this->setComponentFolderName(); + + // set component path + $this->setComponentPath(); + + // set the template path for custom + $this->setTemplatePathCustom(); + } + + /** + * getting any valid paths + * + * @param string $key The value's key/path name + * + * @return string The path found as a string + * @since 3.2.0 + * @throws \InvalidArgumentException If $key is not a valid function name. + */ + public function __get(string $key): string + { + // check if it has been set + if ($this->exists($key)) + { + return $this->get($key); + } + + throw new \InvalidArgumentException(sprintf('Path %s could not be found in the Paths Class.', $key)); + } + + /** + * Set the template path + * + * @return void + * + * @since 3.2.0 + */ + private function setTemplatePath(): void + { + $this->set('template_path', + $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/joomla_' + . $this->config->joomla_versions[$this->config->joomla_version]['folder_key'] + ); + } + + /** + * Set component sales name + * + * @return void + * + * @since 3.2.0 + */ + private function setComponentSalesName(): void + { + $this->set('component_sales_name', + 'com_' . $this->component->get('sales_name') . '__J' + . $this->config->joomla_version + ); + } + + /** + * Set component backup name + * + * @return void + * + * @since 3.2.0 + */ + private function setComponentBackupName(): void + { + $this->set('component_backup_name', + 'com_' . $this->component->get('sales_name') . '_v' . str_replace( + '.', '_', (string) $this->component->get('component_version') + ) . '__J' . $this->config->joomla_version + ); + } + + /** + * Set component folder name + * + * @return void + * + * @since 3.2.0 + */ + private function setComponentFolderName(): void + { + $this->set('component_folder_name', + 'com_' . $this->component->get('name_code') . '_v' . str_replace( + '.', '_', (string) $this->component->get('component_version') + ) . '__J' . $this->config->joomla_version + ); + } + + /** + * Set component path + * + * @return void + * + * @since 3.2.0 + */ + private function setComponentPath(): void + { + $this->set('component_path', + $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/' + . $this->get('component_folder_name') + ); + } + + /** + * set the template path for custom TODO: just use custom_folder_path in config + * + * @return void + * + * @since 3.2.0 + */ + private function setTemplatePathCustom(): void + { + $this->set('template_path_custom', + $this->config->get( + 'custom_folder_path', JPATH_COMPONENT_ADMINISTRATOR . '/custom' + ) + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Placefix.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Placefix.php new file mode 100644 index 000000000..a7da9d08e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Placefix.php @@ -0,0 +1,106 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +/** + * The Placeholder Prefix and Suffix Factory + * + * @since 3.2.0 + */ +abstract class Placefix +{ + /** + * The hash prefix and suffix + * + * @var string + * @since 3.2.0 + **/ + private static string $hhh = '#' . '#' . '#'; + + /** + * The open prefix + * + * @var string + * @since 3.2.0 + **/ + private static string $bbb = '[' . '[' . '['; + + /** + * The close suffix + * + * @var string + * @since 3.2.0 + **/ + private static string $ddd = ']' . ']' . ']'; + + /** + * Get a prefix and suffix added to given string + * + * @param string $class The class name + * + * @return string + * @since 3.2.0 + */ + public static function _(string $string): string + { + return self::b() . $string . self::d(); + } + + /** + * Get a open prefix + * + * @return string + * @since 3.2.0 + */ + public static function b(): string + { + return self::$bbb; + } + + /** + * Get a close suffix + * + * @return string + * @since 3.2.0 + */ + public static function d(): string + { + return self::$ddd; + } + + /** + * Get a hash prefix and suffix added to given string + * + * @param string $class The class name + * + * @return string + * @since 3.2.0 + */ + public static function _h(string $string): string + { + return self::h() . $string . self::h(); + } + + /** + * Get a hash-fix + * + * @return string + * @since 3.2.0 + */ + public static function h(): string + { + return self::$hhh; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Structure.php new file mode 100644 index 000000000..ccef5d633 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Structure.php @@ -0,0 +1,313 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Filesystem\File as JoomlaFile; +use Joomla\CMS\Filesystem\Folder; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Component\Settings; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Compiler Utilities To Build Structure + * + * @since 3.2.0 + */ +class Structure +{ + /** + * Compiler Component Joomla Version Settings + * + * @var Settings + * @since 3.2.0 + */ + protected Settings $settings; + + /** + * Compiler Utilities Paths + * + * @var Paths + * @since 3.2.0 + */ + protected Paths $paths; + + /** + * Compiler Counter + * + * @var Counter + * @since 3.2.0 + */ + protected Counter $counter; + + /** + * Compiler Utilities File + * + * @var File + * @since 3.2.0 + */ + protected File $file; + + /** + * Compiler Utilities Files + * + * @var Files + * @since 3.2.0 + */ + protected Files $files; + + /** + * Database object to query local DB + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param Settings|null $settings The compiler component joomla version settings object. + * @param Paths|null $paths The compiler paths object. + * @param Counter|null $counter The compiler counter object. + * @param File|null $file The compiler file object. + * @param Files|null $files The compiler files object. + * @param CMSApplication|null $app The CMS Application object. + * + * @since 3.2.0 + * @throws \Exception + */ + public function __construct(?Settings $settings = null, ?Paths $paths = null, + ?Counter $counter = null, ?File $file = null, ?Files $files = null, + ?CMSApplication $app = null) + { + $this->settings = $settings ?: Compiler::_('Component.Settings'); + $this->paths = $paths ?: Compiler::_('Utilities.Paths'); + $this->counter = $counter ?: Compiler::_('Utilities.Counter'); + $this->file = $file ?: Compiler::_('Utilities.File'); + $this->files = $files ?: Compiler::_('Utilities.Files'); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * Build Structural Needed Files & Folders + * + * @param array $target The main target and name + * @param string $type The type in the target + * @param string|null $fileName The custom file name + * @param array|null $config To add more data to the files info + * + * @return bool true on success + * @since 3.2.0 + */ + public function build(array $target, string $type, + ?string $fileName = null, ?array $config = null): bool + { + // did we build the files (any number) + $build_status = false; + + // check that we have the target values + if (ArrayHelper::check($target)) + { + // search the target + foreach ($target as $main => $name) + { + // make sure it is lower case + $name = StringHelper::safe($name); + + // setup the files + foreach ($this->settings->multiple()->{$main} as $item => $details) + { + if ($details->type === $type) + { + $file_details = $this->getFileDetails( + $details, + (string) $item, + $name, + $fileName, + $config + ); + + if (is_array($file_details)) + { + // store the new files + $this->files->appendArray('dynamic.' . $file_details['view'], + $file_details); + + // we have build at least one + $build_status = true; + } + } + } + } + } + + return $build_status; + } + + /** + * Get the details + * + * @param object $details The item details + * @param string $item The item name + * @param string $name The given name + * @param string|null $fileName The custom file name + * @param array|null $config To add more data to the files info + * + * @return array|null The details + * @since 3.2.0 + */ + private function getFileDetails(object $details, string $item, + string $name, ?string $fileName = null, ?array $config = null): ?array + { + $zip_path = ''; + if (($path = $this->getPath($details, $zip_path, $name)) === null) + { + return null; + } + + // setup the folder + if (!Folder::exists($path)) + { + Folder::create($path); + $this->file->html($zip_path); + + // count the folder created + $this->counter->folder++; + } + + $new_name = $this->getNewName($details, $item, $name, $fileName); + + if (!JoomlaFile::exists($path . '/' . $new_name)) + { + // move the file to its place + JoomlaFile::copy( + $this->paths->template_path . '/' . $item, + $path . '/' . $new_name + ); + + // count the file created + $this->counter->file++; + } + + // we can't have dots in a view name + if (strpos($name, '.') !== false) + { + $name = preg_replace('/[\.]+/', '_', (string) $name); + } + + // setup array for new file + $file = [ + 'path' => $path . '/' . $new_name, + 'name' => $new_name, + 'view' => $name, + 'zip' => $zip_path . '/' . $new_name + ]; + + if (ArrayHelper::check($config)) + { + $file['config'] = $config; + } + + return $file; + } + + /** + * Get the path + * + * @param object $details The item details + * @param string $zipPath The zip path + * @param string $name The name + * + * @return string|null The path + * @since 3.2.0 + */ + private function getPath(object $details, string &$zipPath, string $name): ?string + { + // set destination path + if (strpos((string) $details->path, 'VIEW') !== false) + { + $path = str_replace('VIEW', $name, (string) $details->path); + } + else + { + $path = $details->path; + } + + // make sure we have component to replace + if (strpos((string) $path, 'c0mp0n3nt') !== false) + { + $zipPath = str_replace('c0mp0n3nt/', '', (string) $path); + + return str_replace( + 'c0mp0n3nt/', $this->paths->component_path . '/', (string) $path + ); + } + + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREECZEROMPZERONTHREENT_ISSUE_FOUNDHTHREEPTHE_PATH_S_COULD_NOT_BE_USEDP', + $path + ), 'Error' + ); + + return null; + } + + /** + * Get the new name + * + * @param object $details The item details + * @param string $item The item name + * @param string $name The name + * @param string|null $fileName The custom file name + * + * @return string The new name + * @since 3.2.0 + */ + private function getNewName(object $details, string $item, + string &$name, ?string $fileName = null): string + { + // do the file need renaming + if ($details->rename) + { + if (!empty($fileName)) + { + $name = $name . '_' . $fileName; + + return str_replace( + $details->rename, $fileName, $item + ); + } + elseif ($details->rename === 'new') + { + return $details->newName; + } + + return str_replace( + $details->rename, $name, $item + ); + } + + return $item; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Unique.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Unique.php new file mode 100644 index 000000000..b92611ad7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Unique.php @@ -0,0 +1,93 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +/** + * Compiler Creating an Unique Code/String + * + * @since 3.2.0 + */ +abstract class Unique +{ + /** + * Unique Code/Strings + * + * @var array + * @since 3.2.0 + */ + protected static array $unique = []; + + /** + * Unique Areas Code/Strings + * + * @var array + * @since 3.2.0 + */ + protected static array $areas = []; + + /** + * Creating an unique local key + * + * @param int $size The key size + * + * @return string The unique local key + * + */ + public static function get($size): string + { + $unique = (isset(self::$unique[$size])) ? end(self::$unique[$size]) : null; + + if(!$unique) + { + $unique = substr("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv", 0, $size); + + self::$unique[$size] = []; + } + + while(in_array($unique, self::$unique[$size])) + { + $unique++; + } + + self::$unique[$size][] = $unique; + + return $unique; + } + + /** + * Creating an Unique Code + * + * @param string $code + * @param string $target + * + * @return string + * @since 3.2.0 + */ + public static function code(string $code, string $target = 'both'): string + { + if (!isset(self::$areas[$target]) + || !in_array( + $code, self::$areas[$target] + )) + { + self::$areas[$target][] = $code; + + return $code; + } + + // make sure it is unique + return self::code($code . self::get(1)); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Xml.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Xml.php new file mode 100644 index 000000000..feb07b3c0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Xml.php @@ -0,0 +1,213 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Utilities; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Config; +use VDM\Joomla\Utilities\FormHelper; + + +/** + * Compiler Utilities Xml + * + * @since 3.2.0 + */ +final class Xml +{ + /** + * Compiler Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor + * + * @param Config|null $config The compiler config object. + * @param CMSApplication|null $app The CMS Application object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?CMSApplication $app = null) + { + $this->config = $config ?: Compiler::_('Config'); + $this->app = $app ?: Factory::getApplication(); + } + + /** + * get the field xml + * + * @param array $attributes The array of attributes + * @param array $options The options to apply to the XML element + * + * @return \SimpleXMLElement|null + * @since 3.2.0 + */ + public function get(array $attributes, ?array $options = null): ?\SimpleXMLElement + { + return FormHelper::xml($attributes, $options); + } + + /** + * xmlAppend + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param mixed $node A SimpleXMLElement node to append to the XML element reference, + * or a stdClass object containing a comment attribute to be injected + * before the XML node and a fieldXML attribute containing a SimpleXMLElement + * + * @return void + * @since 3.2.0 + */ + public function append(\SimpleXMLElement &$xml, $node) + { + FormHelper::append($xml, $node); + } + + /** + * xmlComment + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param string $comment The comment to inject + * + * @return void + * @since 3.2.0 + */ + public function comment(\SimpleXMLElement &$xml, string $comment) + { + FormHelper::comment($xml, $comment); + } + + /** + * xmlAddAttributes + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $attributes The attributes to apply to the XML element + * + * @return void + * @since 3.2.0 + */ + public function attributes(\SimpleXMLElement &$xml, array $attributes = []) + { + FormHelper::attributes($xml, $attributes); + } + + /** + * xmlAddOptions + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $options The options to apply to the XML element + * + * @return void + * @since 3.2.0 + */ + public function options(\SimpleXMLElement &$xml, array $options = []) + { + FormHelper::options($xml, $options); + } + + /** + * XML Pretty Print + * + * @param \SimpleXMLElement $xml The XML element containing a node to be output + * @param string $nodename node name of the input xml element to print out. this is done to omit the ownerDocument; + $dom->formatOutput = true; + $xmlString = $dom->saveXML( + $dom->getElementsByTagName($nodename)->item(0) + ); + // make sure Tidy is enabled + if ($this->config->get('tidy', false)) + { + $tidy = new \Tidy(); + $tidy->parseString( + $xmlString, [ + 'indent' => true, + 'indent-spaces' => 8, + 'input-xml' => true, + 'output-xml' => true, + 'indent-attributes' => true, + 'wrap-attributes' => true, + 'wrap' => false + ] + ); + $tidy->cleanRepair(); + + return $this->indent((string) $tidy, ' ', 8, true, false); + } + // set tidy warning only once + elseif ($this->config->set_tidy_warning) + { + // set the warning only once + $this->config->set('set_tidy_warning', false); + // now set the warning + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_HR_HTHREETIDY_ERRORHTHREE'), 'Error' + ); + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_YOU_MUST_ENABLE_THE_BTIDYB_EXTENSION_IN_YOUR_PHPINI_FILE_SO_WE_CAN_TIDY_UP_YOUR_XML_IF_YOU_NEED_HELP_PLEASE_A_SSTART_HEREA', 'href="https://github.com/vdm-io/Joomla-Component-Builder/issues/197#issuecomment-351181754" target="_blank"'), 'Error' + ); + } + + return $xmlString; + } + + /** + * xmlIndent + * + * @param string $string The XML input + * @param string $char Character or characters to use as the repeated indent + * @param int $depth number of times to repeat the indent character + * @param bool $skipfirst Skip the first line of the input. + * @param bool $skiplast Skip the last line of the input; + * + * @return string XML output + * @since 3.2.0 + */ + public function indent(string $string, string $char = ' ', int $depth = 0, + bool $skipfirst = false, bool $skiplast = false): string + { + $output = array(); + $lines = explode("\n", $string); + $first = true; + $last = count($lines) - 1; + foreach ($lines as $i => $line) + { + $output[] = (($first && $skipfirst) || $i === $last && $skiplast) + ? $line : str_repeat($char, $depth) . $line; + $first = false; + } + + return implode("\n", $output); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt.php new file mode 100644 index 000000000..f12608441 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt.php @@ -0,0 +1,284 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder; + + +use VDM\Joomla\Componentbuilder\Crypt\FOF; +use VDM\Joomla\Componentbuilder\Crypt\Aes; +use VDM\Joomla\Componentbuilder\Crypt\Aes\Legacy; +use VDM\Joomla\Componentbuilder\Crypt\Password; +use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Crypto Class + * + * @since 3.2.0 + */ +class Crypt +{ + /** + * The Crypt AES FOF class + * replacement class + * + * @var FOF + * @since 3.2.0 + */ + protected FOF $fof; + + /** + * The Crypt AES CBC class + * + * @var Aes + * @since 3.2.0 + */ + protected Aes $aes; + + /** + * The Crypt AES Legacy class + * + * @var Legacy + * @since 3.2.0 + */ + protected Legacy $legacy; + + /** + * The Password class + * + * @var Password + * @since 3.2.0 + */ + protected Password $password; + + /** + * Active encryption options + * + * @var array + * @since 3.2.0 + */ + protected array $options = [ + 'basic' => 'fof', + 'medium' => 'fof', + 'local' => 'aes' + ]; + + /** + * Active passwords + * + * @var array + * @since 3.2.0 + */ + protected array $passwords = []; + + /** + * Constructor + * + * @param FOF $fof The FOF class + * @param Aes $aes The AES CBC class + * @param Legacy $legacy The AES Legacy class + * @param Password $password The Password class + * + * @since 3.2.0 + */ + public function __construct(FOF $fof, Aes $aes, Legacy $legacy, Password $password) + { + $this->fof = $fof; + $this->aes = $aes; + $this->legacy = $legacy; + $this->password = $password; + } + + /** + * Encrypt a string as needed + * + * @param string $string The string to encrypt + * @param string $method The encryption method to use + * @param string|null $password The password + * + * @return string + * @since 3.2.0 + **/ + public function encrypt(string $string, string $method, + ?string $password = null): string + { + if (($password = $this->getPassword($method, $password)) !== null + && ($name = $this->getClassName($method)) !== null) + { + return $this->{$name}->encrypt($string, $password); + } + + return $string; + } + + /** + * Decrypt a string as needed + * + * @param string $string The string to decrypt + * @param string $method The encryption method to use + * @param string|null $default The default password + * + * @return string|null + * @since 3.2.0 + **/ + public function decrypt(string $string, string $method, + ?string $default = null): ?string + { + if (($password = $this->getPassword($method, $default)) !== null + && ($name = $this->getClassName($method)) !== null) + { + return $this->{$name}->decrypt($string, $password); + } + + return null; + } + + /** + * Check if a decryption method exist and is supported + * + * @param string $method The encryption method to find + * + * @return bool true if it exist + * @since 3.2.0 + **/ + public function exist(string $method): bool + { + return is_string($this->getClassName($method)) ?? false; + } + + /** + * Get crypto class name to use + * + * @param string $method The encryption method to find + * + * @return string|null The crypto class name + * @since 3.2.0 + **/ + private function getClassName(string $method): ?string + { + if (($name = $this->getClassNameFromRegistry($method)) !== null) + { + return $name; + } + + return $this->getClassNameFromOptions($method); + } + + /** + * Get the crypto class name from the registry + * + * @param string $method The encryption method to use + * + * @return string|null The crypto class name, or null if not found + * @since 3.2.0 + **/ + private function getClassNameFromRegistry(string $method): ?string + { + $name = $this->name($method); + + if (isset($this->{$name}) && $this->{$name} instanceof Cryptinterface) + { + return $name; + } + + return null; + } + + /** + * Get the crypto class name for the given encryption method and options + * + * @param string $method The encryption method to use + * + * @return string|null The crypto class name, or null if not found + * @since 3.2.0 + **/ + private function getClassNameFromOptions(string $method): ?string + { + $key = $this->getPasswordKey($method); + + if (isset($this->options[$key])) + { + $name = $this->options[$key]; + + if (isset($this->{$name}) && $this->{$name} instanceof Cryptinterface) + { + return $name; + } + } + + return null; + } + + /** + * Get the password + * + * @param string $method The encryption method to find + * @param string|null $password The password + * + * @return string|null the password or null + * @since 3.2.0 + **/ + private function getPassword(string $method, ?string $password = null): ?string + { + if (StringHelper::check($password)) + { + return $password; + } + + // get password key name + $key = $this->getPasswordKey($method); + + if (empty($this->passwords[$key])) + { + $this->passwords[$key] = $this->password->get($key); + } + + return $this->passwords[$key]; + } + + /** + * Get the key + * + * @param string $method The encryption method to find + * + * @return string the password key name + * @since 3.2.0 + **/ + private function getPasswordKey(string $method): string + { + if (($pos = strpos($method, '.')) !== false) + { + return substr($method, 0, $pos); + } + + return $method; + } + + /** + * Get the class name + * + * @param string $method The encryption method to find + * + * @return string the class name + * @since 3.2.0 + **/ + private function name(string $method): string + { + if (($pos = strpos($method, '.')) !== false) + { + return substr($method, $pos + 1); + } + + return $method; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes.php new file mode 100644 index 000000000..893691e79 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes.php @@ -0,0 +1,136 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Crypt; + + + +use phpseclib3\Crypt\AES as BASEAES; +use phpseclib3\Exception\BadDecryptionException; +use VDM\Joomla\Componentbuilder\Crypt\Random; +use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface; + + +/** + * Class for Aes Encryption + * + * @since 3.2.0 + */ +class Aes implements Cryptinterface +{ + /** + * The Aes class + * + * @var BASEAES + * @since 3.2.0 + */ + protected BASEAES $aes; + + /** + * The Random class + * + * @var Random + * @since 3.2.0 + */ + protected Random $random; + + /** + * The block size + * + * @var int + * @since 3.2.0 + */ + protected int $size = 256; + + /** + * Constructor + * + * @param BASEAES $aes The Aes class + * @param Random $random The Random class + * + * @since 3.2.0 + */ + public function __construct(BASEAES $aes, Random $random) + { + $this->aes = $aes; + $this->random = $random; + + // we set the length once + $this->aes->setKeyLength($this->size); + + // enable padding + $this->aes->enablePadding(); + } + + /** + * Encrypt a string as needed + * + * @param string $string The string to encrypt + * @param string $key The encryption key + * + * @return string + * @since 3.2.0 + **/ + public function encrypt(string $string, string $key): string + { + // we get the IV length + $iv_length = (int) $this->aes->getBlockLength() >> 3; + + // get the IV value + $iv = $this->random::string($iv_length); + + // Load the IV + $this->aes->setIV($iv); + + // set the password + $this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); + + // encrypt the string, and base 64 encode the result + return base64_encode($iv . $this->aes->encrypt($string)); + } + + /** + * Decrypt a string as needed + * + * @param string $string The string to decrypt + * @param string $key The decryption key + * + * @return string|null + * @since 3.2.0 + **/ + public function decrypt(string $string, string $key): ?string + { + // we get the IV length + $iv_length = (int) $this->aes->getBlockLength() >> 3; + + // remove base 64 encoding + $string = base64_decode($string); + + // get the IV + $iv = substr($string, 0, $iv_length); + + // remove the IV + $string = substr($string, $iv_length); + + // set the IV + $this->aes->setIV($iv); + + // set the password + $this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); + + try { + return $this->aes->decrypt($string); + } catch (\Exception $ex) { + return null; + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes/Legacy.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes/Legacy.php new file mode 100644 index 000000000..f7f4c8e49 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes/Legacy.php @@ -0,0 +1,120 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Crypt\Aes; + + +use phpseclib3\Crypt\AES as BASEAES; +use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface; + + +/** + * Legacy Class for Aes Encryption + * + * @since 3.2.0 + */ +class Legacy implements Cryptinterface +{ + /** + * The Aes class + * + * @var BASEAES + * @since 3.2.0 + */ + protected BASEAES $aes; + + /** + * The block size + * + * @var int + * @since 3.2.0 + */ + protected int $size = 128; + + /** + * Constructor + * + * @param BASEAES $aes The Aes class + * + * @since 3.2.0 + */ + public function __construct(BASEAES $aes) + { + $this->aes = $aes; + + // we set the length once + $this->aes->setKeyLength($this->size); + + // enable padding + $this->aes->enablePadding(); + } + + /** + * Encrypt a string as needed + * + * @param string $string The string to encrypt + * @param string $key The encryption key + * + * @return string + * @since 3.2.0 + **/ + public function encrypt(string $string, string $key): string + { + // we get the IV length + $iv_length = (int) $this->aes->getBlockLength() >> 3; + + // get the IV value + $iv = str_repeat("\0", $iv_length); + + // Load the IV + $this->aes->setIV($iv); + + // set the password + $this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); + + // encrypt the string, and base 64 encode the result + return base64_encode($this->aes->encrypt($string)); + } + + /** + * Decrypt a string as needed + * + * @param string $string The string to decrypt + * @param string $key The decryption key + * + * @return string|null + * @since 3.2.0 + **/ + public function decrypt(string $string, string $key): ?string + { + // remove base 64 encoding + $string = base64_decode($string); + + // we get the IV length + $iv_length = (int) $this->aes->getBlockLength() >> 3; + + // get the IV value + $iv = str_repeat("\0", $iv_length); + + // Load the IV + $this->aes->setIV($iv); + + // set the password + $this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt'); + + try { + return $this->aes->decrypt($string); + } catch (\Exception $ex) { + return null; + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Aes/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/FOF.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/FOF.php new file mode 100644 index 000000000..d9646928a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/FOF.php @@ -0,0 +1,64 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Crypt; + + +use VDM\Joomla\FOF\Encrypt\AES; +use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface; + + +/** + * Temp Class for FOFEncryptAes + * + * @since 3.2.0 + */ +class FOF implements Cryptinterface +{ + /** + * Encrypt a string as needed + * + * @param string $string The string to encrypt + * @param string $key The encryption key + * + * @return string + * @since 3.2.0 + **/ + public function encrypt(string $string, string $key): string + { + // Get the encryption object. + $aes = new Aes($key, 128); + + return $aes->decryptString($string); + } + + /** + * Decrypt a string as needed + * + * @param string $string The string to decrypt + * @param string $key The decryption key + * + * @return string|null + * @since 3.2.0 + **/ + public function decrypt(string $string, string $key): ?string + { + // Get the encryption object. + $aes = new Aes($key, 128); + + try { + return $aes->decryptString($string); + } catch (\Exception $ex) { + return null; + } + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/KeyLoader.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/KeyLoader.php new file mode 100644 index 000000000..e6ed5f0a1 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/KeyLoader.php @@ -0,0 +1,26 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Crypt; + + +use phpseclib3\Crypt\PublicKeyLoader; + + +/** + * KeyLoader Class + * + * @since 3.2.0 + */ +class KeyLoader extends PublicKeyLoader +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Password.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Password.php new file mode 100644 index 000000000..de5e7903c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Password.php @@ -0,0 +1,68 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Crypt; + + +use Joomla\CMS\Language\Text; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * Password Class + * + * @since 3.2.0 + */ +class Password +{ + /** + * Get the type of password + * Example: $this->get('basic', 'default-password'); + * + * @param string $type The value of password to get + * @param string|null $default The default password if the type is not found + * + * @return string|null + * @since 3.2.0 + */ + public function get(string $type, ?string $default = null): ?string + { + // we have a local key for JCB only use + if ('local' === $type) + { + return $this->local(); + } + elseif (($password = Helper::_('getCryptKey', [$type, $default])) !== null) + { + return $password; + } + + return $default; + } + + /** + * Get the local password + * + * @return string + * @since 3.2.0 + */ + private function local(): string + { + return base64_decode( + Text::sprintf( + 'COM_COMPONENTBUILDER_VJRZDESSMHBTRWFIFTYTWVZEROAESFLVVXJTMTHREEJTWOIXM', + 'QzdmV', '9kQ' + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Random.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Random.php new file mode 100644 index 000000000..48156844b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/Random.php @@ -0,0 +1,26 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Crypt; + + +use phpseclib3\Crypt\Random as CryptRandom; + + +/** + * Random Class + * + * @since 3.2.0 + */ +class Random extends CryptRandom +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Crypt/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Cryptinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Cryptinterface.php new file mode 100644 index 000000000..83a8a95d8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Cryptinterface.php @@ -0,0 +1,43 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Interfaces; + + +/** + * The Crypt Interface + */ +interface Cryptinterface +{ + /** + * Encrypt a string as needed + * + * @param string $string The string to encrypt + * @param string $key The encryption key + * + * @return string + * @since 3.2.0 + **/ + public function encrypt(string $string, string $key): string; + + /** + * Decrypt a string as needed + * + * @param string $string The string to decrypt + * @param string $key The decryption key + * + * @return string|null + * @since 3.2.0 + **/ + public function decrypt(string $string, string $key): ?string; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Serverinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Serverinterface.php new file mode 100644 index 000000000..7e14f783d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Serverinterface.php @@ -0,0 +1,42 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Interfaces; + + +/** + * The Core Server Interface + */ +interface Serverinterface +{ + /** + * set the server details + * + * @param object $details The server details + * + * @return self + * @since 3.2.0 + **/ + public function set(object $details); + + /** + * move a file to server with the FTP client + * + * @param string $localPath The full local path to the file + * @param string $fileName The file name + * + * @return bool + * @since 3.2.0 + **/ + public function move(string $localPath, string $fileName): bool; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/Insert.php new file mode 100644 index 000000000..800c8512b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/Insert.php @@ -0,0 +1,187 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Package\Database; + + +use Joomla\CMS\Factory as JoomlaFactory; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Search\Model\Insert as Model; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Package Database Insert + * + * @since 3.2.0 + */ +class Insert +{ + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search Table + * + * @var Table + * @since 3.2.0 + */ + protected Table $table; + + /** + * Search Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Table|null $table The search table object. + * @param Model|null $model The search get model object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Table $table = null, + ?Model $model = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->table = $table ?: Factory::_('Table'); + $this->model = $model ?: Factory::_('Set.Model'); + $this->db = $db ?: JoomlaFactory::getDbo(); + } + + /** + * Set values to a given table + * Example: $this->value(Value, 23, 'value_key', 'table_name'); + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function value($value, int $id, string $field, ?string $table = null): bool + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid field and table + if ($id > 0 && ($name = $this->table->get($table, $field, 'name')) !== null) + { + // build the object + $item = new \stdClass(); + $item->id = $id; + $item->{$name} = $this->model->value($value, $name, $table); + + // Update the column of this table using id as the primary key. + return $this->db->updateObject('#__componentbuilder_' . $table, $item, 'id'); + } + return false; + } + + /** + * Set values to a given table + * Example: $this->item(Object, 23, 'table_name'); + * + * @param object $item The item to save + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item, ?string $table = null): bool + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if (($fields = $this->table->fields($table)) !== null) + { + // model the item values + foreach ($fields as $field) + { + if (isset($item->{$field})) + { + $item->{$field} = $this->model->value($item->{$field}, $field, $table); + } + } + + // Update the column of this table using id as the primary key. + return $this->db->updateObject('#__componentbuilder_' . $table, $item, 'id'); + } + return false; + } + + /** + * Set values to a given table + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The items being saved + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function items(?array $items, string $table = null): bool + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if (ArrayHelper::check($items)) + { + $success = true; + foreach ($items as $item) + { + if (!$this->item($item, $table)) + { + $success = false; + break; + } + } + return $success; + } + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/Load.php new file mode 100644 index 000000000..57a7e0d64 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/Load.php @@ -0,0 +1,127 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Package\Database; + + +use VDM\Joomla\Componentbuilder\Package\Factory; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Database\Load as Database; + + +/** + * Package Database Load + * + * @since 3.2.0 + */ +class Load +{ + /** + * Search Table + * + * @var Table + * @since 3.2.0 + */ + protected Table $table; + + /** + * Database Load + * + * @var Database + * @since 3.2.0 + */ + protected Database $load; + + /** + * Constructor + * + * @param Table|null $table The core table object. + * @param Database|null $load The database object. + * + * @since 3.2.0 + */ + public function __construct(?Table $table = null, ?Database $load = null) + { + $this->table = $table ?: Factory::_('Table'); + $this->load = $load ?: Factory::_('Load'); + } + + /** + * Get a value from a given table + * Example: $this->value(23, 'value_key', 'table_name'); + * + * @param int $id The item ID + * @param string $field The field key + * @param string $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value(int $id, string $field, string $table) + { + // check if this is a valid table + if ($id > 0 && $this->table->exist($table, $field)) + { + return $this->load->value( + ["a.${field}" => $field], ['a' => $table], ['a.id' => $id] + ); + } + + return null; + } + + /** + * Get values from a given table + * Example: $this->item(23, 'table_name'); + * + * @param int $id The item ID + * @param string $table The table + * + * @return object|null + * @since 3.2.0 + */ + public function item(int $id, ?string $table): ?object + { + // check if this is a valid table + if ($id > 0 && $this->table->exist($table)) + { + return $this->load->item( + ['all' => 'a.*'], ['a' => $table], ['a.id' => $id] + ); + } + + return null; + } + + /** + * Get values from a given table + * Example: $this->items($ids, 'table_name'); + * + * @param array $ids The item ids + * @param string $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function items(array $ids, string $table): ?array + { + // check if this is a valid table + if ($this->table->exist($table)) + { + return $this->load->items( + ['all' => 'a.*'], ['a' => $table], ['a.id' => $ids] + ); + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Database/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Display/Details.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Display/Details.php new file mode 100644 index 000000000..9b63d9d96 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Display/Details.php @@ -0,0 +1,281 @@ + 'COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD', + 'owner' => 'COM_COMPONENTBUILDER_DTOWNERDTDDSDD', + 'email' => 'COM_COMPONENTBUILDER_DTEMAILDTDDSDD', + 'website' => 'COM_COMPONENTBUILDER_DTWEBSITEDTDDSDD', + 'license' => 'COM_COMPONENTBUILDER_DTLICENSEDTDDSDD', + 'copyright' => 'COM_COMPONENTBUILDER_DTCOPYRIGHTDTDDSDD' + ]; + + /** + * The Component details template + * + * @var array + * @since 3.2.0 + */ + private array $component = [ + 'ul' => [ + 'companyname' => 'COM_COMPONENTBUILDER_ICOMPANYI_BSB', + 'author' => 'COM_COMPONENTBUILDER_IAUTHORI_BSB', + 'email' => 'COM_COMPONENTBUILDER_IEMAILI_BSB', + 'website' => 'COM_COMPONENTBUILDER_IWEBSITEI_BSB', + ], + 'other' => [ + 'license' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP', + 'copyright' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP' + ] + ]; + + /** + * get the JCB package owner details display + * + * @param array $info The package info object + * @param bool $trust The trust switch + * + * @return string + * @since 3.2.0 + **/ + public function owner(array $info, $trust = false): string + { + $hasOwner = false; + + $ownerDetails = ''; + $ownerDetails .= '
'; + + // load the list items + foreach ($this->owner as $key => $dd) + { + if ($value = $this->getInfoValue($key, $info)) + { + $ownerDetails .= Text::sprintf($dd, $value); + + // check if we have a owner/source name + if (('owner' === $key || 'company' === $key) && !$hasOwner) + { + $hasOwner = true; + $owner = $value; + } + } + } + $ownerDetails .= '
'; + + // provide some details to how the user can get a key + if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && StringHelper::check($info['getKeyFrom']['buy_link'])) + { + $ownerDetails .= '
'; + $ownerDetails .= Text::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="' . $info['getKeyFrom']['buy_link'] . '" target="_blank" title="get a key from ' . $owner . '"', $owner); + } + // add more custom links + elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && ArrayHelper::check($info['getKeyFrom']['buy_links'])) + { + $buttons = array(); + foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link) + { + $buttons[] = Text::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA', $owner, 'class="btn btn-primary" href="' . $link . '" target="_blank" title="get a key from ' . $owner . '"', $keyName); + } + $ownerDetails .= '
'; + $ownerDetails .= implode('
', $buttons); + } + + // return the owner details + if (!$hasOwner) + { + $ownerDetails = '

' . Text::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND') . '

'; + + if (!$trust) + { + $ownerDetails .= '

' . Text::_('COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE') . '

'; + } + } + + return '
'.$ownerDetails.'
'; + } + + /** + * Check if info details has owner values set + * + * @param array $info The package info object + * + * @return bool + * @since 3.2.0 + **/ + public function hasOwner(array &$info): bool + { + if ($this->getInfoValue('owner', $info) || $this->getInfoValue('company', $info)) + { + return true; + } + + return false; + } + + /** + * get the JCB package components details display + * + * @param array $info The package info object + * + * @return string + * @since 3.2.0 + **/ + public function components(array &$info): string + { + // check if these components need a key + $needKey = $this->hasKey($info); + + if (isset($info['name']) && ArrayHelper::check($info['name'])) + { + $cAmount = count((array) $info['name']); + $class2 = ($cAmount == 1) ? 'span12' : 'span6'; + $counter = 1; + $display = array(); + foreach ($info['name'] as $key => $value) + { + // set the name + $name = $value . ' v' . $info['component_version'][$key]; + if ($cAmount > 1 && $counter == 3) + { + $display[] = ''; + $counter = 1; + } + if ($cAmount > 1 && $counter == 1) + { + $display[] = '
'; + } + $display[] = '
'; + $display[] = '

'; + $display[] = $name; + if ($needKey) + { + $display[] = ' - ' . Text::sprintf('COM_COMPONENTBUILDER_PAIDLOCKED') . ''; + } + else + { + $display[] = ' - ' . Text::sprintf('COM_COMPONENTBUILDER_FREEOPEN') . ''; + } + $display[] = '

'; + $display[] = $info['short_description'][$key]; + $display[] = '

'; + $display[] = '
    '; + + // load the list items + foreach ($this->component['ul'] as $li => $value) + { + if (isset($info[$li]) && isset($info[$li][$key])) + { + $display[] = '
  • '.Text::sprintf($value, $info[$li][$key]).'
  • '; + } + } + $display[] = '
'; + + // if we have a source link we add it + if (isset($info['joomla_source_link']) && ArrayHelper::check($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && StringHelper::check($info['joomla_source_link'][$key])) + { + $display[] = '' . Text::_('COM_COMPONENTBUILDER_SOURCE_CODE') . ''; + } + + // load other + foreach ($this->component['other'] as $other => $value) + { + if (isset($info[$other]) && isset($info[$other][$key])) + { + $display[] = Text::sprintf($value, $info[$other][$key]); + } + } + + $display[] = '
'; + + $counter++; + } + + // close the div if needed + if ($cAmount > 1) + { + $display[] = '
'; + } + + return implode(PHP_EOL, $display); + } + + return '
' . Text::_('COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE') . '
'; + } + + /** + * get the value from INFO array + * + * @param string $key The value key + * @param array $info The package info object + * + * @return string|null + * @since 3.2.0 + **/ + private function getInfoValue(string $key, array &$info): ?string + { + $source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : null); + if ($source && StringHelper::check($info[$source][$key])) + { + return $info[$source][$key]; + } + return null; + } + + /** + * Check if the JCB package has a key + * + * @param array $info The package info object + * + * @return bool + * @since 3.2.0 + **/ + private function hasKey(array &$info): bool + { + // check the package key status + if (!isset($info['key'])) + { + if (isset($info['getKeyFrom']) && isset($info['getKeyFrom']['owner'])) + { + // has a key + $info['key'] = true; + } + else + { + // does not have a key + $info['key'] = false; + } + } + + return (bool) $info['key']; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Display/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Display/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Display/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Factory.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Factory.php new file mode 100644 index 000000000..f6710bb4c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Factory.php @@ -0,0 +1,83 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Package; + + +use Joomla\DI\Container; +use VDM\Joomla\Componentbuilder\Service\Crypt; +use VDM\Joomla\Componentbuilder\Package\Service\Database; +use VDM\Joomla\Componentbuilder\Service\Server; +use VDM\Joomla\Componentbuilder\Package\Service\Display; +use VDM\Joomla\Interfaces\FactoryInterface; + + +/** + * Package Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Package Container + * + * @var Container + * @since 3.2.0 + **/ + protected static $container = null; + + /** + * Get any class from the package container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _($key) + { + return self::getContainer()->get($key); + } + + /** + * Get the global package container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Database()) + ->registerServiceProvider(new Crypt()) + ->registerServiceProvider(new Server()) + ->registerServiceProvider(new Display()); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/Database.php new file mode 100644 index 000000000..ecae6e5c4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/Database.php @@ -0,0 +1,112 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Package\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Database\Load; +use VDM\Joomla\Database\Insert; +use VDM\Joomla\Componentbuilder\Package\Database\Load as LoadDatabase; +use VDM\Joomla\Componentbuilder\Package\Database\Insert as InsertDatabase; + + +/** + * Database Service Provider + * + * @since 3.2.0 + */ +class Database implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Load::class, 'Load') + ->share('Load', [$this, 'getLoad'], true); + + $container->alias(Insert::class, 'Insert') + ->share('Insert', [$this, 'getInsert'], true); + + $container->alias(LoadDatabase::class, 'Load.Database') + ->share('Load.Database', [$this, 'getDatabaseLoad'], true); + + $container->alias(InsertDatabase::class, 'Insert.Database') + ->share('Insert.Database', [$this, 'getDatabaseInsert'], true); + } + + /** + * Get the Core Load Database + * + * @param Container $container The DI container. + * + * @return Load + * @since 3.2.0 + */ + public function getLoad(Container $container): Load + { + return new Load(); + } + + /** + * Get the Core Insert Database + * + * @param Container $container The DI container. + * + * @return Insert + * @since 3.2.0 + */ + public function getInsert(Container $container): Insert + { + return new Insert(); + } + + /** + * Get the Load Database + * + * @param Container $container The DI container. + * + * @return LoadDatabase + * @since 3.2.0 + */ + public function getDatabaseLoad(Container $container): LoadDatabase + { + return new LoadDatabase( + $container->get('Table'), + $container->get('Load') + ); + } + + /** + * Get the Insert Database + * + * @param Container $container The DI container. + * + * @return InsertDatabase + * @since 3.2.0 + */ + public function getDatabaseInsert(Container $container): InsertDatabase + { + return new InsertDatabase( + $container->get('Table'), + $container->get('Insert') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/Display.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/Display.php new file mode 100644 index 000000000..5dfbe4f9f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/Display.php @@ -0,0 +1,55 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Package\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Package\Display\Details; + + +/** + * Display Service Provider + * + * @since 3.2.0 + */ +class Display implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Details::class, 'Display.Details') + ->share('Display.Details', [$this, 'getDetails'], true); + } + + /** + * Get the Display Details + * + * @param Container $container The DI container. + * + * @return Details + * @since 3.2.0 + */ + public function getDetails(Container $container): Details + { + return new Details(); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Package/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Config.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Config.php new file mode 100644 index 000000000..8e0085333 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Config.php @@ -0,0 +1,266 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use Joomla\Registry\Registry as JoomlaRegistry; +use Joomla\CMS\Factory as JoomlaFactory; +use VDM\Joomla\Utilities\GetHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Abstraction\BaseConfig; + + +/** + * Compiler Configurations + * + * All these functions are accessed via the direct name without the get: + * example: $this->component_code_name calls: $this->getComponentcodename() + * + * All values once called are cached, yet can be updated directly: + * example: $this->component_code_name = 'new_code_name'; // be warned! + * + * @since 3.2.0 + */ +class Config extends BaseConfig +{ + /** + * The Global Joomla Configuration + * + * @var JoomlaRegistry + * @since 3.2.0 + */ + protected JoomlaRegistry $config; + + /** + * Constructor + * + * @param Input|null $input Input + * @param Registry|null $params The component parameters + * @param Registry|null $config The Joomla configuration + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Input $input = null, ?JoomlaRegistry $params = null, ?JoomlaRegistry $config = null) + { + parent::__construct($input, $params); + + $this->config = $config ?: JoomlaFactory::getConfig(); + } + + /** + * get Gitea Access Token + * + * @return string the access token + * @since 3.2.0 + */ + protected function getGiteatoken(): ?string + { + return $this->custom_gitea_token ?? $this->params->get('gitea_token'); + } + + /** + * get Add Custom Gitea URL + * + * @return int the add switch + * @since 3.2.0 + */ + protected function getAddcustomgiteaurl(): int + { + return $this->params->get('add_custom_gitea_url', 1); + } + + /** + * get Custom Gitea URL + * + * @return string the custom gitea url + * @since 3.2.0 + */ + protected function getCustomgiteaurl(): ?string + { + if ($this->add_custom_gitea_url == 2) + { + return $this->params->get('custom_gitea_url'); + } + + return null; + } + + /** + * get Custom Gitea Access Token + * + * @return string the custom access token + * @since 3.2.0 + */ + protected function getCustomgiteatoken(): ?string + { + if ($this->add_custom_gitea_url == 2) + { + return $this->params->get('custom_gitea_token'); + } + + return null; + } + + /** + * Get super power core organisation + * + * @return string The super power core organisation + * @since 3.2.0 + */ + protected function getSuperpowerscoreorganisation(): string + { + // the VDM default organisation is [joomla] + $organisation = 'joomla'; + + if ($this->add_custom_gitea_url == 2) + { + return $this->params->get('super_powers_core_organisation', $organisation); + } + + return $organisation; + } + + /** + * Get super power init repos + * + * @return array The init repositories on Gitea + * @since 3.2.0 + */ + protected function getSuperpowersinitrepos(): array + { + // some defaults repos we need by JCB + $repos = []; + + // only add custom init with custom gitea + $paths = null; + if ($this->add_custom_gitea_url == 2) + { + $paths = $this->params->get('super_powers_init_repos'); + } + + if (!empty($paths) && is_array($paths)) + { + foreach ($paths as $path) + { + $owner = $path->owner ?? null; + $repo = $path->repo ?? null; + if ($owner !== null && $repo !== null) + { + // we make sure to get only the objects + $repos = ["{$owner}.{$repo}" => $path] + $repos; + } + } + } + else + { + $repos[$this->super_powers_core_organisation . '.super-powers'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'super-powers', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.gitea'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'gitea', 'branch' => 'master']; + $repos[$this->super_powers_core_organisation . '.openai'] = (object) ['owner' => $this->super_powers_core_organisation, 'repo' => 'openai', 'branch' => 'master']; + } + + return $repos; + } + + /** + * get temporary path + * + * @return string The temporary path + * @since 3.2.0 + */ + protected function getTmppath(): string + { + // get the temporary path + return $this->config->get('tmp_path'); + } + + /** + * Get switch to add super powers + * + * @return bool Switch to add super powers + * @since 3.2.0 + */ + protected function getAddsuperpowers(): bool + { + return (bool) $this->params->get('powers_repository', 0); + } + + /** + * Get switch to add own super powers + * + * @return bool Switch to add own super powers + * @since 3.2.0 + */ + protected function getAddownpowers(): bool + { + if ($this->add_super_powers) + { + return (bool) $this->params->get('super_powers_repositories', 0); + } + + return false; + } + + /** + * Get local super powers repository path + * + * @return string The path to the local repository + * @since 3.2.0 + */ + protected function getLocalpowersrepositorypath(): string + { + $default = $this->tmp_path . '/super_powers'; + + if (!$this->add_super_powers) + { + return $default; + } + + return $this->params->get('local_powers_repository_path', $default); + } + + /** + * Get super power approved paths + * + * @return array The approved paths to the repositories on Gitea + * @since 3.2.0 + */ + protected function getApprovedpaths(): array + { + // some defaults repos we need by JCB + $approved = $this->super_powers_init_repos; + + if (!$this->add_own_powers) + { + return array_values($approved); + } + + $paths = $this->params->get('approved_paths'); + + if (!empty($paths)) + { + foreach ($paths as $path) + { + $owner = $path->owner ?? null; + $repo = $path->repo ?? null; + if ($owner !== null && $repo !== null) + { + // we make sure to get only the objects + $approved = ["{$owner}.{$repo}" => $path] + $approved; + } + } + } + + return array_values($approved); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Insert.php new file mode 100644 index 000000000..e01e5e046 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Insert.php @@ -0,0 +1,160 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Database; + + +use VDM\Joomla\Componentbuilder\Power\Model\Upsert as Model; +use VDM\Joomla\Database\Insert as Database; + + +/** + * Power Database Insert + * + * @since 3.2.0 + */ +final class Insert +{ + /** + * Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database + * + * @var Database + * @since 3.2.0 + */ + protected Database $database; + + /** + * Constructor + * + * @param Model $model The set model object. + * @param Database $database The insert database object. + * + * @since 3.2.0 + */ + public function __construct(Model $model, Database $database) + { + $this->model = $model; + $this->database = $database; + } + + /** + * Insert a value to a given table + * Example: $this->value(Value, 'value_key', 'GUID'); + * + * @param mixed $value The field value + * @param string $field The field key + * @param string $keyValue The key value + * @param string $key The key name + * + * @return bool + * @since 3.2.0 + */ + public function value($value, string $field, string $keyValue, string $key = 'guid'): bool + { + // build the array + $item = []; + $item[$key] = $keyValue; + $item[$field] = $value; + + // Insert the column of this table + return $this->row($item); + } + + /** + * Insert single row with multiple values to a given table + * Example: $this->item(Array); + * + * @param array $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function row(array $item): bool + { + // check if object could be modelled + if (($item = $this->model->row($item, 'power')) !== null) + { + // Insert the column of this table + return $this->database->row($item, 'power'); + } + return false; + } + + /** + * Insert multiple rows to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of arrays) + * + * @return bool + * @since 3.2.0 + */ + public function rows(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->rows($items, 'power')) !== null) + { + // Insert the column of this table + return $this->database->rows($items, 'power'); + } + return false; + } + + /** + * Insert single item with multiple values to a given table + * Example: $this->item(Object); + * + * @param object $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item): bool + { + // check if object could be modelled + if (($item = $this->model->item($item, 'power')) !== null) + { + // Insert the column of this table + return $this->database->item($item, 'power'); + } + return false; + } + + /** + * Insert multiple items to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of objects) + * + * @return bool + * @since 3.2.0 + */ + public function items(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->items($items, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->items($items, 'power'); + } + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Load.php new file mode 100644 index 000000000..42f5632d8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Load.php @@ -0,0 +1,158 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Database; + + +use VDM\Joomla\Componentbuilder\Power\Model\Load as Model; +use VDM\Joomla\Database\Load as Database; + + +/** + * Power Database Load + * + * @since 2.0.1 + */ +final class Load +{ + /** + * Model Load + * + * @var Model + * @since 2.0.1 + */ + protected Model $model; + + /** + * Database Load + * + * @var Database + * @since 2.0.1 + */ + protected Database $load; + + /** + * Constructor + * + * @param Table $table The core table object. + * @param Model $model The model object. + * @param Database $load The database object. + * + * @since 2.0.1 + */ + public function __construct(Model $model, Database $load) + { + $this->model = $model; + $this->load = $load; + } + + /** + * Get a value from a given table + * Example: $this->value( + * [ + * 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + * ], 'value_key' + * ); + * + * @param array $keys The item keys + * @param string $field The field key + * @param string $table The table + * + * @return mixed + * @since 2.0.1 + */ + public function value(array $keys, string $field) + { + return $this->model->value( + $this->load->value( + ["a.${field}" => $field], + ['a' => 'power'], + $this->prefix($keys) + ), + $field, + 'power' + ); + } + + /** + * Get values from a given table + * Example: $this->item( + * [ + * 'guid' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + * ] + * ); + * + * @param array $keys The item keys + * @param string $table The table + * + * @return object|null + * @since 2.0.1 + */ + public function item(array $keys): ?object + { + return $this->model->item( + $this->load->item( + ['all' => 'a.*'], + ['a' => 'power'], + $this->prefix($keys) + ), + 'power' + ); + } + + /** + * Get values from a given table + * Example: $this->items( + * [ + * 'guid' => [ + * 'operator' => 'IN', + * 'value' => [''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'', ''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx''] + * ] + * ] + * ); + * Example: $this->items($ids, 'table_name'); + * + * @param array $keys The item keys + * @param string $table The table + * + * @return array|null + * @since 2.0.1 + */ + public function items(array $keys): ?array + { + return $this->model->items( + $this->load->items( + ['all' => 'a.*'], ['a' => 'power'], $this->prefix($keys) + ), + 'power' + ); + } + + /** + * Add prefix to the keys + * + * @param array $keys The query keys + * + * @return array + * @since 2.0.1 + */ + private function prefix(array &$keys): array + { + // update the key values + $bucket = []; + foreach ($keys as $k => $v) + { + $bucket['a.' . $k] = $v; + } + return $bucket; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Update.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Update.php new file mode 100644 index 000000000..c2e65a5f3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Update.php @@ -0,0 +1,159 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Database; + + +use VDM\Joomla\Componentbuilder\Power\Model\Upsert as Model; +use VDM\Joomla\Database\Update as Database; + + +/** + * Power Database Update + * + * @since 3.2.0 + */ +final class Update +{ + /** + * Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database + * + * @var Database + * @since 3.2.0 + */ + protected Database $database; + + /** + * Constructor + * + * @param Model $model The set model object. + * @param Database $database The update database object. + * + * @since 3.2.0 + */ + public function __construct(Model $model, Database $database) + { + $this->model = $model; + $this->database = $database; + } + + /** + * Update a value to a given table + * Example: $this->value(Value, 'value_key', 'GUID'); + * + * @param mixed $value The field value + * @param string $field The field key + * @param string $keyValue The key value + * @param string $key The key name + * + * @return bool + * @since 3.2.0 + */ + public function value($value, string $field, string $keyValue, string $key = 'guid'): bool + { + // build the array + $item = []; + $item[$key] = $keyValue; + $item[$field] = $value; + + // Update the column of this table using guid as the primary key. + return $this->row($item); + } + + /** + * Update single row with multiple values to a given table + * Example: $this->item(Array); + * + * @param array $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function row(array $item): bool + { + // check if object could be modelled + if (($item = $this->model->row($item, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->row($item, 'guid', 'power'); + } + return false; + } + + /** + * Update multiple rows to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of arrays) + * + * @return bool + * @since 3.2.0 + */ + public function rows(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->rows($items, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->rows($items, 'guid', 'power'); + } + return false; + } + + /** + * Update single item with multiple values to a given table + * Example: $this->item(Object); + * + * @param object $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item): bool + { + // check if object could be modelled + if (($item = $this->model->item($item, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->item($item, 'guid', 'power'); + } + return false; + } + + /** + * Update multiple items to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of objects) + * + * @return bool + * @since 3.2.0 + */ + public function items(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->items($items, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->items($items, 'guid', 'power'); + } + return false; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Factory.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Factory.php new file mode 100644 index 000000000..c3ef0491c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Factory.php @@ -0,0 +1,88 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use Joomla\DI\Container; +use VDM\Joomla\Componentbuilder\Power\Service\Power; +use VDM\Joomla\Componentbuilder\Service\Database; +use VDM\Joomla\Componentbuilder\Power\Service\Database as PowerDatabase; +use VDM\Joomla\Componentbuilder\Power\Service\Generator; +use VDM\Joomla\Componentbuilder\Service\Gitea; +use VDM\Joomla\Componentbuilder\Power\Service\Gitea as GiteaPower; +use VDM\Joomla\Gitea\Service\Utilities as GiteaUtilities; +use VDM\Joomla\Interfaces\FactoryInterface; + + +/** + * Power Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Package Container + * + * @var Container + * @since 3.2.0 + **/ + protected static $container = null; + + /** + * Get any class from the package container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _($key) + { + return self::getContainer()->get($key); + } + + /** + * Get the global package container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Power()) + ->registerServiceProvider(new Database()) + ->registerServiceProvider(new PowerDatabase()) + ->registerServiceProvider(new Generator()) + ->registerServiceProvider(new Gitea()) + ->registerServiceProvider(new GiteaPower()) + ->registerServiceProvider(new GiteaUtilities()); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator.php new file mode 100644 index 000000000..8259e1929 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator.php @@ -0,0 +1,85 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use VDM\Joomla\Componentbuilder\Power\Generator\ClassInjectorBuilder as ClassInjector; +use VDM\Joomla\Componentbuilder\Power\Generator\ServiceProviderBuilder as ServiceProvider; + + +/** + * Power code Generator of JCB + * + * @since 3.2.0 + */ +final class Generator +{ + /** + * The ClassInjectorBuilder Class. + * + * @var ClassInjector + * @since 3.2.0 + */ + protected ClassInjector $classinjector; + + /** + * The ServiceProviderBuilder Class. + * + * @var ServiceProvider + * @since 3.2.0 + */ + protected ServiceProvider $serviceprovider; + + /** + * Constructor. + * + * @param ClassInjector $classinjector The ClassInjectorBuilder Class. + * @param ServiceProvider $serviceprovider The ServiceProviderBuilder Class. + * + * @since 3.2.0 + */ + public function __construct(ClassInjector $classinjector, ServiceProvider $serviceprovider) + { + $this->classinjector = $classinjector; + $this->serviceprovider = $serviceprovider; + } + + /** + * Get the class code. + * + * @param array $power The power being saved + * + * @return string|null + * @since 3.2.0 + */ + public function get(array $power): ?string + { + // create dependency injection (when the main_class_code is empty) + if (empty($power['main_class_code']) && !empty($power['use_selection']) && is_array($power['use_selection'])) + { + if (strpos($power['implements_custom'], 'ServiceProviderInterface') !== false) + { + if (($code = $this->serviceprovider->getCode($power)) !== null) + { + return $code; + } + } + elseif (($code = $this->classinjector->getCode($power)) !== null) + { + return $code; + } + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/Bucket.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/Bucket.php new file mode 100644 index 000000000..bf2ee7be6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/Bucket.php @@ -0,0 +1,27 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Generator; + + +use VDM\Joomla\Interfaces\Registryinterface; +use VDM\Joomla\Abstraction\Registry; + + +/** + * Power Bucket + * + * @since 3.2.0 + */ +final class Bucket extends Registry implements Registryinterface +{ +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ClassInjector.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ClassInjector.php new file mode 100644 index 000000000..8f2f41913 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ClassInjector.php @@ -0,0 +1,246 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Generator; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Power code Generator for the Class Injection of JCB + * + * @since 3.2.0 + */ +final class ClassInjector +{ + /** + * The version + * + * @var string + * @since 3.2.0 + **/ + protected string $version; + + /** + * The properties + * + * @var array + * @since 3.2.0 + **/ + protected array $properties = []; + + /** + * The comments + * + * @var array + * @since 3.2.0 + **/ + protected array $comments = []; + + /** + * The arguments + * + * @var array + * @since 3.2.0 + **/ + protected array $arguments = []; + + /** + * The assignments + * + * @var array + * @since 3.2.0 + **/ + protected array $assignments = []; + + /** + * Get the generated class code + * + * @return string|null + * @since 3.2.0 + */ + public function getCode(): ?string + { + if ($this->properties === []) + { + return null; + } + + $code = []; + + $code[] = implode(PHP_EOL . PHP_EOL, $this->properties) . PHP_EOL; + $code[] = Indent::_(1) . "/**"; + $code[] = Indent::_(1) . " * Constructor."; + $code[] = Indent::_(1) . " *"; + $code[] = $this->getComments(); + $code[] = Indent::_(1) . " *"; + $code[] = Indent::_(1) . " * @since {$this->version}"; + $code[] = Indent::_(1) . " */"; + $code[] = Indent::_(1) . "public function __construct(" . $this->getArguments() . ")"; + $code[] = Indent::_(1) . "{"; + $code[] = implode(PHP_EOL, $this->assignments); + $code[] = Indent::_(1) . "}"; + + $this->properties = []; + $this->comments = []; + $this->arguments = []; + $this->assignments = []; + + return implode(PHP_EOL, $code); + } + + /** + * Set the class since version + * + * @param string $version The variable version format. + * + * @return void + * @since 3.2.0 + */ + public function setVersion(string $version): void + { + $this->version = $version; + } + + /** + * Set the class property + * + * @param string $classname The variable name in lowerCamelCase format. + * @param string $ClassName The type hint in PascalCase format. + * @param string $description The variable description format. + * + * @return void + * @since 3.2.0 + */ + public function setProperty(string $classname, string $ClassName, string $description): void + { + $this->properties[] = implode(PHP_EOL, [ + Indent::_(1) . "/**", + Indent::_(1) . " * {$description}", + Indent::_(1) . " *", + Indent::_(1) . " * @var {$ClassName}", + Indent::_(1) . " * @since {$this->version}", + Indent::_(1) . " */", + Indent::_(1) . "protected {$ClassName} \${$classname};" + ]); + } + + /** + * Set the comment for the constructor parameter. + * + * @param string $classname The variable name in lowerCamelCase format. + * @param string $ClassName The type hint in PascalCase format. + * @param string $description The variable description format. + * + * @return void + * @since 3.2.0 + */ + public function setComment(string $classname, string $ClassName, string $description): void + { + $this->comments[] = [$ClassName, $classname, $description]; + } + + /** + * Set the constructor argument. + * + * @param string $classname The variable name in lowerCamelCase format. + * @param string $ClassName The type hint in PascalCase format. + * + * @return void + * @since 3.2.0 + */ + public function setArgument(string $classname, string $ClassName): void + { + $this->arguments[] = "{$ClassName} \${$classname}"; + } + + /** + * Set the assignment code inside the constructor. + * + * @param string $classname The variable name in lowerCamelCase format. + * + * @return void + * @since 3.2.0 + */ + public function setAssignment(string $classname): void + { + $this->assignments[] = Indent::_(2) . "\$this->{$classname} = \${$classname};"; + } + + /** + * Get the comments for the constructor parameter. + * + * @return string + * @since 3.2.0 + */ + private function getComments(): string + { + $max_lengths = array_reduce($this->comments, function($carry, $comment) { + foreach ($comment as $index => $part) + { + $carry[$index] = max($carry[$index] ?? 0, strlen($part)); + } + return $carry; + }, []); + + $max_lengths[0] = $max_lengths[0] + 2; + $max_lengths[1] = $max_lengths[1] + 2; + + $comments = array_map(function($comment) use ($max_lengths) { + return Indent::_(1) . " * @param " . + str_pad($comment[0], $max_lengths[0]) . " $" . + str_pad($comment[1], $max_lengths[1]) . " " . + $comment[2]; + }, $this->comments); + + return implode(PHP_EOL, $comments); + } + + /** + * Format the arguments to ensure they fit within a specified line length. + * Arguments are added to the line until the max length is reached. + * Then, they are pushed to a new line with appropriate indentation. + * + * @return string Formatted arguments + * @since 3.2.0 + */ + private function getArguments(): string + { + $maxLength = 60; // or any other preferred line length + $lines = []; + $currentLineContent = ''; + + foreach ($this->arguments as $argument) + { + $proposedContent = $currentLineContent ? $currentLineContent . ', ' . $argument : $argument; + + if (strlen($proposedContent) >= $maxLength) + { + $lines[] = $currentLineContent; + $currentLineContent = Indent::_(2) . $argument; + } + else + { + $currentLineContent = $proposedContent; + } + } + + // Append the last line if it has content + if ($currentLineContent) + { + $lines[] = $currentLineContent; + } + + return implode(',' . PHP_EOL, $lines); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ClassInjectorBuilder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ClassInjectorBuilder.php new file mode 100644 index 000000000..e3a234c88 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ClassInjectorBuilder.php @@ -0,0 +1,251 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Generator; + + +use VDM\Joomla\Componentbuilder\Power\Generator\Search; +use VDM\Joomla\Componentbuilder\Power\Generator\ClassInjector; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Power Class Injector Builder of JCB + * + * @since 3.2.0 + */ +final class ClassInjectorBuilder +{ + /** + * The Search Class. + * + * @var Search + * @since 3.2.0 + */ + protected Search $search; + + /** + * The Class Injector Class. + * + * @var ClassInjector + * @since 3.2.0 + */ + protected ClassInjector $classinjector; + + /** + * Constructor. + * + * @param Search $search The Search Class. + * @param ClassInjector $classinjector The Class Injector Class. + * + * @since 3.2.0 + */ + public function __construct(Search $search, ClassInjector $classinjector) + { + $this->search = $search; + $this->classinjector = $classinjector; + } + + /** + * Get the injection code. + * + * @param array $power The power being saved + * + * @return string|null + * @since 3.2.0 + */ + public function getCode(array $power): ?string + { + $this->setVersion($this->extractSinceVersion($power['description']) ?? $power['power_version'] ?? '1.0.0'); + + foreach ($power['use_selection'] as $use_selection) + { + if (!$this->valid($use_selection['use'])) + { + continue; + } + + if (($name = $this->getName($use_selection['use'], $use_selection['as'])) === null) + { + continue; + } + + if (($description = $this->getDescription($use_selection['use'])) === null) + { + continue; + } + + $this->setProperty($name, $description); + $this->setComment($name, $description); + $this->setArgument($name); + $this->setAssignment($name); + } + + return $this->getDependencyInjectionCode(); + } + + /** + * Check that this is a valid injection class. + * + * @param string $guid The class GUID of the power + * + * @return bool + * @since 3.2.0 + */ + private function valid(string $guid): bool + { + return $this->search->validInject($guid); + } + + /** + * Get the class name. + * + * @param string $guid The class GUID of the power + * @param string $as The as name + * + * @return string|null + * @since 3.2.0 + */ + private function getName(string $guid, string $as = 'default'): ?string + { + return $this->search->name($guid, $as); + } + + /** + * Get the class description. + * + * @param string $guid The class GUID of the power + * + * @return string|null + * @since 3.2.0 + */ + private function getDescription(string $guid): ?string + { + return $this->search->description($guid); + } + + /** + * Get the dependency injection code. + * + * @return string|null + * @since 3.2.0 + */ + private function getDependencyInjectionCode(): ?string + { + return $this->classinjector->getCode(); + } + + /** + * Set the class since version. + * + * @param string $version The class since version + * + * @return void + * @since 3.2.0 + */ + private function setVersion(string $version): void + { + $this->classinjector->setVersion($version); + } + + /** + * Set the class property. + * + * @param string $name The class name + * @param string $description The class description + * + * @return void + * @since 3.2.0 + */ + private function setProperty(string $name, string $description): void + { + $this->classinjector->setProperty( + strtolower($name), + $name, + $description + ); + } + + /** + * Set the class comment for the constructor parameter. + * + * @param string $name The class name + * @param string $description The class description + * + * @return void + * @since 3.2.0 + */ + private function setComment(string $name, string $description): void + { + $this->classinjector->setComment( + strtolower($name), + $name, + $description + ); + } + + /** + * Set the class constructor argument. + * + * @param string $name The class name + * + * @return void + * @since 3.2.0 + */ + private function setArgument(string $name): void + { + $this->classinjector->setArgument( + strtolower($name), + $name + ); + } + + /** + * Get the assignment code inside the constructor. + * + * @param string $name The class name + * + * @return void + * @since 3.2.0 + */ + private function setAssignment(string $name): void + { + $this->classinjector->setAssignment( + strtolower($name) + ); + } + + /** + * Extract the '@since' version number from a given string. + * + * This function checks the provided string for a '@since' annotation + * and retrieves the subsequent version number. If no '@since' + * annotation is found or no version number is provided after the + * annotation, the function will return null. + * + * @param string $inputString The input string to search. + * + * @return string|null The version number if found, or null if not. + * @since 3.2.0 + */ + private function extractSinceVersion(string $inputString): ?string + { + // Use regex to match the @since pattern and capture the version number + if (preg_match('/@since\s+([\d\.]+)/', $inputString, $matches)) + { + return $matches[1]; + } + + // If no match is found, return null + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/Search.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/Search.php new file mode 100644 index 000000000..25cb6c8e2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/Search.php @@ -0,0 +1,496 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Generator; + + +use VDM\Joomla\Componentbuilder\Power\Database\Load as Database; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Power\Generator\Bucket; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; + + +/** + * Power code Generator Search of JCB + * + * @since 3.2.0 + */ +final class Search +{ + /** + * The Database Class + * + * @var Database + * @since 3.2.0 + **/ + protected Database $database; + + /** + * The Code Parser Class + * + * @var Parser + * @since 3.2.0 + **/ + protected Parser $parser; + + /** + * The found powers + * + * @var Bucket + * @since 3.2.0 + **/ + protected Bucket $bucket; + + /** + * Constructor. + * + * @param Database $database The Database object. + * @param Parser $parser The parser object. + * @param Bucket $bucket The bucket object. + * + * @since 3.2.0 + */ + public function __construct(Database $database, Parser $parser, Bucket $bucket) + { + $this->database = $database; + $this->parser = $parser; + $this->bucket = $bucket; + } + + /** + * Get the power object + * + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + public function power(string $guid): ?object + { + if (($power = $this->bucket->get("power.{$guid}")) === null) + { + if (($power = $this->database->item(['guid' => $guid])) === null) + { + return null; + } + + $this->bucket->set("power.{$guid}", $power); + } + + return $power; + } + + /** + * Get the power alias to use in container calls + * + * @param string $guid The global unique id of the power + * @param string $className The current class name + * + * @return string + * @since 3.2.0 + */ + public function alias(string $guid, string $className): string + { + if (($alias = $this->bucket->get("alias.{$guid}")) !== null) + { + return $alias; + } + + // load the service providers where its already linked + if (($service_providers = $this->serviceProviders($guid)) !== null) + { + foreach ($service_providers as $service_provider) + { + $dependency_name = $this->getServiceProviderDependencyName($service_provider, $guid) ?? $className; + + if (($alias = $this->getAliasFromServiceProvider($service_provider, $dependency_name)) === null) + { + continue; + } + + break; + } + } + + if (empty($alias)) + { + // build it based on the class name and namespace of this power + $alias = $this->getAliasFromPower($guid); + } + + // finally we set the alias for later use + $alias = $alias ?? "Set.Me.$className"; + $alias = trim($alias); + $this->bucket->set("alias.{$guid}", $alias); + + return $alias; + } + + /** + * Check if a power class is valid to inject into another class + * + * @param string $guid The global unique id of the power + * + * @return bool True if class can (should) be injected + * @since 3.2.0 + */ + public function validInject(string $guid): bool + { + if (($valid_inject = $this->bucket->get("valid_inject.{$guid}")) !== null) + { + return $valid_inject; + } + + if (($power = $this->power($guid)) === null) + { + return false; + } + + // Types: [class, abstract class, final class, interface, trait] + // Allowed: [class, final class, interface] + if ($power->type === 'class' || $power->type === 'final class' || $power->type === 'interface') + { + $this->bucket->set("valid_inject.{$guid}", true); + + return true; + } + + $this->bucket->set("valid_inject.{$guid}", false); + + return false; + } + + /** + * Get the power class name + * + * @param string $guid The global unique id of the power + * @param string $as The use AS value + * + * @return string|null + * @since 3.2.0 + */ + public function name(string $guid, string $as = 'default'): ?string + { + if ($as !== 'default') + { + return $as; + } + + if (($name = $this->bucket->get("name.{$guid}")) !== null) + { + return $name; + } + + if (($power = $this->power($guid)) === null) + { + return null; + } + + if (strpos($power->name, '[') !== false) + { + $name = 'DynamicClassName'; + } + else + { + $name = ClassfunctionHelper::safe($power->name); + } + + $name = trim($name); + $this->bucket->set("name.{$guid}", $name); + + return $name; + } + + /** + * Get the power class description + * + * @param string $guid The global unique id of the power + * + * @return string|null + * @since 3.2.0 + */ + public function description(string $guid): ?string + { + if (($description = $this->bucket->get("description.{$guid}")) !== null) + { + return $description; + } + + if (($power = $this->power($guid)) === null) + { + return null; + } + + if (strpos($power->name, '[') !== false) + { + $description = 'The Dynamic {$power->name} Name'; + } + else + { + $description = "The {$power->name} Class."; + } + + $this->bucket->set("description.{$guid}", $description); + + return $description; + } + + /** + * Get all service providers where this power is linked + * + * @param string $guid The global unique id of the power + * + * @return array|null + * @since 3.2.0 + */ + public function serviceProviders(string $guid): ?array + { + if (($service_providers = $this->bucket->get("service_providers.{$guid}")) === null) + { + if (($powers = $this->database->items([ + 'use_selection' => [ + 'operator' => 'LIKE', + 'value' => "'%{$guid}%'", + 'quote' => false + ], + 'implements_custom' => [ + 'operator' => 'LIKE', + 'value' => "'%ServiceProviderInterface%'", + 'quote' => false + ] + ])) === null) + { + return null; + } + + $service_providers = []; + foreach ($powers as $power) + { + $this->bucket->set("power.{$power->guid}", $power); + $service_providers[] = $power->guid; + } + + $this->bucket->set("service_providers.{$guid}", $service_providers); + } + + return $service_providers; + } + + /** + * Get all the power dependencies + * + * @param string $guid The global unique id of the power + * + * @return array|null + * @since 3.2.0 + */ + public function dependencies(string $guid): ?array + { + if (($dependencies = $this->bucket->get("dependencies.{$guid}")) !== null) + { + return $dependencies; + } + + if (($power = $this->power($guid)) === null) + { + return null; + } + + if (empty($power->use_selection) || !is_object($power->use_selection)) + { + return null; + } + + $dependencies = []; + foreach ($power->use_selection as $use_selection) + { + if (!$this->validInject($use_selection->use)) + { + continue; + } + + if (($name = $this->name($use_selection->use, $use_selection->as)) === null) + { + continue; + } + + $dependencies[] = $this->alias($use_selection->use, $name); + } + + if ($dependencies === []) + { + return null; + } + + $this->bucket->set("dependencies.{$guid}", $dependencies); + + return $dependencies; + } + + /** + * Retrieves the alias form linked service provider. + * + * @param string $guid The global unique id of the power + * @param string $className The current class name + * + * @return string|null Returns the alias if found, otherwise returns null. + * @since 3.2.0 + */ + private function getAliasFromServiceProvider(string $guid, string $className): ?string + { + if (($power = $this->power($guid)) === null || empty($power->main_class_code)) + { + return null; + } + + $code = $this->parser->code($power->main_class_code); + + if (empty($code['methods'])) + { + return null; + } + + $method = null; + + foreach ($code['methods'] as $_method) + { + if ($_method['name'] === 'register' && strlen($_method['body']) > 5) + { + $method = $_method['body']; + break; + } + } + + if (empty($method)) + { + return null; + } + + return $this->getAliasFromRegisterMethod($method, $className); + } + + /** + * Retrieves the alias for a given class from a provided string. + * + * @param string $content The string to search. + * @param string $className The name of the class whose alias is to be retrieved. + * + * @return string|null Returns the alias if found, otherwise returns null. + * @since 3.2.0 + */ + private function getAliasFromRegisterMethod(string $content, string $className): ?string + { + + // Escaping any special characters in the class name to use in regex + $escapedClassName = preg_quote($className, '/'); + + // Regular expression to match the pattern where class name and its alias are specified + $pattern = "/\\\$container->alias\s*\(\s*{$escapedClassName}::class\s*,\s*['\"](.*?)['\"]\s*\)\s*->/s"; + + if (preg_match($pattern, $content, $matches)) + { + return $matches[1]; + } + + return null; + } + + /** + * Retrieves the alias form linked service provider. + * + * @param string $guid The global unique id of the power + * + * @return string|null Returns the alias if found, otherwise returns null. + * @since 3.2.0 + */ + private function getAliasFromPower(string $guid): ?string + { + if (($power = $this->power($guid)) === null || empty($power->namespace)) + { + return null; + } + + return $this->getAliasFromNamespace($power->namespace); + } + + /** + * Converts the namespace of a power into an class alias + * + * @param string $input The namespaced string to process. + * + * @return string The modified string. + * @since 3.2.0 + */ + private function getAliasFromNamespace(string $input): string + { + // 1. Split on backslash to get the components of the namespace path. + $parts = explode('\\', $input); + + // 2. Consider only the last part after the final backslash for further processing. + $lastSegment = end($parts); + + // 3. Get the part after the first dot. + $target = (strpos($lastSegment, '.') !== false) + ? substr($lastSegment, strpos($lastSegment, '.') + 1) + : $lastSegment; + + // 4. Split on dots. + $dotParts = explode('.', $target); + + // 5. Modify segments with camel case words. + $modifiedDotParts = array_map(function ($part) { + return preg_replace('/(?<=[a-z])(?=[A-Z])/', '.', $part); + }, $dotParts); + + // 6. Implode the array with dots and return. + return implode('.', $modifiedDotParts); + } + + /** + * Get dependency name linked to service provider + * + * @param string $serviceProvider The global unique id of the (service provider) power + * @param string $dependency The global unique id of the (dependency) power + * + * @return string|null + * @since 3.2.0 + */ + private function getServiceProviderDependencyName(string $serviceProvider, string $dependency): ?string + { + if (($power = $this->power($serviceProvider)) === null) + { + return null; + } + + if (empty($power->use_selection) || !is_object($power->use_selection)) + { + return null; + } + + foreach ($power->use_selection as $use_selection) + { + if ($use_selection->use !== $dependency) + { + continue; + } + + if (($name = $this->name($use_selection->use, $use_selection->as)) === null) + { + continue; + } + + return $name; + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ServiceProvider.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ServiceProvider.php new file mode 100644 index 000000000..7173c0be0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ServiceProvider.php @@ -0,0 +1,203 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Generator; + + +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Power code Generator for the Service Provider of JCB + * + * @since 3.2.0 + */ +final class ServiceProvider +{ + /** + * The version + * + * @var string + * @since 3.2.0 + **/ + protected string $version; + + /** + * The register lines + * + * @var array + * @since 3.2.0 + **/ + protected array $registerlines = []; + + /** + * The get functions + * + * @var array + * @since 3.2.0 + **/ + protected array $getfunctions = []; + + /** + * Get the generated class code + * + * @return string|null + * @since 3.2.0 + */ + public function getCode(): ?string + { + if ($this->registerlines === []) + { + return null; + } + + $code = []; + + $code[] = Indent::_(1) . "/**"; + $code[] = Indent::_(1) . " * Registers the service provider with a DI container."; + $code[] = Indent::_(1) . " *"; + $code[] = Indent::_(1) . " * @param Container \$container The DI container."; + $code[] = Indent::_(1) . " *"; + $code[] = Indent::_(1) . " * @return void"; + $code[] = Indent::_(1) . " * @since {$this->version}"; + $code[] = Indent::_(1) . " */"; + $code[] = Indent::_(1) . "public function register(Container \$container)"; + $code[] = Indent::_(1) . "{"; + $code[] = implode(PHP_EOL . PHP_EOL, $this->registerlines); + $code[] = Indent::_(1) . "}"; + $code[] = PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->getfunctions); + + $this->registerlines = []; + $this->getfunctions = []; + + return implode(PHP_EOL, $code); + } + + /** + * Set the class since version + * + * @param string $version The variable version format. + * + * @return void + * @since 3.2.0 + */ + public function setVersion(string $version): void + { + $this->version = $version; + } + + /** + * Set the class alias and share code for the service provider register. + * + * @param string $className The variable name in lowerCamelCase format. + * @param string $functionName The function name in lowerCamelCase format. + * @param string $alias The variable alias format. + * + * @return void + * @since 3.2.0 + */ + public function setRegisterLine(string $className, string $functionName, string $alias): void + { + $this->registerlines[] = implode(PHP_EOL , [ + $this->getAlias($className, $alias), + $this->getShare($functionName, $alias) + ]); + } + + /** + * Set the class get function for the service provider. + * + * @param string $className The variable name in lowerCamelCase format. + * @param string $functionName The function name in lowerCamelCase format. + * @param string $description The function description. + * @param array|null $dependencies The class dependencies aliases. + * + * @return void + * @since 3.2.0 + */ + public function setGetFunction(string $className, string $functionName, + string $description, ?array $dependencies = null): void + { + $this->getfunctions[] = implode(PHP_EOL , [ + Indent::_(1) . "/**", + Indent::_(1) . " * $description", + Indent::_(1) . " *", + Indent::_(1) . " * @param Container \$container The DI container.", + Indent::_(1) . " *", + Indent::_(1) . " * @return $className", + Indent::_(1) . " * @since {$this->version}", + Indent::_(1) . " */", + Indent::_(1) . "public function $functionName(Container \$container): $className", + Indent::_(1) . "{", + $this->getDependencies($className, $dependencies), + Indent::_(1) . "}" + ]); + } + + /** + * Generates the class alias for the service provider. + * + * @param string $className The variable name in lowerCamelCase format. + * @param string $alias The variable alias format. + * + * @return string Generated class alias code. + * @since 3.2.0 + */ + protected function getAlias(string $className, string $alias): string + { + return Indent::_(2) . "\$container->alias({$className}::class, '{$alias}')"; + } + + /** + * Generates the class share for the service provider. + * + * @param string $functionName The function name in lowerCamelCase format. + * @param string $alias The variable alias format. + * + * @return string Generated class share code. + * @since 3.2.0 + */ + protected function getShare(string $functionName, string $alias): string + { + return Indent::_(3) . "->share('$alias', [\$this, '$functionName'], true);"; + } + + /** + * Generates the class dependencies. + * + * @param string $className The variable name in lowerCamelCase format. + * @param array|null $dependencies The class dependencies aliases. + * + * @return string Generated class and its dependencies code if found. + * @since 3.2.0 + */ + protected function getDependencies(string $className, ?array $dependencies = null): string + { + $bucket = []; + if (!empty($dependencies)) + { + $bucket[] = Indent::_(2) . "return new $className("; + $bucket[] = Indent::_(3) . "\$container->get('" + . implode( + "')," . PHP_EOL . Indent::_(3) . "\$container->get('" + , $dependencies + ) . "')"; + $bucket[] = Indent::_(2) . ");"; + } + else + { + $bucket[] = Indent::_(2) . "return new $className();"; + } + + return implode(PHP_EOL , $bucket); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ServiceProviderBuilder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ServiceProviderBuilder.php new file mode 100644 index 000000000..61a55805d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/ServiceProviderBuilder.php @@ -0,0 +1,303 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Generator; + + +use VDM\Joomla\Componentbuilder\Power\Generator\Search; +use VDM\Joomla\Componentbuilder\Power\Generator\ServiceProvider; +use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent; + + +/** + * Power Service Provider Builder of JCB + * + * @since 3.2.0 + */ +final class ServiceProviderBuilder +{ + /** + * The Search Class. + * + * @var Search + * @since 3.2.0 + */ + protected Search $search; + + /** + * The Service Provider Class. + * + * @var ServiceProvider + * @since 3.2.0 + */ + protected ServiceProvider $serviceprovider; + + /** + * Constructor. + * + * @param Search $search The Search Class. + * @param ServiceProvider $serviceprovider The Service Provider Class. + * + * @since 3.2.0 + */ + public function __construct(Search $search, ServiceProvider $serviceprovider) + { + $this->search = $search; + $this->serviceprovider = $serviceprovider; + } + + /** + * Get the service provider code. + * + * @param array $power The power being saved + * + * @return string|null + * @since 3.2.0 + */ + public function getCode(array $power): ?string + { + $this->setVersion($this->extractSinceVersion($power['description'] ?? '') ?? $power['power_version'] ?? '1.0.0'); + + if (!empty($power['use_selection'])) + { + $this->setRegisterLines($power['use_selection']); + $this->setGetFunctions($power['use_selection']); + } + + return $this->getServiceProviderCode(); + } + + /** + * Set the class alias and share code for the service provider register. + * + * @param array $useSelections The use (in class) selections + * + * @return void + * @since 3.2.0 + */ + private function setRegisterLines(array $useSelections): void + { + foreach ($useSelections as $use_selection) + { + if (!$this->valid($use_selection['use'])) + { + continue; + } + + if (($name = $this->getName($use_selection['use'], $use_selection['as'])) === null) + { + continue; + } + + $function_name = $this->getFunctionName($name); + $alias = $this->getAlias($use_selection['use'], $name); + + $this->setRegisterLine($name, $function_name, $alias); + } + } + + /** + * Set the class get function for the service provider. + * + * @param array $useSelections The use (in class) selections + * + * @return void + * @since 3.2.0 + */ + private function setGetFunctions(array $useSelections): void + { + foreach ($useSelections as $use_selection) + { + if (!$this->valid($use_selection['use'])) + { + continue; + } + + if (($name = $this->getName($use_selection['use'], $use_selection['as'])) === null) + { + continue; + } + + if (($description = $this->getDescription($use_selection['use'])) === null) + { + continue; + } + + $function_name = $this->getFunctionName($name); + $dependencies = $this->getDependencies($use_selection['use']); + + $this->setGetFunction($name, $function_name, "Get $description", $dependencies); + } + } + + /** + * Check that this is a valid injection class. + * + * @param string $guid The class GUID of the power + * + * @return bool + * @since 3.2.0 + */ + private function valid(string $guid): bool + { + return $this->search->validInject($guid); + } + + /** + * Get the class name. + * + * @param string $guid The class GUID of the power + * @param string $as The as name + * + * @return string|null + * @since 3.2.0 + */ + private function getName(string $guid, string $as = 'default'): ?string + { + return $this->search->name($guid, $as); + } + + /** + * Get the function name. + * + * @param string $name The class name + * + * @return string + * @since 3.2.0 + */ + private function getFunctionName(string $name): string + { + return "get{$name}"; + } + + /** + * Get the dependencies of a class + * + * @param string $guid The class GUID of the power + * + * @return array|null + * @since 3.2.0 + */ + private function getDependencies(string $guid): ?array + { + return $this->search->dependencies($guid); + } + + /** + * Get the class description. + * + * @param string $guid The class GUID of the power + * + * @return string|null + * @since 3.2.0 + */ + private function getDescription(string $guid): ?string + { + return $this->search->description($guid); + } + + /** + * Get the class alias + * + * @param string $guid The class GUID of the power + * @param string $className The class name + * + * @return string + * @since 3.2.0 + */ + private function getAlias(string $guid, string $className): string + { + return $this->search->alias($guid, $className); + } + + /** + * Get the service provider code. + * + * @return string|null + * @since 3.2.0 + */ + private function getServiceProviderCode(): ?string + { + return $this->serviceprovider->getCode(); + } + + /** + * Set the class since version. + * + * @param string $version The class since version + * + * @return void + * @since 3.2.0 + */ + private function setVersion(string $version): void + { + $this->serviceprovider->setVersion($version); + } + + /** + * Set the class alias and share code for the service provider register. + * + * @param string $className The variable name in lowerCamelCase format. + * @param string $functionName The function name in lowerCamelCase format. + * @param string $alias The variable alias format. + * + * @return void + * @since 3.2.0 + */ + public function setRegisterLine(string $className, string $functionName, string $alias): void + { + $this->serviceprovider->setRegisterLine($className, $functionName, $alias); + } + + /** + * Set the class get function for the service provider. + * + * @param string $className The variable name in lowerCamelCase format. + * @param string $functionName The function name in lowerCamelCase format. + * @param string $description The function description. + * @param array|null $dependencies The class dependencies aliases. + * + * @return void + * @since 3.2.0 + */ + public function setGetFunction(string $className, string $functionName, + string $description, ?array $dependencies = null): void + { + $this->serviceprovider->setGetFunction($className, $functionName, + $description, $dependencies); + } + + /** + * Extract the '@since' version number from a given string. + * + * This function checks the provided string for a '@since' annotation + * and retrieves the subsequent version number. If no '@since' + * annotation is found or no version number is provided after the + * annotation, the function will return null. + * + * @param string $inputString The input string to search. + * + * @return string|null The version number if found, or null if not. + * @since 3.2.0 + */ + private function extractSinceVersion(string $inputString): ?string + { + // Use regex to match the @since pattern and capture the version number + if (preg_match('/@since\s+([\d\.]+)/', $inputString, $matches)) + { + return $matches[1]; + } + + // If no match is found, return null + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Generator/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Grep.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Grep.php new file mode 100644 index 000000000..709036fd9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Grep.php @@ -0,0 +1,403 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Gitea\Repository\Contents; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\JsonHelper; + + +/** + * Global Resource Empowerment Platform + * + * The Grep feature will try to find your power in the repositories listed in the global + * Options of JCB in the super powers tab, and if it can't be found there will try the global core + * Super powers of JCB. All searches are performed according the the [algorithm:cascading] + * See documentation for more details: https://git.vdm.dev/joomla/super-powers/wiki + * + * @since 3.2.0 + */ +final class Grep +{ + /** + * The local path + * + * @var string + * @since 3.2.0 + **/ + public ?string $path; + + /** + * All approved paths + * + * @var array + * @since 3.2.0 + **/ + public ?array $paths; + + /** + * Gitea Repository Contents + * + * @var Contents + * @since 3.2.0 + **/ + protected Contents $contents; + + /** + * Joomla Application object + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param string $path The local path + * @param array $paths The approved paths + * @param Contents $contents The Gitea Repository Contents object. + * @param CMSApplication|null $app The CMS Application object. + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(string $path, array $paths, Contents $contents, ?CMSApplication $app = null) + { + $this->path = $path; + $this->paths = $paths; + $this->contents = $contents; + $this->app = $app ?: Factory::getApplication(); + + $this->init(); + } + + /** + * Get all remote powers GUID's + * + * @return array|null + * @since 3.2.0 + */ + public function getRemotePowersGuid(): ?array + { + if (!is_array($this->paths) || $this->paths === []) + { + return null; + } + + $powers = []; + foreach ($this->paths as $path) + { + // Get local index + $this->remoteIndex($path); + + if (isset($path->index) && is_object($path->index)) + { + $powers = array_merge($powers, array_keys((array) $path->index)); + } + } + + return empty($powers) ? null : array_unique($powers); + } + + /** + * Get a power + * + * @param string $guid The global unique id of the power + * @param array $order The search order + * + * @return object|null + * @since 3.2.0 + */ + public function get(string $guid, array $order = ['local', 'remote']): ?object + { + // we can only search if we have paths + if (is_array($this->paths) && $this->paths !== []) + { + foreach ($order as $target) + { + if (($function_name = $this->getFunctionName($target)) !== null && + ($power = $this->{$function_name}($guid)) !== null) + { + return $power; + } + } + } + + return null; + } + + /** + * Search for a local power + * + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function searchLocal(string $guid): ?object + { + // we can only search if we have paths + if ($this->path && $this->paths) + { + foreach ($this->paths as $path) + { + // get local index + $this->localIndex($path); + + if (!empty($path->local) && isset($path->local->{$guid})) + { + return $this->getLocal($path, $guid); + } + } + } + + return null; + } + + /** + * Search for a remote power + * + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function searchRemote(string $guid): ?object + { + // we can only search if we have paths + if ($this->path && $this->paths) + { + foreach ($this->paths as $path) + { + // get local index + $this->remoteIndex($path); + + if (!empty($path->index) && isset($path->index->{$guid})) + { + return $this->getRemote($path, $guid); + } + } + } + + return null; + } + + /** + * Get a local power + * + * @param object $path The repository path details + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function getLocal(object $path, string $guid): ?object + { + if (empty($path->local->{$guid}->settings) || empty($path->local->{$guid}->code)) + { + return null; + } + + // get the settings + if (($settings = FileHelper::getContent($path->full_path . '/' . $path->local->{$guid}->settings, null)) !== null && + JsonHelper::check($settings)) + { + $power = json_decode($settings); + + // get the code + if (($code = FileHelper::getContent($path->full_path . '/' . $path->local->{$guid}->power, null)) !== null) + { + $power->main_class_code = $code; + return $power; + } + } + + return null; + } + + /** + * Get a remote power + * + * @param object $path The repository path details + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function getRemote(object $path, string $guid): ?object + { + if (empty($path->index->{$guid}->settings) || empty($path->index->{$guid}->code)) + { + return null; + } + + // get the settings + if (($power = $this->loadRemoteFile($path->owner, $path->repo, $path->index->{$guid}->settings, $path->branch)) !== null && + isset($power->guid)) + { + // get the code + if (($code = $this->loadRemoteFile($path->owner, $path->repo, $path->index->{$guid}->power, $path->branch)) !== null) + { + $power->main_class_code = $code; + return $power; + } + } + + return null; + } + + /** + * Set path details + * + * @return void + * @since 3.2.0 + */ + private function init() + { + if (is_array($this->paths) && $this->paths !== []) + { + foreach ($this->paths as $n => &$path) + { + if (isset($path->owner) && strlen($path->owner) > 1 && + isset($path->repo) && strlen($path->repo) > 1) + { + // build the path + $path->path = trim($path->owner) . '/' . trim($path->repo); + + // update the branch + if ($path->branch === 'default' || empty($path->branch)) + { + $path->branch = null; + } + + // set local path + if ($this->path && Folder::exists($this->path . '/' . $path->path)) + { + $path->full_path = $this->path . '/' . $path->path; + } + } + else + { + unset($this->paths[$n]); + } + } + } + } + + /** + * Load the local repository index of powers + * + * @param object $path The repository path details + * + * @return void + * @since 3.2.0 + */ + private function localIndex(object &$path) + { + if (isset($path->local) || !isset($path->full_path)) + { + return; + } + + if (($content = FileHelper::getContent($path->full_path . '/super-powers.json', null)) !== null && + JsonHelper::check($content)) + { + $path->local = json_decode($content); + + return; + } + + $path->local = null; + } + + /** + * Load the remote repository index of powers + * + * @param object $path The repository path details + * + * @return void + * @since 3.2.0 + */ + private function remoteIndex(object &$path) + { + if (isset($path->index)) + { + return; + } + + try + { + $path->index = $this->contents->get($path->owner, $path->repo, 'super-powers.json', $path->branch); + } + catch (\Exception $e) + { + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_PSUPER_POWERB_REPOSITORY_AT_BSSB_GAVE_THE_FOLLOWING_ERRORBR_SP', $this->contents->api(), $path->path, $e->getMessage()), + 'Error' + ); + + $path->index = null; + } + } + + /** + * Load the remote file + * + * @param string $owner The repository owner + * @param string $repo The repository name + * @param string $path The repository path to file + * @param string|null $branch The repository branch name + * + * @return mixed + * @since 3.2.0 + */ + private function loadRemoteFile(string $owner, string $repo, string $path, ?string $branch) + { + try + { + $data = $this->contents->get($owner, $repo, $path, $branch); + } + catch (\Exception $e) + { + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_PFILE_AT_BSSB_GAVE_THE_FOLLOWING_ERRORBR_SP', $this->contents->api(), $path, $e->getMessage()), + 'Error' + ); + + return null; + } + + return $data; + } + + /** + * Get function name + * + * @param string $name The targeted function name + * + * @return string|null + * @since 3.2.0 + */ + private function getFunctionName(string $name): ?string + { + $function_name = 'search' . ucfirst(strtolower($name)); + + return method_exists($this, $function_name) ? $function_name : null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/Load.php new file mode 100644 index 000000000..046379092 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/Load.php @@ -0,0 +1,119 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Model; + + +use VDM\Joomla\Abstraction\Model as AbstractionModel; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Interfaces\ModelInterface; + + +/** + * Power Model Load + * + * @since 3.2.0 + */ +final class Load extends AbstractionModel implements ModelInterface +{ + /** + * Model the value + * Example: $this->value(value, 'field_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if (($store = $this->table->get($table, $field, 'store')) !== null) + { + // open the value based on the store method + switch($store) + { + case 'base64': + $value = base64_decode((string) $value); + break; + case 'json': + $value = json_decode($value); + break; + } + } + + return $value; + } + + /** + * Validate before the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + // only strings or numbers allowed + if (StringHelper::check($value) || is_numeric($value)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Validate after the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + // only strings or numbers allowed + if (StringHelper::check($value) || ArrayHelper::check($value, true) || ObjectHelper::check($value) || is_numeric($value)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + protected function getTable(): string + { + return 'power'; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/Upsert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/Upsert.php new file mode 100644 index 000000000..607b5ca12 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/Upsert.php @@ -0,0 +1,120 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Model; + + +use VDM\Joomla\Abstraction\Model as AbstractionModel; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Interfaces\ModelInterface; + + +/** + * Power Model Update or Insert + * + * @since 3.2.0 + */ +final class Upsert extends AbstractionModel implements ModelInterface +{ + /** + * Model the value + * Example: $this->value(value, 'field_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if (($store = $this->table->get($table, $field, 'store')) !== null) + { + // open the value based on the store method + switch($store) + { + case 'base64': + $value = base64_encode((string) $value); + break; + case 'json': + $value = json_encode($value, JSON_FORCE_OBJECT); + break; + } + } + + return $value; + } + + /** + * Validate before the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + // check values + if (StringHelper::check($value) || ArrayHelper::check($value, true) || ObjectHelper::check($value) || is_numeric($value)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Validate after the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + // only strings or numbers allowed + if (StringHelper::check($value) || is_numeric($value)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + protected function getTable(): string + { + return 'power'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Database.php new file mode 100644 index 000000000..4b1a238a4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Database.php @@ -0,0 +1,135 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Power\Model\Load as ModelLoad; +use VDM\Joomla\Componentbuilder\Power\Model\Upsert as ModelUpsert; +use VDM\Joomla\Componentbuilder\Power\Database\Load as LoadDatabase; +use VDM\Joomla\Componentbuilder\Power\Database\Insert as InsertDatabase; +use VDM\Joomla\Componentbuilder\Power\Database\Update as UpdateDatabase; + + +/** + * Database Service Provider + * + * @since 3.2.0 + */ +class Database implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(ModelLoad::class, 'Power.Model.Load') + ->share('Power.Model.Load', [$this, 'getModelLoad'], true); + + $container->alias(ModelUpsert::class, 'Power.Model.Upsert') + ->share('Power.Model.Upsert', [$this, 'getModelUpsert'], true); + + $container->alias(LoadDatabase::class, 'Power.Database.Load') + ->share('Power.Database.Load', [$this, 'getLoadDatabase'], true); + + $container->alias(InsertDatabase::class, 'Power.Database.Insert') + ->share('Power.Database.Insert', [$this, 'getInsertDatabase'], true); + + $container->alias(UpdateDatabase::class, 'Power.Database.Update') + ->share('Power.Database.Update', [$this, 'getUpdateDatabase'], true); + } + + /** + * Get the Power Model Load + * + * @param Container $container The DI container. + * + * @return ModelLoad + * @since 3.2.0 + */ + public function getModelLoad(Container $container): ModelLoad + { + return new ModelLoad( + $container->get('Table') + ); + } + + /** + * Get the Power Model Update or Insert + * + * @param Container $container The DI container. + * + * @return ModelUpsert + * @since 3.2.0 + */ + public function getModelUpsert(Container $container): ModelUpsert + { + return new ModelUpsert( + $container->get('Table') + ); + } + + /** + * Get the Load Database + * + * @param Container $container The DI container. + * + * @return LoadDatabase + * @since 3.2.0 + */ + public function getLoadDatabase(Container $container): LoadDatabase + { + return new LoadDatabase( + $container->get('Power.Model.Load'), + $container->get('Load') + ); + } + + /** + * Get the Insert Database + * + * @param Container $container The DI container. + * + * @return InsertDatabase + * @since 3.2.0 + */ + public function getInsertDatabase(Container $container): InsertDatabase + { + return new InsertDatabase( + $container->get('Power.Model.Upsert'), + $container->get('Insert') + ); + } + + /** + * Get the Update Database + * + * @param Container $container The DI container. + * + * @return UpdateDatabase + * @since 3.2.0 + */ + public function getUpdateDatabase(Container $container): UpdateDatabase + { + return new UpdateDatabase( + $container->get('Power.Model.Upsert'), + $container->get('Update') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Generator.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Generator.php new file mode 100644 index 000000000..23a82cd1e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Generator.php @@ -0,0 +1,169 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Power\Generator as PowerGenerator; +use VDM\Joomla\Componentbuilder\Power\Generator\ClassInjectorBuilder; +use VDM\Joomla\Componentbuilder\Power\Generator\ServiceProviderBuilder; +use VDM\Joomla\Componentbuilder\Power\Generator\Search; +use VDM\Joomla\Componentbuilder\Power\Generator\ClassInjector; +use VDM\Joomla\Componentbuilder\Power\Generator\ServiceProvider; +use VDM\Joomla\Componentbuilder\Power\Generator\Bucket; + + +/** + * Generator Service Provider + * + * @since 3.2.0 + */ +class Generator implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(PowerGenerator::class, 'Power.Generator') + ->share('Power.Generator', [$this, 'getGenerator'], true); + + $container->alias(ClassInjectorBuilder::class, 'Power.Generator.Class.Injector.Builder') + ->share('Power.Generator.Class.Injector.Builder', [$this, 'getClassInjectorBuilder'], true); + + $container->alias(ServiceProviderBuilder::class, 'Power.Generator.Service.Provider.Builder') + ->share('Power.Generator.Service.Provider.Builder', [$this, 'getServiceProviderBuilder'], true); + + $container->alias(Search::class, 'Power.Generator.Search') + ->share('Power.Generator.Search', [$this, 'getSearch'], true); + + $container->alias(ClassInjector::class, 'Power.Generator.Class.Injector') + ->share('Power.Generator.Class.Injector', [$this, 'getClassInjector'], true); + + $container->alias(ServiceProvider::class, 'Power.Generator.Service.Provider') + ->share('Power.Generator.Service.Provider', [$this, 'getServiceProvider'], true); + + $container->alias(Bucket::class, 'Power.Generator.Bucket') + ->share('Power.Generator.Bucket', [$this, 'getBucket'], true); + } + + /** + * Get the Generator + * + * @param Container $container The DI container. + * + * @return PowerGenerator + * @since 3.2.0 + */ + public function getGenerator(Container $container): PowerGenerator + { + return new PowerGenerator( + $container->get('Power.Generator.Class.Injector.Builder'), + $container->get('Power.Generator.Service.Provider.Builder') + ); + } + + /** + * Get the Generator Class Injector Builder + * + * @param Container $container The DI container. + * + * @return ClassInjectorBuilder + * @since 3.2.0 + */ + public function getClassInjectorBuilder(Container $container): ClassInjectorBuilder + { + return new ClassInjectorBuilder( + $container->get('Power.Generator.Search'), + $container->get('Power.Generator.Class.Injector') + ); + } + + /** + * Get the Generator Service Provider Builder + * + * @param Container $container The DI container. + * + * @return ServiceProviderBuilder + * @since 3.2.0 + */ + public function getServiceProviderBuilder(Container $container): ServiceProviderBuilder + { + return new ServiceProviderBuilder( + $container->get('Power.Generator.Search'), + $container->get('Power.Generator.Service.Provider') + ); + } + + /** + * Get the Generator Search + * + * @param Container $container The DI container. + * + * @return Search + * @since 3.2.0 + */ + public function getSearch(Container $container): Search + { + return new Search( + $container->get('Power.Database.Load'), + $container->get('Power.Parser'), + $container->get('Power.Generator.Bucket') + ); + } + + /** + * Get the Generator Class Injector + * + * @param Container $container The DI container. + * + * @return ClassInjector + * @since 3.2.0 + */ + public function getClassInjector(Container $container): ClassInjector + { + return new ClassInjector(); + } + + /** + * Get the Generator Service Provider + * + * @param Container $container The DI container. + * + * @return ServiceProvider + * @since 3.2.0 + */ + public function getServiceProvider(Container $container): ServiceProvider + { + return new ServiceProvider(); + } + + /** + * Get the Generator Bucket + * + * @param Container $container The DI container. + * + * @return Bucket + * @since 3.2.0 + */ + public function getBucket(Container $container): Bucket + { + return new Bucket(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Gitea.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Gitea.php new file mode 100644 index 000000000..7459e6ccc --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Gitea.php @@ -0,0 +1,58 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Repository\Contents; + + +/** + * Power Gitea Service Provider + * + * @since 3.2.0 + */ +class Gitea implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Contents::class, 'Gitea.Repository.Contents') + ->share('Gitea.Repository.Contents', [$this, 'getContents'], true); + } + + /** + * Get the Contents class + * + * @param Container $container The DI container. + * + * @return Contents + * @since 3.2.0 + */ + public function getContents(Container $container): Contents + { + return new Contents( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Power.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Power.php new file mode 100644 index 000000000..b307743ad --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/Power.php @@ -0,0 +1,130 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Power\Config; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Power\Grep; +use VDM\Joomla\Componentbuilder\Power\Super as Superpower; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; + + +/** + * Power Service Provider + * + * @since 3.2.0 + */ +class Power implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Config::class, 'Config') + ->share('Config', [$this, 'getConfig'], true); + + $container->alias(Table::class, 'Table') + ->share('Table', [$this, 'getTable'], true); + + $container->alias(Grep::class, 'Power.Grep') + ->share('Power.Grep', [$this, 'getGrep'], true); + + $container->alias(Superpower::class, 'Superpower') + ->share('Superpower', [$this, 'getSuperpower'], true); + + $container->alias(Parser::class, 'Power.Parser') + ->share('Power.Parser', [$this, 'getParser'], true); + } + + /** + * Get The Config Class. + * + * @param Container $container The DI container. + * + * @return Config + * @since 3.2.0 + */ + public function getConfig(Container $container): Config + { + return new Config(); + } + + /** + * Get The Table Class. + * + * @param Container $container The DI container. + * + * @return Table + * @since 3.2.0 + */ + public function getTable(Container $container): Table + { + return new Table(); + } + + /** + * Get The Grep Class. + * + * @param Container $container The DI container. + * + * @return Grep + * @since 3.2.0 + */ + public function getGrep(Container $container): Grep + { + return new Grep( + $container->get('Config')->local_powers_repository_path, + $container->get('Config')->approved_paths, + $container->get('Gitea.Repository.Contents') + ); + } + + /** + * Get The Super Class. + * + * @param Container $container The DI container. + * + * @return Superpower + * @since 3.2.0 + */ + public function getSuperpower(Container $container): Superpower + { + return new Superpower( + $container->get('Power.Grep'), + $container->get('Power.Database.Insert'), + $container->get('Power.Database.Update') + ); + } + + /** + * Get The Parser Class. + * + * @param Container $container The DI container. + * + * @return Parser + * @since 3.2.0 + */ + public function getParser(Container $container): Parser + { + return new Parser(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Super.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Super.php new file mode 100644 index 000000000..30d9fa3b3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Super.php @@ -0,0 +1,185 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use VDM\Joomla\Componentbuilder\Power\Grep; +use VDM\Joomla\Componentbuilder\Power\Database\Insert; +use VDM\Joomla\Componentbuilder\Power\Database\Update; +use VDM\Joomla\Utilities\GuidHelper; + + +/** + * Superpower of JCB + * + * @since 3.2.0 + */ +final class Super +{ + /** + * The Power Search Tool + * + * @var Grep + * @since 3.2.0 + **/ + protected Grep $grep; + + /** + * Insert Data Class + * + * @var Insert + * @since 3.2.0 + **/ + protected Insert $insert; + + /** + * Update Data Class + * + * @var Update + * @since 3.2.0 + **/ + protected Update $update; + + /** + * Constructor. + * + * @param Grep $grep The Power Grep object. + * @param Insert $insert The Power Database Insert object. + * @param Update $update The Power Database Update object. + * + * @since 3.2.0 + */ + public function __construct(Grep $grep, Insert $insert, Update $update) + { + $this->grep = $grep; + $this->insert = $insert; + $this->update = $update; + } + + /** + * Init all power not found in database + * + * @return bool + * @since 3.2.0 + */ + public function init(): bool + { + if (($powers = $this->grep->getRemotePowersGuid()) !== null) + { + foreach($powers as $guid) + { + if ($this->action($guid) === 'insert' && ($power = $this->grep->get($guid, ['remote'])) !== null) + { + $this->insert($power); + } + } + + return true; + } + + return false; + } + + /** + * Reset the powers + * + * @param array $powers The global unique ids of the powers + * + * @return bool + * @since 3.2.0 + */ + public function reset(array $powers): bool + { + if ($powers === []) + { + return false; + } + + $success = true; + + foreach($powers as $guid) + { + if (!$this->load($guid, ['remote'])) + { + $success = false; + } + } + + return $success; + } + + /** + * Load a superpower + * + * @param string $guid The global unique id of the power + * @param array $order The search order + * @param string|null $action The action to load power + * + * @return bool + * @since 3.2.0 + */ + public function load(string $guid, array $order = ['remote', 'local'], ?string $action = null): bool + { + if (($power = $this->grep->get($guid, $order)) !== null && + ($action !== null || ($action = $this->action($power->guid)) !== null)) + { + return method_exists($this, $action) ? $this->{$action}($power) : false; + } + + return false; + } + + /** + * Insert a superpower + * + * @param object $power The power + * + * @return bool + * @since 3.2.0 + */ + private function insert(object $power): bool + { + return $this->insert->item($power); + } + + /** + * Update a superpower + * + * @param object $power The power + * + * @return bool + * @since 3.2.0 + */ + private function update(object $power): bool + { + return $this->update->item($power); + } + + /** + * Get loading action + * + * @param string $guid The global unique id of the power + * + * @return string + * @since 3.2.0 + */ + private function action(string $guid): string + { + if (($id = GuidHelper::item($guid, 'power')) !== null && $id > 0) + { + return 'update'; + } + + return 'insert'; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Engine.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Engine.php new file mode 100644 index 000000000..a15b48dae --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Engine.php @@ -0,0 +1,123 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Abstraction; + + +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; + + +/** + * Search Engine + * + * @since 3.2.0 + */ +abstract class Engine +{ + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search Value + * + * @var string|null + * @since 3.2.0 + */ + protected ?string $searchValue; + + /** + * Replace Value + * + * @var string + * @since 3.2.0 + */ + protected string $replaceValue; + + /** + * Search Should Match Case + * + * @var int + * @since 3.2.0 + */ + protected int $matchCase = 0; + + /** + * Search Should Match Whole Word + * + * @var int + * @since 3.2.0 + */ + protected int $wholeWord = 0; + + /** + * Start marker + * + * @var string + * @since 3.2.0 + */ + protected string $start = ''; + + /** + * End marker + * + * @var string + * @since 3.2.0 + */ + protected string $end = ''; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null) + { + $this->config = $config ?: Factory::_('Config'); + + // set search value + $this->searchValue = $this->config->search_value; + + // set replace value + $this->replaceValue = $this->config->replace_value; + + // set match case + $this->matchCase = $this->config->match_case; + + // set whole word + $this->wholeWord = $this->config->whole_word; + + // set start marker + $this->start = $this->config->marker_start; + + // set end marker + $this->end = $this->config->marker_end; + } + + /** + * we count every line being searched + * + * @since 3.2.0 + */ + protected function lineCounter() + { + // we count every line we search + $this->config->line_counter += 1; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php new file mode 100644 index 000000000..b33c55dc8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php @@ -0,0 +1,425 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search; + + +use Joomla\CMS\Language\Text; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Search\Database\Load; +use VDM\Joomla\Componentbuilder\Search\Database\Insert; +use VDM\Joomla\Componentbuilder\Search\Agent\Find; +use VDM\Joomla\Componentbuilder\Search\Agent\Replace; +use VDM\Joomla\Componentbuilder\Search\Agent\Search; +use VDM\Joomla\Componentbuilder\Search\Agent\Update; +use VDM\Joomla\Componentbuilder\Table; + + +/** + * Search Agent + * + * @since 3.2.0 + */ +class Agent +{ + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search Load Database + * + * @var Load + * @since 3.2.0 + */ + protected Load $load; + + /** + * Search Insert Database + * + * @var Insert + * @since 3.2.0 + */ + protected Insert $insert; + + /** + * Search Find + * + * @var Find + * @since 3.2.0 + */ + protected Find $find; + + /** + * Search Replace + * + * @var Replace + * @since 3.2.0 + */ + protected Replace $replace; + + /** + * Search + * + * @var Search + * @since 3.2.0 + */ + protected Search $search; + + /** + * Update + * + * @var Update + * @since 3.2.0 + */ + protected Update $update; + + /** + * Table + * + * @var Table + * @since 3.2.0 + */ + protected Table $table; + + /** + * Return value to search view + * + * @var string + * @since 3.2.0 + */ + protected string $return; + + /** + * Marker start and end values + * + * @var array + * @since 3.2.0 + */ + protected array $marker; + + /** + * Marker start and end html values + * + * @var array + * @since 3.2.0 + */ + protected array $markerHtml; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Load|null $load The search load database object. + * @param Insert|null $insert The search insert database object. + * @param Find|null $find The search find object. + * @param Replace|null $replace The search replace object. + * @param Search|null $search The search object. + * @param Update|null $update The update object. + * @param Table|null $table The table object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Load $load = null, + ?Insert $insert = null, ?Find $find = null, ?Replace $replace = null, + ?Search $search = null, ?Update $update = null, ?Table $table = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->load = $load ?: Factory::_('Load.Database'); + $this->insert = $insert ?: Factory::_('Insert.Database'); + $this->find = $find ?: Factory::_('Agent.Find'); + $this->replace = $replace ?: Factory::_('Agent.Replace'); + $this->search = $search ?: Factory::_('Agent.Search'); + $this->update = $update ?: Factory::_('Agent.Update'); + $this->table = $table ?: Factory::_('Table'); + } + + /** + * Get the value of a field in a row and table + * + * @param int $id The item ID + * @param string $field The field key + * @param mixed $line The field line + * @param string|null $table The table + * @param bool $update The switch to triger an update (default is false) + * + * @return string|null + * @since 3.2.0 + */ + public function getValue(int $id, string $field, $line = null, + ?string $table = null, bool $update = false): ?string + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if (($value = $this->load->value($id, $field, $table)) !== null) + { + // we only return strings that can load in an editor + if (is_string($value)) + { + // try to update the value if required + if ($update && ($updated_value = $this->update->value($value, $line)) !== null) + { + return $updated_value; + } + + return $value; + } + + return '// VALUE CAN NOT BE LOADED (AT THIS TIME) SINCE ITS NOT A STRING'; + } + + return null; + } + + /** + * Set the value of a field in a row and table + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function setValue($value, int $id, string $field, ?string $table = null): bool + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + return $this->insert->value($value, $id, $field, $table); + } + + /** + * Return Table Ready Search Results + * + * @param string|null $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function table(?string $table = null): ?array + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if(($values = $this->find($table)) !== null) + { + // build return value + $this->setReturnValue(); + + // set the markers + $this->setMarkers(); + + // start table bucket + $table_rows = []; + + foreach ($values as $id => $fields) + { + foreach ($fields as $field => $lines) + { + foreach ($lines as $line => $code) + { + $table_rows[] = $this->getRow($code, $table, $field, $id, $line); + } + } + } + return $table_rows; + } + return null; + } + + /** + * Search the posted table for the search value and return all + * + * @param string|null $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function find(?string $table = null): ?array + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + $set = 1; + + // continue loading items until all are searched + while(($items = $this->load->items($table, $set)) !== null) + { + $this->find->items($items, $table); + $set++; + } + + return $this->search->get($table); + } + + /** + * Search the posted table for the search value, and replace all + * + * @param string|null $table The table being searched + * + * @return int + * @since 3.2.0 + */ + public function replace(?string $table = null): int + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + $set = 1; + $replaced = 0; + + // continue loading items until all was loaded + while(($items = $this->load->items($table, $set)) !== null) + { + // search for items + $this->find->items($items, $table); + + // update those found + $this->replace->items($this->find->get($table), $table); + + // update the database + if ($this->insert->items($this->replace->get($table), $table)) + { + $replaced++; + } + + // reset found items + $this->find->reset($table); + $this->replace->reset($table); + + $set++; + } + + // we return the number of times we replaced + return $replaced; + } + + /** + * Return prepared code string for table + * + * @param string $code The code value fro the table + * @param string|null $table The table + * @param string $field The field key + * @param int $id The the row id + * @param mixed $line The code line where found + * + * @return array + * @since 3.2.0 + */ + protected function getRow(string $code, string $table, string $field, int $id, $line): array + { + return [ + 'edit' => $this->getRowEditButton($table, $field, $id, $line), + 'code' => $this->getRowCode($code), + 'table' => $table, + 'field' => $field, + 'id' => $id, + 'line' => $line + ]; + } + + /** + * Return prepared code string for table + * + * @param string $code The code value fro the table + * + * @return string + * @since 3.2.0 + */ + protected function getRowCode(string $code): string + { + return str_replace($this->marker, $this->markerHtml, htmlentities($code)); + } + + /** + * Get the Item button to edit an item + * + * @param string|null $view The single view + * @param string $field The field key + * @param int $id The the row id + * @param mixed $line The code line where found + * + * @return string + * @since 3.2.0 + */ + protected function getRowEditButton(string $view, string $field, int $id, $line): string + { + // get list view + $views = $this->table->get($view, $field, 'list'); + $tab = $this->table->get($view, $field, 'tab_name'); + + // return edit link + return ''; + } + + /** + * Set the return value for this search + * + * @return void + * @since 3.2.0 + */ + protected function setReturnValue() + { + // set the return value so the search auto load on return + $this->return = urlencode(base64_encode('index.php?option=com_componentbuilder&view=search' . + '&type_search=' . (int) $this->config->type_search . + '&match_case=' . (int) $this->config->match_case . + '&whole_word=' . (int) $this->config->whole_word . + '®ex_search=' . (int) $this->config->regex_search . + '&search_value=' . (string) urlencode((string) $this->config->search_value) . + '&replace_value=' . (string) urlencode((string) $this->config->replace_value))); + } + + /** + * Set the markers of the found code + * + * @return void + * @since 3.2.0 + */ + protected function setMarkers() + { + // set the markers + $this->marker = [$this->config->marker_start, $this->config->marker_end]; + $this->markerHtml = ['','']; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Find.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Find.php new file mode 100644 index 000000000..dda386d24 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Find.php @@ -0,0 +1,180 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Agent; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Search\Agent\Search; +use VDM\Joomla\Componentbuilder\Search\Interfaces\FindInterface; + + +/** + * Search Agent Find + * + * @since 3.2.0 + */ +class Find implements FindInterface +{ + /** + * Found Values + * + * @var array + * @since 3.2.0 + */ + protected array $found = []; + + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search + * + * @var Search + * @since 3.2.0 + */ + protected Search $search; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Search|null $search The search object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Search $search = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->search = $search ?: Factory::_('Agent.Search'); + } + + /** + * Get found values + * + * @param string|null $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function get(?string $table = null): ?array + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if (isset($this->found[$table])) + { + return $this->found[$table]; + } + + return null; + } + + /** + * Search over an item fields + * + * @param object $item The item object of fields to search through + * @param int|null $id The item id + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function item(object $item, ?int $id =null, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + // set the item id + if (empty($id)) + { + $id = $item->id; + } + + if (ObjectHelper::check($item)) + { + foreach ($item as $field => $value) + { + if ($field !== 'id' && $this->search->value($value, $id, $field, $table)) + { + if (empty($this->found[$table][$id])) + { + $this->found[$table][$id] = new \stdClass(); + $this->found[$table][$id]->id = $id; + } + $this->found[$table][$id]->{$field} = $value; + } + } + } + } + + /** + * Search over an array of items + * + * @param array|null $items The array of items to search through + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function items(?array $items = null, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if (ArrayHelper::check($items)) + { + foreach ($items as $id => $item) + { + $this->item($item, $id, $table); + } + } + } + + /** + * Reset all found values of a table + * + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function reset(?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + // empty or unset the table active values + unset($this->found[$table]); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Replace.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Replace.php new file mode 100644 index 000000000..2fd4bae01 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Replace.php @@ -0,0 +1,181 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Agent; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Search\Agent\Update; +use VDM\Joomla\Componentbuilder\Search\Interfaces\ReplaceInterface; + + +/** + * Search Agent Replace + * + * @since 3.2.0 + */ +class Replace implements ReplaceInterface +{ + /** + * Updated Values + * + * @var array + * @since 3.2.0 + */ + protected array $updated = []; + + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Update + * + * @var Update + * @since 3.2.0 + */ + protected Update $update; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Update|null $update The update object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Update $update = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->update = $update ?: Factory::_('Agent.Update'); + } + + /** + * Get updated values + * + * @param string|null $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function get(?string $table = null): ?array + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if (isset($this->updated[$table])) + { + return $this->updated[$table]; + } + + return null; + } + + /** + * Search over an item fields + * + * @param object $item The item object of fields to search through + * @param int|null $id The item id + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function item(object $item, ?int $id =null, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + // set the item id + if (empty($id)) + { + $id = $item->id; + } + + if (ObjectHelper::check($item)) + { + foreach ($item as $field => $value) + { + if ($field !== 'id' && ($_value = $this->update->value($value)) !== null) + { + if (empty($this->updated[$table][$id])) + { + $this->updated[$table][$id] = new \stdClass(); + $this->updated[$table][$id]->id = $id; + } + // add updated value + $this->updated[$table][$id]->{$field} = $_value; + } + } + } + } + + /** + * Search over an array of items + * + * @param array|null $items The array of items to search through + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function items(?array $items = null, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if (ArrayHelper::check($items)) + { + foreach ($items as $id => $item) + { + $this->item($item, $id, $table); + } + } + } + + /** + * Reset all updated values of a table + * + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function reset(?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + // empty or unset the table active values + unset($this->updated[$table]); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Search.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Search.php new file mode 100644 index 000000000..9ccd89a1c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Search.php @@ -0,0 +1,302 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Agent; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine; +use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchInterface; + + +/** + * Search Agent Search + * + * @since 3.2.0 + */ +class Search implements SearchInterface +{ + /** + * Search results found + * + * @var array + * @since 3.2.0 + */ + protected array $found = []; + + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search Engine + * + * @var SearchEngine + * @since 3.2.0 + */ + protected SearchEngine $search; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param SearchEngine|null $search The search engine object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?SearchEngine $search = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->search = $search ?: Factory::_('Search'); + } + + /** + * Get found values + * + * @param string $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function get(string $table): ?array + { + if (isset($this->found[$table])) + { + return $this->found[$table]; + } + + return null; + } + + /** + * Search inside a value + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string $table The table + * + * @return bool + * @since 3.2.0 + */ + public function value($value, int $id, string $field, string $table): bool + { + // search the mixed value + $found = $this->searchValue($value); + + // check if we found any match + if (ArrayHelper::check($found)) + { + foreach ($found as $line => $line_value) + { + // may not be needed... but being old school + $this->prep($id, $field, $table); + + // load the detail into our multidimensional array... lol + // Table->Item_id->Field_name->Line_number = marked_full_line + // Search Example: soon... + // Marked Line Example: Soon.... + $this->found[$table][$id][$field][$line] = $line_value; + } + return true; + } + + return false; + } + + /** + * Empty the found values + * + * @param string $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function reset(string $table) + { + unset($this->found[$table]); + } + + /** + * Search inside a string + * + * @param mixed $value The field value + * + * @return array|null + * @since 3.2.0 + */ + protected function searchValue($value): ?array + { + // check if this is an array + $found = null; + + // I know this is a little crazy... TODO refactor into recursion functions + // the possibility of searching sub-forms in sub-forms + if (ArrayHelper::check($value)) + { + // first layer + foreach ($value as $keys => $rows) + { + if (ArrayHelper::check($rows)) + { + // second layer + foreach ($rows as $key => $row) + { + if (ArrayHelper::check($row)) + { + // third layer + foreach ($row as $ke => $ro) + { + if (ArrayHelper::check($ro)) + { + // forth layer + foreach ($ro as $k => $r) + { + if (StringHelper::check($r) && ($_found = $this->string($r)) !== null) + { + foreach ($_found as $_n => $_f) + { + $found[$keys . '.' . $key . '.' . $ke . '.' . $k . '.' . $_n] = $_f; + } + } + } + } + elseif (StringHelper::check($ro) && ($_found = $this->string($ro)) !== null) + { + foreach ($_found as $_n => $_f) + { + $found[$keys. '.' . $key . '.' . $ke . '.' . $_n] = $_f; + } + } + + } + } + elseif (StringHelper::check($row) && ($_found = $this->string($row)) !== null) + { + foreach ($_found as $_n => $_f) + { + $found[$keys. '.' . $key . '.' . $_n] = $_f; + } + } + } + } + elseif (StringHelper::check($rows) && ($_found = $this->string($rows)) !== null) + { + foreach ($_found as $_n => $_f) + { + $found[$keys. '.' . $_n] = $_f; + } + } + } + } + elseif (StringHelper::check($value)) + { + $found = $this->string($value); + } + + return $found; + } + + /** + * Search inside a string + * + * @param string $value The field value + * + * @return array|null + * @since 3.2.0 + */ + protected function string(string $value): ?array + { + // line counter + $line = 1; + + // we count every field we search + $this->fieldCounter(); + + // check if string has a new line + if (\preg_match('/\R/', $value)) + { + $search_array = \preg_split('/\R/', $value); + + // start search bucket + $found = []; + + // loop over the lines + foreach ($search_array as $line_value) + { + if (($_found = $this->search->string($line_value)) !== null) + { + $found[$line] = $_found; + } + + // next line + $line++; + } + + if (ArrayHelper::check($found)) + { + return $found; + } + } + elseif (($found = $this->search->string($value)) !== null) + { + return [$line => $found]; + } + + return null; + } + + /** + * Prep the bucket + * + * @param int $id The item ID + * @param string $field The field key + * @param string $table The table + * + * @return void + * @since 3.2.0 + */ + protected function prep(int $id, string $field, string $table) + { + if (empty($this->found[$table])) + { + $this->found[$table] = []; + } + if (empty($this->found[$table][$id])) + { + $this->found[$table][$id] = []; + } + if (empty($this->found[$table][$id][$field])) + { + $this->found[$table][$id][$field] = []; + } + // we should add a call to get the item name if the table has a name field TODO + } + + /** + * we count every field being searched + * + * @since 3.2.0 + */ + protected function fieldCounter() + { + // we count every field we search + $this->config->field_counter += 1; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Update.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Update.php new file mode 100644 index 000000000..410366ab6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/Update.php @@ -0,0 +1,236 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Agent; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine; + + +/** + * Search Agent Update + * + * @since 3.2.0 + */ +class Update +{ + /** + * Search Engine + * + * @var SearchEngine + * @since 3.2.0 + */ + protected SearchEngine $search; + + /** + * Constructor + * + * @param SearchEngine|null $search The search engine object. + * + * @since 3.2.0 + */ + public function __construct(?SearchEngine $search = null) + { + $this->search = $search ?: Factory::_('Search'); + } + + /** + * Update the value + * + * @param mixed $value The field value + * @param mixed $line The line to update (0 = all) + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, $line = 0) + { + // update the value + $update = $this->updateValue($value, $line); + + // was anything updated + if ($value === $update) + { + return null; + } + + return $update; + } + + /** + * Update all search-replace instances inside a value + * + * @param mixed $value The field value + * @param mixed $line The line to update (0 = all) + * + * @return mixed + * @since 3.2.0 + */ + protected function updateValue($value, $line = 0) + { + // I know this is a little crazy... TODO refactor into recursion functions + // the possibility of updating sub-forms in sub-forms + if (ArrayHelper::check($value)) + { + if (strpos((string) $line, '.') !== false) + { + $line = explode('.', (string) $line); + } + // first layer + foreach ($value as $keys => &$rows) + { + if (ArrayHelper::check($rows)) + { + // second layer + foreach ($rows as $key => &$row) + { + if (ArrayHelper::check($row)) + { + // third layer + foreach ($row as $ke => &$ro) + { + if (ArrayHelper::check($ro)) + { + // forth layer + foreach ($ro as $k => &$r) + { + if (StringHelper::check($r) && + $this->validateUpdateKey($line, $keys, $key, $ke, $k)) + { + $_line = (isset($line[4])) ? $line[4] : 0; + $r = $this->string($r, $_line); + } + } + } + elseif (StringHelper::check($ro) && + $this->validateUpdateKey($line, $keys, $key, $ke)) + { + $_line = (isset($line[3])) ? $line[3] : 0; + $ro = $this->string($ro, $_line); + } + + } + } + elseif (StringHelper::check($row) && + $this->validateUpdateKey($line, $keys, $key)) + { + $_line = (isset($line[2])) ? $line[2] : 0; + $row = $this->string($row, $_line); + } + } + } + elseif (StringHelper::check($rows) && + $this->validateUpdateKey($line, $keys)) + { + $_line = (isset($line[1])) ? $line[1] : 0; + $rows = $this->string($rows, $_line); + } + } + } + elseif (StringHelper::check($value)) + { + $value = $this->string($value, $line); + } + + return $value; + } + + /** + * Check if the keys are valid for search when working with arrays + * + * @param int $line The lines array + * @param mixed $keys The line keys + * @param mixed $key The line key + * @param mixed $k The line ke + * @param mixed $k The line k + * + * @return bool + * @since 3.2.0 + */ + protected function validateUpdateKey($line, $keys = null, $key = null, $ke = null, $k = null): bool + { + if (ArrayHelper::check($line)) + { + $_keys = (isset($line[0])) ? $line[0] : null; + $_key = (isset($line[1])) ? $line[1] : null; + $_ke = (isset($line[2])) ? $line[2] : null; + $_k = (isset($line[3])) ? $line[3] : null; + + if ($keys && $_keys && $_keys !== $keys) + { + return false; + } + + if ($key && $_key && $_key !== $key) + { + return false; + } + + if ($ke && $_ke && $_ke !== $ke) + { + return false; + } + + if ($k && $_k && $_k !== $k) + { + return false; + } + } + + return true; + } + + /** + * Update all search-replace instances inside a string + * + * @param string $value The field value + * @param int $line The line to update (0 = all) + * + * @return string + * @since 3.2.0 + */ + protected function string(string $value, int $line = 0): string + { + // check if string has a new line + if (\preg_match('/\R/', $value) && $line > 0) + { + // line counter + $line_number = 1; + + $search_array = \preg_split('/\R/', $value); + + // loop over the lines + foreach ($search_array as $nr => $line_value) + { + if ($line_number == $line) + { + $search_array[$nr] = $this->search->replace($line_value); + + // since we are targeting on line (and possibly one number) + // this can only happen once, and so we return at this point + return implode(PHP_EOL, $search_array); + } + // next line + $line_number++; + } + + // no update took place so we just return the original value + return $value; + } + + return $this->search->replace($value); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Config.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Config.php new file mode 100644 index 000000000..ecb35d9d0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Config.php @@ -0,0 +1,206 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search; + + +use Joomla\CMS\Factory; +use Joomla\Input\Input; +use VDM\Joomla\Abstraction\BaseConfig; + + +/** + * Search Configurations + * + * @since 3.2.0 + */ +class Config extends BaseConfig +{ + /** + * Hold a JInput object for easier access to the input variables. + * + * @var Input + * @since 3.2.0 + */ + protected Input $input; + + /** + * Constructor + * + * @param Input|null $input Input + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(?Input $input = null) + { + $this->input = $input ?: Factory::getApplication()->input; + + // run parent constructor + parent::__construct(); + } + + /** + * get type search being preformed + * + * @return int the search type 1 = search, 2 = search & replace + * @since 3.2.0 + */ + protected function getTypesearch(): ?int + { + return $this->input->get('type_search', 1, 'INT'); + } + + /** + * get posted search value + * + * @return string|null Raw search value + * @since 3.2.0 + */ + protected function getSearchvalue(): ?string + { + return $this->input->get('search_value', null, 'RAW'); + } + + /** + * get posted replace value + * + * @return string Raw replace value + * @since 3.2.0 + */ + protected function getReplacevalue(): string + { + return $this->input->get('replace_value', '', 'RAW'); + } + + /** + * get posted search match case + * + * @return int Match case + * @since 3.2.0 + */ + protected function getMatchcase(): int + { + return $this->input->get('match_case', 0, 'INT'); + } + + /** + * get posted search whole word + * + * @return int Whole word + * @since 3.2.0 + */ + protected function getWholeword(): int + { + return $this->input->get('whole_word', 0, 'INT'); + } + + /** + * get posted search regex + * + * @return int Regex + * @since 3.2.0 + */ + protected function getRegexsearch(): int + { + return $this->input->get('regex_search', 0, 'INT'); + } + + /** + * get posted component + * + * @return int Component ID + * @since 3.2.0 + */ + protected function getComponentid(): int + { + return $this->input->get('component_id', 0, 'INT'); + } + + /** + * get posted area/table + * + * @return string|null Table name + * @since 3.2.0 + */ + protected function getTablename(): ?string + { + return $this->input->get('table_name', null, 'word'); + } + + /** + * get posted field + * + * @return string|null Field name + * @since 3.2.0 + */ + protected function getFieldname(): ?string + { + return $this->input->get('field_name', null, 'word'); + } + + /** + * get posted item id + * + * @return int Item id + * @since 3.2.0 + */ + protected function getItemid(): int + { + return $this->input->get('item_id', 0, 'INT'); + } + + /** + * get field counter + * + * @return int we start at 0 + * @since 3.2.0 + */ + protected function getFieldcounter(): int + { + return 0; + } + + /** + * get line counter + * + * @return int we start at 0 + * @since 3.2.0 + */ + protected function getLinecounter(): int + { + return 0; + } + + /** + * get the start marker + * + * @return string The string to use as the start marker + * @since 3.2.0 + */ + protected function getMarkerstart(): string + { + return '{+' . '|' . '=['; + } + + /** + * get the end marker + * + * @return string The string to use as the end marker + * @since 3.2.0 + */ + protected function getMarkerend(): string + { + return ']=' . '|' . '+}'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php new file mode 100644 index 000000000..afce63c7c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php @@ -0,0 +1,188 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Database; + + +use Joomla\CMS\Factory as JoomlaFactory; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Search\Model\Insert as Model; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Search\Interfaces\InsertInterface; + + +/** + * Search Database Set + * + * @since 3.2.0 + */ +class Insert implements InsertInterface +{ + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search Table + * + * @var Table + * @since 3.2.0 + */ + protected Table $table; + + /** + * Search Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Table|null $table The search table object. + * @param Model|null $model The search get model object. + * @param \JDatabaseDriver|null $db The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Table $table = null, + ?Model $model = null, ?\JDatabaseDriver $db = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->table = $table ?: Factory::_('Table'); + $this->model = $model ?: Factory::_('Insert.Model'); + $this->db = $db ?: JoomlaFactory::getDbo(); + } + + /** + * Set values to a given table + * Example: $this->value(Value, 23, 'value_key', 'table_name'); + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function value($value, int $id, string $field, ?string $table = null): bool + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid field and table + if ($id > 0 && ($name = $this->table->get($table, $field, 'name')) !== null) + { + // build the object + $item = new \stdClass(); + $item->id = $id; + $item->{$name} = $this->model->value($value, $name, $table); + + // Update the column of this table using id as the primary key. + return $this->db->updateObject('#__componentbuilder_' . $table, $item, 'id'); + } + return false; + } + + /** + * Set values to a given table + * Example: $this->item(Object, 'table_name'); + * + * @param object $item The item to save + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item, ?string $table = null): bool + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if (($fields = $this->table->fields($table)) !== null) + { + // model the item values + foreach ($fields as $field) + { + if (isset($item->{$field})) + { + $item->{$field} = $this->model->value($item->{$field}, $field, $table); + } + } + + // Update the column of this table using id as the primary key. + return $this->db->updateObject('#__componentbuilder_' . $table, $item, 'id'); + } + return false; + } + + /** + * Set values to a given table + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The items being saved + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function items(?array $items, string $table = null): bool + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if (ArrayHelper::check($items)) + { + $success = true; + foreach ($items as $item) + { + if (!$this->item($item, $table)) + { + $success = false; + break; + } + } + return $success; + } + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Load.php new file mode 100644 index 000000000..646fb0ee0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Load.php @@ -0,0 +1,305 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Database; + + +use Joomla\CMS\Factory as JoomlaFactory; +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Search\Model\Load as Model; +use VDM\Joomla\Database\Load as Database; +use VDM\Joomla\Componentbuilder\Search\Interfaces\LoadInterface; + + +/** + * Search Database Load + * + * @since 3.2.0 + */ +class Load implements LoadInterface +{ + /** + * Bundle Size + * + * @var int + * @since 3.2.0 + */ + protected int $bundle = 300; + + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Search Table + * + * @var Table + * @since 3.2.0 + */ + protected Table $table; + + /** + * Search Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database load class + * + * @var Database + * @since 3.2.0 + **/ + protected Database $load; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Table|null $table The search table object. + * @param Model|null $model The search get model object. + * @param Database|null $load The database object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Table $table = null, + ?Model $model = null, ?Database $load = null) + { + $this->config = $config ?: Factory::_('Config'); + $this->table = $table ?: Factory::_('Table'); + $this->model = $model ?: Factory::_('Load.Model'); + $this->load = $load ?: Factory::_('Load'); + } + + /** + * Get a value from a given table + * Example: $this->value(23, 'value_key', 'table_name'); + * + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value(int $id, string $field, string $table = null) + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if ($id > 0 && $this->table->exist($table, $field) && + ($value = $this->load->value( + ["a.${field}" => $field], // select + ['a' => $table], // tables + ['a.id' => $id] // where + )) !== null) + { + return $this->model->value( + $value, $field, $table + ); + } + + return null; + } + + /** + * Get values from a given table + * Example: $this->item(23, 'table_name'); + * + * @param int $id The item ID + * @param string| null $table The table + * + * @return object|null + * @since 3.2.0 + */ + public function item(int $id, string $table = null): ?object + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if ($id > 0 && ($fields = $this->setDatabaseFields($table)) !== null && + ($item = $this->load->item( + $fields, // select + ['a' => $table], // tables + ['a.id' => $id] // where + )) !== null) + { + // return found values + return $this->model->item($item, $table); + } + + return null; + } + + /** + * Get values from a given table + * Example: $this->items('table_name'); + * + * @param string|null $table The table + * @param int $bundle The bundle to return (0 = all) + * + * @return array|null + * @since 3.2.0 + */ + public function items(string $table = null, int $bundle = 0): ?array + { + // load the table + if (empty($table)) + { + $table = $this->config->table_name; + } + + // check if this is a valid table + if ( ($fields = $this->setDatabaseFields($table)) !== null) + { + // add a key to the selection return set + $fields['key'] = 'id'; + // get the title value + $title = $this->table->titleName($table); + // set order + $order = ['a.' . $title => 'ASC']; + // select all + $where = null; + // no limit + $limit = null; + + // add limitation and pagination + if ($bundle > 0) + { + // get the incremental number + $where = ['a.id' => [ + 'operator' => '>=', + 'value' => $this->next($table, $bundle) + ] + ]; + + // only return a limited number + $limit = $this->bundle; + } + + if (($items = $this->load->items( + $fields, // select + ['a' => $table], // tables + $where, + $order, + $limit + )) !== null) + { + // return found values + return $this->model->items($items, $table); + } + } + + return null; + } + + /** + * Get next id to call + * + * @param string $table The table + * @param int $bundle The bundle to return + * + * @return int + * @since 3.2.0 + */ + protected function next(string $table, int $bundle): int + { + if ($bundle == 1 || $bundle == 0) + { + return 1; + } + + if (($number = $this->model->last($table)) !== null) + { + return $number + 1; + } + + return $this->incremental($bundle); + } + + /** + * Get Incremental number where the set starts + * + * @param int $bundle The bundle to return + * + * @return int + * @since 3.2.0 + */ + protected function incremental(int $bundle): int + { + // just in case + if ($bundle == 1 || $bundle == 0) + { + return 1; + } + + /** Number two set starts at 301 + * 2 x 300 = 600 + * 600 - 300 = 300 + * 300 + 1 = 301 <-- + * Number five set starts at 1201 + * 5 x 300 = 1500 + * 1500 - 300 = 1200 + * 1200 + 1 = 1201 <-- + **/ + return (($bundle * $this->bundle) - $this->bundle) + 1; + } + + /** + * Get Fields ready to use in database call + * + * @param string $table The table which fields we want to get + * @param string $key The table key to which the fields belong + * @param bool $addId The switch to add ID + * + * @return array|null + * @since 3.2.0 + */ + protected function setDatabaseFields(string $table, string $key = 'a', bool $addId = true): ?array + { + if (($fields = $this->table->fields($table)) !== null) + { + // add the ID + if ($addId) + { + array_unshift($fields , 'id'); + } + + $bucket = []; + foreach ($fields as $field) + { + $bucket[$key . '.' . $field] = $field; + } + + return $bucket; + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Basic.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Basic.php new file mode 100644 index 000000000..2be7282b5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Basic.php @@ -0,0 +1,271 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Engine; + + +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface; +use VDM\Joomla\Componentbuilder\Search\Abstraction\Engine; + + +/** + * Search Type String + * + * @since 3.2.0 + */ +class Basic extends Engine implements SearchTypeInterface +{ + /** + * Regex Search Value + * + * @var string + * @since 3.2.0 + */ + protected string $regexValue = ''; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null) + { + parent::__construct($config); + + // quote all regular expression characters + $searchValue = preg_quote((string) $this->searchValue, '/'); + + $start = ''; $end = ''; + + // if this is a whole word search we need to do some prep + if ($this->wholeWord == 1) + { + // get first character of search string + $first = mb_substr((string) $this->searchValue, 0, 1); + // get last character of search string + $last = mb_substr((string) $this->searchValue, -1); + + // set the start boundary behavior + $start = '(\b)'; + if (\preg_match("/\W/", $first)) + { + $start = '(\b|\B)'; + } + + // set the boundary behavior + $end = '(\b)'; + if (\preg_match("/\W/", $last)) + { + $end = '(\b|\B)'; + } + } + + // set search based on match case + $case = ''; + if ($this->matchCase == 0) + { + $case = 'i'; + } + + $this->regexValue = "/" . $start . '(' . $searchValue . ')' . $end . "/" . $case; + } + + /** + * Search inside a string + * + * @param string $value The string value + * + * @return string|null The marked string if found, else null + * @since 3.2.0 + */ + public function string(string $value): ?string + { + // we count every line + $this->lineCounter(); + + if (StringHelper::check($this->searchValue)) + { + if ($this->wholeWord == 1) + { + return $this->searchWhole($value); + } + else + { + return $this->searchAll($value); + } + } + + return null; + } + + /** + * Replace found instances inside string value + * + * @param string $value The string value to update + * + * @return string The updated string + * @since 3.2.0 + */ + public function replace(string $value): string + { + if (StringHelper::check($this->searchValue)) + { + if ($this->wholeWord == 1) + { + return $this->replaceWhole($value); + } + else + { + return $this->replaceAll($value); + } + } + return $value; + } + + /** + * Replace whole words + * + * @param string $value The string value + * + * @return string The marked string if found, else null + * @since 3.2.0 + */ + protected function replaceWhole(string $value): string + { + if ($this->match($value)) + { + return preg_replace( + $this->regexValue . 'm', + "$1" . $this->replaceValue . "$3", + $value + ); + } + + return $value; + } + + /** + * Search for whole words + * + * @param string $value The string value + * + * @return string|null The marked string if found, else null + * @since 3.2.0 + */ + protected function searchWhole(string $value): ?string + { + if ($this->match($value)) + { + return trim(preg_replace( + $this->regexValue . 'm', + "$1" . $this->start . "$2" . $this->end . "$3", + $value + )); + } + + return null; + } + + /** + * Math the Regular Expression + * + * @param string $value The string value + * + * @return bool true if match is found + * @since 3.0.9 + */ + public function match(string $value): bool + { + $match = []; + + preg_match($this->regexValue, $value, $match); + + $match = array_filter( + $match, + fn($found) => !empty($found) + ); + + return (bool) ArrayHelper::check($match); + } + + /** + * Search for all instances + * + * @param string $value The string value + * + * @return string|null The marked string if found, else null + * @since 3.2.0 + */ + protected function searchAll(string $value): ?string + { + if ($this->matchCase == 1) + { + if (strpos($value, (string) $this->searchValue) !== false) + { + return trim(preg_replace( + $this->regexValue . 'm', + $this->start . "$1" . $this->end, + $value + )); + } + } + elseif (stripos($value, (string) $this->searchValue) !== false) + { + return trim(preg_replace( + $this->regexValue . 'm', + $this->start . "$1" . $this->end, + $value + )); + } + + return null; + } + + /** + * Replace for all instances + * + * @param string $value The string value + * + * @return string The marked string if found, else null + * @since 3.2.0 + */ + protected function replaceAll(string $value): string + { + if ($this->matchCase == 1) + { + if (strpos($value, (string) $this->searchValue) !== false) + { + return preg_replace( + $this->regexValue . 'm', + (string) $this->replaceValue, + $value + ); + } + } + elseif (stripos($value, (string) $this->searchValue) !== false) + { + return preg_replace( + $this->regexValue . 'm', + (string) $this->replaceValue, + $value + ); + } + + return $value; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Regex.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Regex.php new file mode 100644 index 000000000..58c07c93a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Regex.php @@ -0,0 +1,128 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Engine; + + +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface; +use VDM\Joomla\Componentbuilder\Search\Abstraction\Engine; + + +/** + * Search Type Regex + * + * @since 3.2.0 + */ +class Regex extends Engine implements SearchTypeInterface +{ + /** + * Regex Search Value + * + * @var string + * @since 3.2.0 + */ + protected string $regexValue = ''; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null) + { + parent::__construct($config); + + // set search based on match case + $case = ''; + if ($this->matchCase == 0) + { + $case = 'i'; + } + + $this->regexValue = "/(" . $this->searchValue . ")/" . $case; + } + + /** + * Search inside a string + * + * @param string $value The string value + * + * @return string|null The marked string if found, else null + * @since 3.2.0 + */ + public function string(string $value): ?string + { + // we count every line + $this->lineCounter(); + + if (StringHelper::check($this->searchValue) && $this->match($value)) + { + return trim(preg_replace( + $this->regexValue . 'm', + $this->start . "$1" . $this->end, + $value + )); + } + + return null; + } + + /** + * Replace found instances inside string value + * + * @param string $value The string value to update + * + * @return string The updated string + * @since 3.2.0 + */ + public function replace(string $value): string + { + if (StringHelper::check($this->searchValue) && $this->match($value)) + { + return preg_replace( + $this->regexValue . 'm', + (string) $this->replaceValue, + $value + ); + } + + return $value; + } + + /** + * Math the Regular Expression + * + * @param string $value The string value + * + * @return bool true if match is found + * @since 3.0.9 + */ + public function match(string $value): bool + { + $match = []; + + preg_match($this->regexValue, $value, $match); + + $match = array_filter( + $match, + fn($found) => !empty($found) + ); + + return (bool) ArrayHelper::check($match); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Factory.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Factory.php new file mode 100644 index 000000000..a12ee8c23 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Factory.php @@ -0,0 +1,83 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search; + + +use Joomla\DI\Container; +use VDM\Joomla\Componentbuilder\Search\Service\Search; +use VDM\Joomla\Componentbuilder\Search\Service\Model; +use VDM\Joomla\Componentbuilder\Search\Service\Database; +use VDM\Joomla\Componentbuilder\Search\Service\Agent; +use VDM\Joomla\Interfaces\FactoryInterface; + + +/** + * Search Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Search Container + * + * @var Container + * @since 3.2.0 + **/ + protected static $container = null; + + /** + * Get any class from the search container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _(string $key) + { + return self::getContainer()->get($key); + } + + /** + * Get the global search container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Search()) + ->registerServiceProvider(new Model()) + ->registerServiceProvider(new Database()) + ->registerServiceProvider(new Agent()); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/FindInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/FindInterface.php new file mode 100644 index 000000000..ea34b2d00 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/FindInterface.php @@ -0,0 +1,66 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Interfaces; + + +/** + * Search Find Interface + * + * @since 3.2.0 + */ +interface FindInterface +{ + /** + * Get found values + * + * @param string|null $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function get(?string $table = null): ?array; + + /** + * Search over an item fields + * + * @param object $item The item object of fields to search through + * @param int|null $id The item id + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function item(object $item, ?int $id =null, ?string $table = null); + + /** + * Search over an array of items + * + * @param array|null $items The array of items to search through + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function items(?array $items = null, ?string $table = null); + + /** + * Reset all found values of a table + * + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function reset(?string $table = null); + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/InsertInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/InsertInterface.php new file mode 100644 index 000000000..171b1e5d5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/InsertInterface.php @@ -0,0 +1,60 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Interfaces; + + +/** + * Search Database Insert Interface + * + * @since 3.2.0 + */ +interface InsertInterface +{ + /** + * Set values to a given table + * Example: $this->value(Value, 23, 'value_key', 'table_name'); + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function value($value, int $id, string $field, ?string $table = null): bool; + + /** + * Set values to a given table + * Example: $this->item(Object, 23, 'table_name'); + * + * @param object $item The item to save + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item, ?string $table = null): bool; + + /** + * Set values to a given table + * Example: $this->items(Array, 'table_name'); + * + * @param array $items The items being saved + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function items(array $items, string $table = null): bool; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/LoadInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/LoadInterface.php new file mode 100644 index 000000000..6c38fcc42 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/LoadInterface.php @@ -0,0 +1,60 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Interfaces; + + +/** + * Search Database Load Interface + * + * @since 3.2.0 + */ +interface LoadInterface +{ + /** + * Get a value from a given table + * Example: $this->value(23, 'value_key', 'table_name'); + * + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value(int $id, string $field, string $table = null); + + /** + * Get values from a given table + * Example: $this->item(23, 'table_name'); + * + * @param int $id The item ID + * @param string| null $table The table + * + * @return object|null + * @since 3.2.0 + */ + public function item(int $id, string $table = null): ?object; + + /** + * Get values from a given table + * Example: $this->items('table_name'); + * + * @param string|null $table The table + * @param int $bundle The bundle to return (0 = all) + * + * @return array|null + * @since 3.2.0 + */ + public function items(string $table = null, int $bundle = 0): ?array; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/ReplaceInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/ReplaceInterface.php new file mode 100644 index 000000000..6bc17f5d3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/ReplaceInterface.php @@ -0,0 +1,66 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Interfaces; + + +/** + * Search Replace Interface + * + * @since 3.2.0 + */ +interface ReplaceInterface +{ + /** + * Get updated values + * + * @param string|null $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function get(?string $table = null): ?array; + + /** + * Search over an item fields + * + * @param object $item The item object of fields to search through + * @param int|null $id The item id + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function item(object $item, ?int $id =null, ?string $table = null); + + /** + * Search over an array of items + * + * @param array|null $items The array of items to search through + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function items(?array $items = null, ?string $table = null); + + /** + * Reset all updated values of a table + * + * @param string|null $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function reset(?string $table = null); + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/SearchInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/SearchInterface.php new file mode 100644 index 000000000..29e944e95 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/SearchInterface.php @@ -0,0 +1,56 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Interfaces; + + +/** + * Search Interface + * + * @since 3.2.0 + */ +interface SearchInterface +{ + /** + * Get found values + * + * @param string $table The table being searched + * + * @return array|null + * @since 3.2.0 + */ + public function get(string $table): ?array; + + /** + * Search inside a value + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string $table The table + * + * @return bool + * @since 3.2.0 + */ + public function value($value, int $id, string $field, string $table): bool; + + /** + * Empty the found values + * + * @param string $table The table being searched + * + * @return void + * @since 3.2.0 + */ + public function reset(string $table); + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/SearchTypeInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/SearchTypeInterface.php new file mode 100644 index 000000000..d120860da --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/SearchTypeInterface.php @@ -0,0 +1,43 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Interfaces; + + +/** + * Search Type Interface + * + * @since 3.2.0 + */ +interface SearchTypeInterface +{ + /** + * Search inside a string + * + * @param string $value The string value + * + * @return string|null The marked string if found, else null + * @since 3.2.0 + */ + public function string(string $value): ?string; + + /** + * Replace found instances inside string value + * + * @param string $value The string value to update + * + * @return string The updated string + * @since 3.2.0 + */ + public function replace(string $value): string; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Interfaces/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php new file mode 100644 index 000000000..88dd61459 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php @@ -0,0 +1,138 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Model; + + +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Interfaces\ModelInterface; +use VDM\Joomla\Abstraction\Model; + + +/** + * Search Insert Model + * + * @since 3.2.0 + */ +class Insert extends Model implements ModelInterface +{ + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Table|null $table The search table object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Table $table = null) + { + parent::__construct($table ?? Factory::_('Table')); + + $this->config = $config ?: Factory::_('Config'); + } + + /** + * Model the value + * Example: $this->value(value, 'field_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if (($store = $this->table->get($table, $field, 'store')) !== null) + { + // open the value based on the store method + switch($store) + { + case 'base64': + $value = base64_encode((string) $value); + break; + case 'json': + $value = json_encode($value, JSON_FORCE_OBJECT); + break; + } + } + + return $value; + } + + /** + * Validate before the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + // check values + if (StringHelper::check($value) || ArrayHelper::check($value, true)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Validate after the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + return true; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + protected function getTable(): string + { + return $this->config->table_name; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php new file mode 100644 index 000000000..07dd04bd4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php @@ -0,0 +1,143 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Model; + + +use VDM\Joomla\Componentbuilder\Search\Factory; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Interfaces\ModelInterface; +use VDM\Joomla\Abstraction\Model; + + +/** + * Search Load Model + * + * @since 3.2.0 + */ +class Load extends Model implements ModelInterface +{ + /** + * Search Config + * + * @var Config + * @since 3.2.0 + */ + protected Config $config; + + /** + * Constructor + * + * @param Config|null $config The search config object. + * @param Table|null $table The search table object. + * + * @since 3.2.0 + */ + public function __construct(?Config $config = null, ?Table $table = null) + { + parent::__construct($table ?? Factory::_('Table')); + + $this->config = $config ?: Factory::_('Config'); + } + + /** + * Model the value + * Example: $this->value(value, 'value_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null) + { + // load the table + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if (StringHelper::check($value) && ($store = $this->table->get($table, $field, 'store')) !== null) + { + // open the value based on the store method + switch($store) + { + case 'base64': + $value = base64_decode((string) $value); + break; + case 'json': + // check if there is a json string + if (JsonHelper::check($value)) + { + $value = json_decode((string) $value, true); + } + break; + } + } + return $value; + } + + /** + * Validate before the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + return true; + } + + /** + * Validate after the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + // check values + if (StringHelper::check($value) || ArrayHelper::check($value, true)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + protected function getTable(): string + { + return $this->config->table_name; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Agent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Agent.php new file mode 100644 index 000000000..17ad513e3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Agent.php @@ -0,0 +1,143 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Search\Agent as SearchAgent; +use VDM\Joomla\Componentbuilder\Search\Agent\Find; +use VDM\Joomla\Componentbuilder\Search\Agent\Replace; +use VDM\Joomla\Componentbuilder\Search\Agent\Search; +use VDM\Joomla\Componentbuilder\Search\Agent\Update; + + +/** + * Agent Service Provider + * + * @since 3.2.0 + */ +class Agent implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(SearchAgent::class, 'Agent') + ->share('Agent', [$this, 'getAgent'], true); + + $container->alias(Find::class, 'Agent.Find') + ->share('Agent.Find', [$this, 'getFind'], true); + + $container->alias(Replace::class, 'Agent.Replace') + ->share('Agent.Replace', [$this, 'getReplace'], true); + + $container->alias(Search::class, 'Agent.Search') + ->share('Agent.Search', [$this, 'getSearch'], true); + + $container->alias(Update::class, 'Agent.Update') + ->share('Agent.Update', [$this, 'getUpdate'], true); + } + + /** + * Get the Search Agent + * + * @param Container $container The DI container. + * + * @return SearchAgent + * @since 3.2.0 + */ + public function getAgent(Container $container): SearchAgent + { + return new SearchAgent( + $container->get('Config'), + $container->get('Load.Database'), + $container->get('Insert.Database'), + $container->get('Agent.Find'), + $container->get('Agent.Replace'), + $container->get('Agent.Search'), + $container->get('Agent.Update'), + $container->get('Table') + ); + } + + /** + * Get the Search Agent Find + * + * @param Container $container The DI container. + * + * @return Find + * @since 3.2.0 + */ + public function getFind(Container $container): Find + { + return new Find( + $container->get('Config'), + $container->get('Agent.Search') + ); + } + + /** + * Get the Search Agent Replace + * + * @param Container $container The DI container. + * + * @return Replace + * @since 3.2.0 + */ + public function getReplace(Container $container): Replace + { + return new Replace( + $container->get('Config'), + $container->get('Agent.Update') + ); + } + + /** + * Get the Search Agent Search + * + * @param Container $container The DI container. + * + * @return Search + * @since 3.2.0 + */ + public function getSearch(Container $container): Search + { + return new Search( + $container->get('Config'), + $container->get('Search') + ); + } + + /** + * Get the Search Agent Update + * + * @param Container $container The DI container. + * + * @return Update + * @since 3.2.0 + */ + public function getUpdate(Container $container): Update + { + return new Update( + $container->get('Search') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Database.php new file mode 100644 index 000000000..24f9bce3b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Database.php @@ -0,0 +1,98 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Database\Load; +use VDM\Joomla\Componentbuilder\Search\Database\Load as LoadDatabase; +use VDM\Joomla\Componentbuilder\Search\Database\Insert as InsertDatabase; + + +/** + * Database Service Provider + * + * @since 3.2.0 + */ +class Database implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Load::class, 'Load') + ->share('Load', [$this, 'getLoad'], true); + + $container->alias(LoadDatabase::class, 'Load.Database') + ->share('Load.Database', [$this, 'getDatabaseLoad'], true); + + $container->alias(InsertDatabase::class, 'Insert.Database') + ->share('Insert.Database', [$this, 'getDatabaseInsert'], true); + } + + /** + * Get the Core Load Database + * + * @param Container $container The DI container. + * + * @return Load + * @since 3.2.0 + */ + public function getLoad(Container $container): Load + { + return new Load(); + } + + /** + * Get the Load Database + * + * @param Container $container The DI container. + * + * @return LoadDatabase + * @since 3.2.0 + */ + public function getDatabaseLoad(Container $container): LoadDatabase + { + return new LoadDatabase( + $container->get('Config'), + $container->get('Table'), + $container->get('Load.Model'), + $container->get('Load') + ); + } + + /** + * Get the Insert Database + * + * @param Container $container The DI container. + * + * @return InsertDatabase + * @since 3.2.0 + */ + public function getDatabaseInsert(Container $container): InsertDatabase + { + return new InsertDatabase( + $container->get('Config'), + $container->get('Table'), + $container->get('Insert.Model') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Model.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Model.php new file mode 100644 index 000000000..968001f32 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Model.php @@ -0,0 +1,77 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Search\Model\Load; +use VDM\Joomla\Componentbuilder\Search\Model\Insert; + + +/** + * Model Service Provider + * + * @since 3.2.0 + */ +class Model implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Load::class, 'Load.Model') + ->share('Load.Model', [$this, 'getModelLoad'], true); + $container->alias(Insert::class, 'Insert.Model') + ->share('Insert.Model', [$this, 'getModelInsert'], true); + } + + /** + * Get the Load Model + * + * @param Container $container The DI container. + * + * @return Load + * @since 3.2.0 + */ + public function getModelLoad(Container $container): Load + { + return new Load( + $container->get('Config'), + $container->get('Table') + ); + } + + /** + * Get the Insert Model + * + * @param Container $container The DI container. + * + * @return Insert + * @since 3.2.0 + */ + public function getModelInsert(Container $container): Insert + { + return new Insert( + $container->get('Config'), + $container->get('Table') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php new file mode 100644 index 000000000..945be9885 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php @@ -0,0 +1,149 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Search\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine; +use VDM\Joomla\Componentbuilder\Search\Engine\Regex; +use VDM\Joomla\Componentbuilder\Search\Engine\Basic; + + +/** + * Search Service Provider + * + * @since 3.2.0 + */ +class Search implements ServiceProviderInterface +{ + /** + * Selected search engine + * + * @var int + * @since 3.2.0 + **/ + protected $searchEngine = 101; + + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Config::class, 'Config') + ->share('Config', [$this, 'getConfig'], true); + + $container->alias(Table::class, 'Table') + ->share('Table', [$this, 'getTable'], true); + + $container->alias(Regex::class, 'Search.Regex') + ->share('Search.Regex', [$this, 'getRegex'], true); + + $container->alias(Basic::class, 'Search.Basic') + ->share('Search.Basic', [$this, 'getBasic'], true); + + $container->alias(SearchEngine::class, 'Search') + ->share('Search', [$this, 'getSearch'], true); + } + + /** + * Get the Config + * + * @param Container $container The DI container. + * + * @return Config + * @since 3.2.0 + */ + public function getConfig(Container $container): Config + { + return new Config(); + } + + /** + * Get the Table + * + * @param Container $container The DI container. + * + * @return Table + * @since 3.2.0 + */ + public function getTable(Container $container): Table + { + return new Table(); + } + + /** + * Get the Regex Type Search Engine + * + * @param Container $container The DI container. + * + * @return Regex + * @since 3.2.0 + */ + public function getRegex(Container $container): Regex + { + return new Regex( + $container->get('Config') + ); + } + + /** + * Get the Basic Type Search Engine + * + * @param Container $container The DI container. + * + * @return Basic + * @since 3.2.0 + */ + public function getBasic(Container $container): Basic + { + return new Basic( + $container->get('Config') + ); + } + + /** + * Get the Search Engine + * + * @param Container $container The DI container. + * + * @return SearchEngine + * @since 3.2.0 + */ + public function getSearch(Container $container): SearchEngine + { + // set the search engine to use for this container + if ($this->searchEngine == 101) + { + $this->searchEngine = (int) $container->get('Config')->regex_search; + } + + // get the correct type of search engine + if ($this->searchEngine == 1) + { + return $container->get('Search.Regex'); + } + + // the default is the basic + return $container->get('Search.Basic'); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server.php new file mode 100644 index 000000000..46220dc08 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server.php @@ -0,0 +1,165 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder; + + +use Joomla\CMS\Factory as JoomlaFactory; +use Joomla\CMS\User\User; +use VDM\Joomla\Componentbuilder\Server\Load; +use VDM\Joomla\Componentbuilder\Server\Ftp; +use VDM\Joomla\Componentbuilder\Server\Sftp; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * Server Class + * + * @since 3.2.0 + */ +class Server +{ + /** + * The Loader + * + * @var Load + * @since 3.2.0 + */ + protected Load $load; + + /** + * The Ftp object + * + * @var Ftp + * @since 3.2.0 + **/ + protected Ftp $ftp; + + /** + * The Sftp object + * + * @var Sftp + * @since 3.2.0 + **/ + protected Sftp $sftp; + + /** + * Current User object + * + * @var User + * @since 3.2.0 + */ + protected User $user; + + /** + * Constructor + * + * @param Load $load The server details loader object. + * @param Ftp $ftp The server ftp object. + * @param Sftp $sftp The server sftp object. + * @param User|null $user The user object. + * + * @since 3.2.0 + */ + public function __construct(Load $load, Ftp $ftp, Sftp $sftp, ?User $user = null) + { + $this->load = $load; + $this->ftp = $ftp; + $this->sftp = $sftp; + $this->user = $user ?: JoomlaFactory::getUser(); + } + + /** + * Move File to Server + * + * @param int $id The server local id to use + * @param string $localPath The local path to the file + * @param string $fileName The actual file name + * @param int|null $protocol The protocol to use (if set) + * @param string $permission The permission validation area + * + * @return bool true on success + * @since 3.2.0 + */ + public function move(int $id, string $localPath, string $fileName, + ?int $protocol = null, string $permission = 'core.export'): bool + { + // get the server + if ($this->user->authorise($permission, 'com_componentbuilder') && + ( + ( + is_numeric($protocol) && + ($protocol == 1 || $protocol == 2) + ) || ( + ($protocol = $this->load->value($id, 'protocol')) !== null && + ($protocol == 1 || $protocol == 2) + ) + ) + ) + { + // use the FTP protocol + if (1 == $protocol) + { + $protocol = 'ftp'; + $fields = [ + 'name', + 'signature' + ]; + } + // use the SFTP protocol + else + { + $protocol = 'sftp'; + $fields = [ + 'name', + 'authentication', + 'username', + 'host', + 'password', + 'path', + 'port', + 'private', + 'private_key', + 'secret' + ]; + } + + // get the details + if (StringHelper::check($protocol) && ($details = $this->load->item($id, $fields)) !== null) + { + // now move the file + return $this->{$protocol}->set($details)->move($localPath, $fileName); + } + } + + return false; + } + + /** + * Move File to Server (Legacy Signature) + * + * @param string $localPath The local path to the file + * @param string $fileName The actual file name + * @param int $serverID The server local id to use + * @param int $protocol The server protocol to use + * @param string $permission The permission validation area + * + * @return bool true on success + * @since 3.2.0 + * @deprecated 4.0 + */ + public function legacyMove($localPath, $fileName, $serverID, $protocol = null, $permission = 'core.export'): bool + { + return $this->move($serverID, $localPath, $fileName, $protocol, $permission); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Ftp.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Ftp.php new file mode 100644 index 000000000..d981017a6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Ftp.php @@ -0,0 +1,154 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Server; + + +use Joomla\CMS\Client\FtpClient; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Interfaces\Serverinterface; + + +/** + * Ftp Class + * + * @since 3.2.0 + */ +class Ftp implements Serverinterface +{ + /** + * The client object + * + * @var FtpClient|null + * @since 3.2.0 + **/ + protected ?FtpClient $client = null; + + /** + * The server details + * + * @var object + * @since 3.2.0 + **/ + protected ?object $details = null; + + /** + * set the server details + * + * @param object $details The server details + * + * @return Ftp + * @since 3.2.0 + **/ + public function set(object $details): Ftp + { + // we need to make sure the if the details changed to get a new server client + if (!ObjectHelper::equal($details, $this->details)) + { + // set the details + $this->details = $details; + + // reset the client if it was set before + $this->client = null; + } + + return $this; + } + + /** + * move a file to server with the FTP client + * + * @param string $localPath The full local path to the file + * @param string $fileName The file name + * + * @return bool + * @since 3.2.0 + **/ + public function move(string $localPath, string $fileName): bool + { + if ($this->connected()) + { + return $this->client->store($localPath, $fileName); + } + + return false; + } + + /** + * Make sure we are connected + * + * @return bool + * @since 3.2.0 + **/ + private function connected(): bool + { + // check if we have a connection + if ($this->client instanceof FtpClient && $this->client->isConnected()) + { + return true; + } + + $this->client = $this->getClient(); + + return $this->client instanceof FtpClient; + } + + /** + * get the FtpClient object + * + * @return FtpClient|null + * @since 3.2.0 + **/ + private function getClient(): ?FtpClient + { + // make sure we have a string and it is not default or empty + if (StringHelper::check($this->details->signature)) + { + // turn into array of variables + $signature = []; + parse_str((string) $this->details->signature, $signature); + // set options + if (isset($signature['options']) && ArrayHelper::check($signature['options'])) + { + foreach ($signature['options'] as $o__p0t1on => $vAln3) + { + if ('timeout' === $o__p0t1on) + { + $options[$o__p0t1on] = (int) $vAln3; + } + if ('type' === $o__p0t1on) + { + $options[$o__p0t1on] = (string) $vAln3; + } + } + } + else + { + $options = []; + } + // get ftp object + if (isset($signature['host']) && $signature['host'] != 'HOSTNAME' && + isset($signature['port']) && $signature['port'] != 'PORT_INT' && + isset($signature['username']) && $signature['username'] != 'user@name.com' && + isset($signature['password']) && $signature['password'] != 'password') + { + // this is a singleton + return FtpClient::getInstance($host, $port, $options, $username, $password); + } + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Load.php new file mode 100644 index 000000000..7abbea0fc --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Load.php @@ -0,0 +1,122 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Server; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory; +use VDM\Joomla\Database\Load as Database; +use VDM\Joomla\Componentbuilder\Server\Model\Load as Model; + + +/** + * Server Load Class + * + * @since 3.2.0 + */ +class Load +{ + /** + * Database Load + * + * @var Database + * @since 3.2.0 + */ + protected Database $db; + + /** + * Model Class + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Constructor + * + * @param Database|null $db The database object. + * @param Model|null $model The core crypt object. + * + * @since 3.2.0 + */ + public function __construct(?Database $db = null, ?Model $model = null) + { + $this->db = $db ?: Factory::_('Load'); + $this->model = $model ?: Factory::_('Model.Server.Load'); + } + + /** + * Get a value from a given server + * Example: $this->value(23, 'protocol'); + * + * @param int $id The item ID + * @param string $field The table field + * + * @return mixed|null + * @since 3.2.0 + */ + public function value(int $id, string $field) + { + if ($id > 0 && ($value = $this->db->value( + $this->setDatabaseFields([$field]), ['a' => 'server'], ['a.id' => $id] + )) !== null) + { + return $this->model->value($value, $field, 'server'); + } + + return null; + } + + /** + * Get values from a given server + * Example: $this->item(23, ['name', 'of', 'fields']); + * + * @param int $id The item ID + * @param array $fields The table fields + * + * @return object|null + * @since 3.2.0 + */ + public function item(int $id, array $fields): ?object + { + if ($id > 0 && ($item = $this->db->item( + $this->setDatabaseFields($fields), ['a' => 'server'], ['a.id' => $id] + )) !== null) + { + return $this->model->item($item, 'server'); + } + + return null; + } + + /** + * Set Fields ready to use in database call + * + * @param array $fields The table + * @param string $key The table key to which the fields belong + * + * @return array + * @since 3.2.0 + */ + protected function setDatabaseFields(array $fields, string $key = 'a'): array + { + $bucket = []; + foreach ($fields as $field) + { + $bucket[$key . '.' . $field] = $field; + } + + return $bucket; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php new file mode 100644 index 000000000..9917bc87c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php @@ -0,0 +1,153 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Server\Model; + + +use Joomla\Registry\Registry; +use VDM\Joomla\Componentbuilder\Compiler\Factory; +use VDM\Joomla\Componentbuilder\Crypt; +use VDM\Joomla\Componentbuilder\Table; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Interfaces\ModelInterface; +use VDM\Joomla\Abstraction\Model; + + +/** + * Server Model Load Class + * + * @since 3.2.0 + */ +class Load extends Model implements ModelInterface +{ + /** + * Decryption Class + * + * @var Crypt + * @since 3.2.0 + */ + protected Crypt $crypt; + + /** + * Constructor + * + * @param Crypt|null $crypt The core crypt object. + * @param Table|null $table The search table object. + * + * @since 3.2.0 + */ + public function __construct(?Crypt $crypt = null, ?Table $table = null) + { + parent::__construct($table ?? Factory::_('Table')); + + $this->crypt = $crypt ?: Factory::_('Crypt'); + } + + /** + * Model the value + * Example: $this->value(value, 'value_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null) + { + // load the table + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if (StringHelper::check($value) && ($store = $this->table->get($table, $field, 'store')) !== null) + { + // open the value based on the store method + switch($store) + { + case 'basic_encryption': + $value = $this->crypt->decrypt($value, 'basic'); + break; + case 'medium_encryption': + $value = $this->crypt->decrypt($value, 'medium'); + break; + case 'base64': + $value = base64_decode((string) $value); + break; + case 'json': + // check if there is a json string + if (JsonHelper::check($value)) + { + $registry = new Registry; + $registry->loadString($value); + $value = $registry->toArray(); + } + break; + default: + if ($this->crypt->exist($store)) + { + $value = $this->crypt->decrypt($value, $store); + } + break; + } + } + + return $value; + } + + /** + * Validate before the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + // remove none + return true; + } + + /** + * Validate after the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + return true; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + protected function getTable(): string + { + return 'server'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Sftp.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Sftp.php new file mode 100644 index 000000000..27772b8cd --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Sftp.php @@ -0,0 +1,271 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Server; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Application\CMSApplication; +use phpseclib3\Net\SFTP as SftpClient; +use VDM\Joomla\Componentbuilder\Crypt\KeyLoader; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Interfaces\Serverinterface; + + +/** + * Sftp Class + * + * @since 3.2.0 + */ +class Sftp implements Serverinterface +{ + /** + * The KeyLoader + * + * @var KeyLoader + * @since 3.2.0 + */ + protected KeyLoader $key; + + /** + * The client object + * + * @var SftpClient|null + * @since 3.2.0 + **/ + protected ?SftpClient $client = null; + + /** + * The server details + * + * @var object + * @since 3.2.0 + **/ + protected ?object $details = null; + + /** + * Application object. + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor + * + * @param KeyLoader $key The key loader object. + * @param CMSApplication|null $app The app object. + * + * @since 3.2.0 + */ + public function __construct(KeyLoader $key, ?CMSApplication $app = null) + { + $this->key = $key; + $this->app = $app ?: Factory::getApplication(); + } + + /** + * set the server details + * + * @param object $details The server details + * + * @return Sftp + * @since 3.2.0 + **/ + public function set(object $details): Sftp + { + // we need to make sure the if the details changed to get a new server client + if (!ObjectHelper::equal($details, $this->details)) + { + // set the details + $this->details = $details; + + // reset the client if it was set before + $this->client = null; + } + + return $this; + } + + /** + * move a file to server with the FTP client + * + * @param string $localPath The full local path to the file + * @param string $fileName The file name + * + * @return bool + * @since 3.2.0 + **/ + public function move(string $localPath, string $fileName): bool + { + if ($this->connected() && + ($data = FileHelper::getContent($localPath, null)) !== null) + { + // get the remote path + $path = ''; + if (isset($this->details->path) && + StringHelper::check($this->details->path) && + $this->details->path !== '/') + { + $path = trim((string) $this->details->path); + $path = '/' . trim($path, '/') . '/'; + } + + try + { + return $this->client->put($path . trim($fileName), $data); + } + catch(\Exception $e) + { + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_MOVING_OF_THE_S_FAILED', $fileName) . ': ' . $e->getMessage(), + 'Error' + ); + } + } + + return false; + } + + /** + * Make sure we are connected + * + * @return bool + * @since 3.2.0 + **/ + private function connected(): bool + { + // check if we have a connection + if ($this->client instanceof SftpClient && ($this->client->isConnected() || $this->client->ping())) + { + return true; + } + + $this->client = $this->getClient(); + + return $this->client instanceof SftpClient; + } + + /** + * get the SftpClient object + * + * @return SftpClient|null + * @since 3.2.0 + **/ + private function getClient(): ?SftpClient + { + // make sure we have a host value set + if (isset($this->details->host) && StringHelper::check($this->details->host) && + isset($this->details->username) && StringHelper::check($this->details->username)) + { + // insure the port is set + $port = (int)($this->details->port ?? 22); + + // open the connection + $sftp = new SftpClient($this->details->host, $port); + + // set the passphrase if it exist + $passphrase = (isset($this->details->secret) && StringHelper::check(trim($this->details->secret))) ? trim($this->details->secret) : false; + + // set the password if it exist + $password = (isset($this->details->password) && StringHelper::check(trim($this->details->password))) ? trim($this->details->password) : false; + + // now login based on authentication type + $key = null; + switch($this->details->authentication) + { + case 1: // password + $key = $password ?? null; + $password = null; + break; + case 2: // private key file + case 3: // both password and private key file + if (isset($this->details->private) && StringHelper::check($this->details->private) && + ($private_key = FileHelper::getContent($this->details->private, null)) !== null) + { + try + { + $key = $this->key::load(trim($private_key), $passphrase); + } + catch(\Exception $e) + { + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_LOADING_THE_PRIVATE_KEY_FILE_FAILED') . ': ' . $e->getMessage(), + 'Error' + ); + $key = null; + } + } + break; + case 4: // private key field + case 5: // both password and private key field + if (isset($this->details->private_key) && StringHelper::check($this->details->private_key)) + { + try + { + $key = $this->key::load(trim($this->details->private_key), $passphrase); + } + catch(\Exception $e) + { + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_LOADING_THE_PRIVATE_KEY_TEXT_FAILED') . ': ' . $e->getMessage(), + 'Error' + ); + $key = null; + } + } + break; + } + + // remove any null bites from the username + $this->details->username = trim($this->details->username); + + // login + if (!empty($key) && !empty($password)) + { + try + { + $sftp->login($this->details->username, $key, $password); + return $sftp; + } + catch(\Exception $e) + { + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_LOGIN_FAILED') . ': ' . $e->getMessage(), + 'Error' + ); + } + } + elseif (!empty($key)) + { + try + { + $sftp->login($this->details->username, $key); + return $sftp; + } + catch(\Exception $e) + { + $this->app->enqueueMessage( + Text::_('COM_COMPONENTBUILDER_LOGIN_FAILED') . ': ' . $e->getMessage(), + 'Error' + ); + } + } + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Crypt.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Crypt.php new file mode 100644 index 000000000..65947df85 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Crypt.php @@ -0,0 +1,187 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use phpseclib3\Crypt\AES as BASEAES; +use VDM\Joomla\Componentbuilder\Crypt as Crypto; +use VDM\Joomla\Componentbuilder\Crypt\KeyLoader; +use VDM\Joomla\Componentbuilder\Crypt\Random; +use VDM\Joomla\Componentbuilder\Crypt\Password; +use VDM\Joomla\Componentbuilder\Crypt\FOF; +use VDM\Joomla\Componentbuilder\Crypt\Aes; +use VDM\Joomla\Componentbuilder\Crypt\Aes\Legacy; + + +/** + * Phpseclib Crypt Service Provider + * + * @since 3.2.0 + */ +class Crypt implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Crypto::class, 'Crypt') + ->share('Crypt', [$this, 'getCrypt'], true); + + $container->alias(Random::class, 'Crypt.Random') + ->share('Crypt.Random', [$this, 'getRandom'], true); + + $container->alias(Password::class, 'Crypt.Password') + ->share('Crypt.Password', [$this, 'getPassword'], true); + + $container->alias(KeyLoader::class, 'Crypt.Key') + ->share('Crypt.Key', [$this, 'getKeyLoader'], true); + + $container->alias(BASEAES::class, 'Crypt.AESCBC') + ->share('Crypt.AESCBC', [$this, 'getBASEAESCBC'], false); + + $container->alias(FOF::class, 'Crypt.FOF') + ->share('Crypt.FOF', [$this, 'getFOF'], true); + + $container->alias(Aes::class, 'Crypt.AES.CBC') + ->share('Crypt.AES.CBC', [$this, 'getAesCBC'], true); + + $container->alias(Legacy::class, 'Crypt.AES.LEGACY') + ->share('Crypt.AES.LEGACY', [$this, 'getAesLEGACY'], true); + } + + /** + * Get the Crypto class + * + * @param Container $container The DI container. + * + * @return Crypto + * @since 3.2.0 + */ + public function getCrypt(Container $container): Crypto + { + return new Crypto( + $container->get('Crypt.FOF'), + $container->get('Crypt.AES.CBC'), + $container->get('Crypt.AES.LEGACY'), + $container->get('Crypt.Password') + ); + } + + /** + * Get the Password class + * + * @param Container $container The DI container. + * + * @return Password + * @since 3.2.0 + */ + public function getPassword(Container $container): Password + { + return new Password(); + } + + /** + * Get the Random class + * + * @param Container $container The DI container. + * + * @return Random + * @since 3.2.0 + */ + public function getRandom(Container $container): Random + { + return new Random(); + } + + /** + * Get the KeyLoader class + * + * @param Container $container The DI container. + * + * @return KeyLoader + * @since 3.2.0 + */ + public function getKeyLoader(Container $container): KeyLoader + { + return new KeyLoader(); + } + + /** + * Get the AES Cyper with CBC mode + * + * @param Container $container The DI container. + * + * @return BASEAES + * @since 3.2.0 + */ + public function getBASEAESCBC(Container $container): BASEAES + { + return new BASEAES('cbc'); + } + + /** + * Get the Wrapper AES Cyper with CBC mode + * + * @param Container $container The DI container. + * + * @return Aes + * @since 3.2.0 + */ + public function getAesCBC(Container $container): Aes + { + return new Aes( + $container->get('Crypt.AESCBC'), + $container->get('Crypt.Random') + ); + } + + /** + * Get the Wrapper AES Legacy Cyper with CBC mode + * + * @param Container $container The DI container. + * + * @return Legacy + * @since 3.2.0 + */ + public function getAesLEGACY(Container $container): Legacy + { + return new Legacy( + $container->get('Crypt.AESCBC') + ); + } + + /** + * Get the FOF AES Cyper with CBC mode + * + * @param Container $container The DI container. + * + * @return FOF + * @since 3.2.0 + */ + public function getFOF(Container $container): FOF + { + return new FOF( + $container->get('Crypt.AESCBC'), + $container->get('Crypt.Random') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Database.php new file mode 100644 index 000000000..c5a417bf5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Database.php @@ -0,0 +1,88 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Database\Load; +use VDM\Joomla\Database\Insert; +use VDM\Joomla\Database\Update; + + +/** + * Database Service Provider + * + * @since 3.2.0 + */ +class Database implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Load::class, 'Load') + ->share('Load', [$this, 'getLoad'], true); + + $container->alias(Insert::class, 'Insert') + ->share('Insert', [$this, 'getInsert'], true); + + $container->alias(Update::class, 'Update') + ->share('Update', [$this, 'getUpdate'], true); + } + + /** + * Get the Core Load Database + * + * @param Container $container The DI container. + * + * @return Load + * @since 3.2.0 + */ + public function getLoad(Container $container): Load + { + return new Load(); + } + + /** + * Get the Core Insert Database + * + * @param Container $container The DI container. + * + * @return Insert + * @since 3.2.0 + */ + public function getInsert(Container $container): Insert + { + return new Insert(); + } + + /** + * Get the Core Update Database + * + * @param Container $container The DI container. + * + * @return Update + * @since 3.2.0 + */ + public function getUpdate(Container $container): Update + { + return new Update(); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Gitea.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Gitea.php new file mode 100644 index 000000000..a4299c614 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Gitea.php @@ -0,0 +1,83 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Http; + + +/** + * The Gitea Utilities Service + * + * @since 3.2.0 + */ +class Gitea implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Gitea.Dynamic.Uri') + ->share('Gitea.Dynamic.Uri', [$this, 'getUri'], true); + + $container->alias(Http::class, 'Gitea.Utilities.Http') + ->share('Gitea.Utilities.Http', [$this, 'getHttp'], true); + } + + /** + * Get the Dynamic Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + // get the global gitea URL + $add_gitea_url = $container->get('Config')->get('add_custom_gitea_url', 1); + $gitea_url = $container->get('Config')->get('custom_gitea_url'); + + // only load this if we have a custom URL set + if ($add_gitea_url == 2 && !empty($gitea_url) && strpos($gitea_url, 'http') !== false) + { + return new Uri($gitea_url); + } + + return $container->get('Gitea.Utilities.Uri'); + } + + /** + * Get the Http class + * + * @param Container $container The DI container. + * + * @return Http + * @since 3.2.0 + */ + public function getHttp(Container $container): Http + { + return new Http( + $container->get('Config')->get('gitea_token') + ); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Server.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Server.php new file mode 100644 index 000000000..98933f081 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Server.php @@ -0,0 +1,114 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Server as Client; +use VDM\Joomla\Componentbuilder\Server\Load; +use VDM\Joomla\Componentbuilder\Server\Ftp; +use VDM\Joomla\Componentbuilder\Server\Sftp; + + +/** + * Server Service Provider + * + * @since 3.2.0 + */ +class Server implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Client::class, 'Server') + ->share('Server', [$this, 'getServer'], true); + + $container->alias(Load::class, 'Server.Load') + ->share('Server.Load', [$this, 'getServerLoad'], true); + + $container->alias(Ftp::class, 'Server.FTP') + ->share('Server.FTP', [$this, 'getServerFtp'], true); + $container->alias(Sftp::class, 'Server.SFTP') + ->share('Server.SFTP', [$this, 'getServerSftp'], true); + } + + /** + * Get the Server Client class + * + * @param Container $container The DI container. + * + * @return Client + * @since 3.2.0 + */ + public function getServer(Container $container): Client + { + return new Client( + $container->get('Server.Load'), + $container->get('Server.FTP'), + $container->get('Server.SFTP') + ); + } + + /** + * Get the Server Load class + * + * @param Container $container The DI container. + * + * @return Load + * @since 3.2.0 + */ + public function getServerLoad(Container $container): Load + { + return new Load( + $container->get('Load'), + $container->get('Model.Server.Load') + ); + } + + /** + * Get the Server Ftp class + * + * @param Container $container The DI container. + * + * @return Ftp + * @since 3.2.0 + */ + public function getServerFtp(Container $container): Ftp + { + return new Ftp(); + } + + /** + * Get the Server Sftp class + * + * @param Container $container The DI container. + * + * @return Sftp + * @since 3.2.0 + */ + public function getServerSftp(Container $container): Sftp + { + return new Sftp( + $container->get('Crypt.Key') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php new file mode 100644 index 000000000..0210aa25a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php @@ -0,0 +1,5585 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder; + + +use VDM\Joomla\Interfaces\Tableinterface; +use VDM\Joomla\Abstraction\BaseTable; + + +/** + * JCB Tables + * + * @since 3.2.0 + */ +class Table extends BaseTable implements Tableinterface +{ + /** + * All areas/views/tables with their field details + * + * @var array + * @since 3.2.0 + **/ + protected array $tables = [ + 'joomla_component' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'name_code' => [ + 'name' => 'name_code', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'short_description' => [ + 'name' => 'short_description', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_SHORT_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'companyname' => [ + 'name' => 'companyname', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPANYNAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'css_admin' => [ + 'name' => 'css_admin', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CSS_ADMIN_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'php_admin_event' => [ + 'name' => 'php_admin_event', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_ADMIN_EVENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'php_site_event' => [ + 'name' => 'php_site_event', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_SITE_EVENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'crowdin_username' => [ + 'name' => 'crowdin_username', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CROWDIN_USERNAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'basic_encryption', + 'tab_name' => 'Dynamic Integration', + ], + 'component_version' => [ + 'name' => 'component_version', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPONENT_VERSION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_postflight_install' => [ + 'name' => 'php_postflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_POSTFLIGHT_INSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Dash & Install', + ], + 'remove_line_breaks' => [ + 'name' => 'remove_line_breaks', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_REMOVE_LINE_BREAKS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'sql_uninstall' => [ + 'name' => 'sql_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_SQL_UNINSTALL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'debug_linenr' => [ + 'name' => 'debug_linenr', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_DEBUG_LINENR_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'mvc_versiondate' => [ + 'name' => 'mvc_versiondate', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MVC_VERSIONDATE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_preflight_install' => [ + 'name' => 'php_preflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_PREFLIGHT_INSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Dash & Install', + ], + 'backup_folder_path' => [ + 'name' => 'backup_folder_path', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_FOLDER_PATH_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'php_method_uninstall' => [ + 'name' => 'php_method_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_METHOD_UNINSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Dash & Install', + ], + 'add_placeholders' => [ + 'name' => 'add_placeholders', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PLACEHOLDERS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'author' => [ + 'name' => 'author', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_AUTHOR_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_sales_server' => [ + 'name' => 'add_sales_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_SALES_SERVER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'email' => [ + 'name' => 'email', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EMAIL_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'translation_tool' => [ + 'name' => 'translation_tool', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_TRANSLATION_TOOL_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'website' => [ + 'name' => 'website', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_WEBSITE_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'buildcompsql' => [ + 'name' => 'buildcompsql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMPSQL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Dynamic Build (beta)', + ], + 'add_license' => [ + 'name' => 'add_license', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_LICENSE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_helper_admin' => [ + 'name' => 'php_helper_admin', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_HELPER_ADMIN_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'license_type' => [ + 'name' => 'license_type', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_LICENSE_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_helper_site' => [ + 'name' => 'php_helper_site', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_HELPER_SITE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'javascript' => [ + 'name' => 'javascript', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_JAVASCRIPT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'whmcs_key' => [ + 'name' => 'whmcs_key', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_WHMCS_KEY_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'css_site' => [ + 'name' => 'css_site', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CSS_SITE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'whmcs_url' => [ + 'name' => 'whmcs_url', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_WHMCS_URL_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'whmcs_buy_link' => [ + 'name' => 'whmcs_buy_link', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_WHMCS_BUY_LINK_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_preflight_update' => [ + 'name' => 'php_preflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_PREFLIGHT_UPDATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Dash & Install', + ], + 'license' => [ + 'name' => 'license', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_LICENSE_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_postflight_update' => [ + 'name' => 'php_postflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_POSTFLIGHT_UPDATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Dash & Install', + ], + 'bom' => [ + 'name' => 'bom', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BOM_LABEL', + 'type' => 'filelist', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'sql' => [ + 'name' => 'sql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_SQL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'image' => [ + 'name' => 'image', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMAGE_LABEL', + 'type' => 'media', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'addreadme' => [ + 'name' => 'addreadme', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDREADME_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Readme', + ], + 'copyright' => [ + 'name' => 'copyright', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COPYRIGHT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'update_server_url' => [ + 'name' => 'update_server_url', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_UPDATE_SERVER_URL_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_powers' => [ + 'name' => 'add_powers', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_POWERS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_backup_folder_path' => [ + 'name' => 'add_backup_folder_path', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_BACKUP_FOLDER_PATH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'crowdin_project_identifier' => [ + 'name' => 'crowdin_project_identifier', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CROWDIN_PROJECT_IDENTIFIER_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'created' => [ + 'name' => 'created', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CREATED_LABEL', + 'type' => 'calendar', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'add_php_helper_admin' => [ + 'name' => 'add_php_helper_admin', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_HELPER_ADMIN_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'add_admin_event' => [ + 'name' => 'add_admin_event', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_ADMIN_EVENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'add_php_helper_site' => [ + 'name' => 'add_php_helper_site', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_HELPER_SITE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'add_site_event' => [ + 'name' => 'add_site_event', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_SITE_EVENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'add_javascript' => [ + 'name' => 'add_javascript', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_JAVASCRIPT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'add_menu_prefix' => [ + 'name' => 'add_menu_prefix', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_MENU_PREFIX_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'add_css_admin' => [ + 'name' => 'add_css_admin', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_CSS_ADMIN_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'menu_prefix' => [ + 'name' => 'menu_prefix', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'add_css_site' => [ + 'name' => 'add_css_site', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_CSS_SITE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'dashboard_type' => [ + 'name' => 'dashboard_type', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_DASHBOARD_TYPE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'dashboard' => [ + 'name' => 'dashboard', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_DASHBOARD_LABEL', + 'type' => 'dynamicdashboard', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'toignore' => [ + 'name' => 'toignore', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_TOIGNORE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'add_php_preflight_install' => [ + 'name' => 'add_php_preflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_PREFLIGHT_INSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'add_php_preflight_update' => [ + 'name' => 'add_php_preflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_PREFLIGHT_UPDATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'add_php_postflight_install' => [ + 'name' => 'add_php_postflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_POSTFLIGHT_INSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'export_key' => [ + 'name' => 'export_key', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'basic_encryption', + 'tab_name' => 'Settings', + ], + 'add_php_postflight_update' => [ + 'name' => 'add_php_postflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_POSTFLIGHT_UPDATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'joomla_source_link' => [ + 'name' => 'joomla_source_link', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_JOOMLA_SOURCE_LINK_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'add_php_method_uninstall' => [ + 'name' => 'add_php_method_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_METHOD_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dash & Install', + ], + 'export_buy_link' => [ + 'name' => 'export_buy_link', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_BUY_LINK_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'add_sql' => [ + 'name' => 'add_sql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_SQL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'add_sql_uninstall' => [ + 'name' => 'add_sql_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_SQL_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'assets_table_fix' => [ + 'name' => 'assets_table_fix', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'addcontributors' => [ + 'name' => 'addcontributors', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDCONTRIBUTORS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'json', + 'tab_name' => 'Settings', + ], + 'readme' => [ + 'name' => 'readme', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_README_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Readme', + ], + 'emptycontributors' => [ + 'name' => 'emptycontributors', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EMPTYCONTRIBUTORS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'add_update_server' => [ + 'name' => 'add_update_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UPDATE_SERVER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'number' => [ + 'name' => 'number', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NUMBER_LABEL', + 'type' => 'number', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Settings', + ], + 'update_server_target' => [ + 'name' => 'update_server_target', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_UPDATE_SERVER_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'update_server' => [ + 'name' => 'update_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_UPDATE_SERVER_LABEL', + 'type' => 'servers', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'sales_server' => [ + 'name' => 'sales_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_SALES_SERVER_LABEL', + 'type' => 'servers', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_git_folder_path' => [ + 'name' => 'add_git_folder_path', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_GIT_FOLDER_PATH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'git_folder_path' => [ + 'name' => 'git_folder_path', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GIT_FOLDER_PATH_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'creatuserhelper' => [ + 'name' => 'creatuserhelper', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CREATUSERHELPER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'adduikit' => [ + 'name' => 'adduikit', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDUIKIT_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'crowdin_project_api_key' => [ + 'name' => 'crowdin_project_api_key', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CROWDIN_PROJECT_API_KEY_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'basic_encryption', + 'tab_name' => 'Dynamic Integration', + ], + 'addfootable' => [ + 'name' => 'addfootable', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADDFOOTABLE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'crowdin_account_api_key' => [ + 'name' => 'crowdin_account_api_key', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CROWDIN_ACCOUNT_API_KEY_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'basic_encryption', + 'tab_name' => 'Dynamic Integration', + ], + 'add_email_helper' => [ + 'name' => 'add_email_helper', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_EMAIL_HELPER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'buildcomp' => [ + 'name' => 'buildcomp', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMP_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Dynamic Build (beta)', + ], + 'add_php_helper_both' => [ + 'name' => 'add_php_helper_both', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_PHP_HELPER_BOTH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Libs & Helpers', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'php_helper_both' => [ + 'name' => 'php_helper_both', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_PHP_HELPER_BOTH_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_components', + 'store' => 'base64', + 'tab_name' => 'Libs & Helpers', + ], + 'modified' => [ + 'name' => 'modified', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MODIFIED_LABEL', + 'type' => 'calendar', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_components', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'joomla_module' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'HTML', + ], + 'target' => [ + 'name' => 'target', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'HTML', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'HTML', + ], + 'add_php_method_uninstall' => [ + 'name' => 'add_php_method_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_METHOD_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'add_php_postflight_update' => [ + 'name' => 'add_php_postflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_POSTFLIGHT_UPDATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'add_php_postflight_install' => [ + 'name' => 'add_php_postflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_POSTFLIGHT_INSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'add_php_preflight_uninstall' => [ + 'name' => 'add_php_preflight_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_PREFLIGHT_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'addreadme' => [ + 'name' => 'addreadme', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADDREADME_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Readme', + ], + 'default' => [ + 'name' => 'default', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_DEFAULT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'HTML', + ], + 'snippet' => [ + 'name' => 'snippet', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_SNIPPET_LABEL', + 'type' => 'snippets', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'HTML', + ], + 'add_sql' => [ + 'name' => 'add_sql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_SQL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'update_server_target' => [ + 'name' => 'update_server_target', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_UPDATE_SERVER_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_sql_uninstall' => [ + 'name' => 'add_sql_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_SQL_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'update_server' => [ + 'name' => 'update_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_UPDATE_SERVER_LABEL', + 'type' => 'servers', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_update_server' => [ + 'name' => 'add_update_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_UPDATE_SERVER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'libraries' => [ + 'name' => 'libraries', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_LIBRARIES_LABEL', + 'type' => 'libraries', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'json', + 'tab_name' => 'HTML', + ], + 'module_version' => [ + 'name' => 'module_version', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_MODULE_VERSION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'HTML', + ], + 'sales_server' => [ + 'name' => 'sales_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_SALES_SERVER_LABEL', + 'type' => 'servers', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'custom_get' => [ + 'name' => 'custom_get', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_CUSTOM_GET_LABEL', + 'type' => 'customgets', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'php_preflight_update' => [ + 'name' => 'php_preflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_PREFLIGHT_UPDATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'php_preflight_uninstall' => [ + 'name' => 'php_preflight_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_PREFLIGHT_UNINSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'mod_code' => [ + 'name' => 'mod_code', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_MOD_CODE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Code', + ], + 'php_postflight_install' => [ + 'name' => 'php_postflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_POSTFLIGHT_INSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'add_class_helper' => [ + 'name' => 'add_class_helper', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_CLASS_HELPER_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Helper', + ], + 'php_postflight_update' => [ + 'name' => 'php_postflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_POSTFLIGHT_UPDATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'add_class_helper_header' => [ + 'name' => 'add_class_helper_header', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_CLASS_HELPER_HEADER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Helper', + ], + 'php_method_uninstall' => [ + 'name' => 'php_method_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_METHOD_UNINSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'class_helper_header' => [ + 'name' => 'class_helper_header', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_CLASS_HELPER_HEADER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Helper', + ], + 'sql' => [ + 'name' => 'sql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_SQL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'class_helper_code' => [ + 'name' => 'class_helper_code', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_CLASS_HELPER_CODE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Helper', + ], + 'sql_uninstall' => [ + 'name' => 'sql_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_SQL_UNINSTALL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'fields' => [ + 'name' => 'fields', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FIELDS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'json', + 'tab_name' => 'Forms & Fields', + ], + 'readme' => [ + 'name' => 'readme', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_README_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Readme', + ], + 'add_php_script_construct' => [ + 'name' => 'add_php_script_construct', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_SCRIPT_CONSTRUCT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'update_server_url' => [ + 'name' => 'update_server_url', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_UPDATE_SERVER_URL_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'php_script_construct' => [ + 'name' => 'php_script_construct', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_SCRIPT_CONSTRUCT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'add_php_preflight_install' => [ + 'name' => 'add_php_preflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_PREFLIGHT_INSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'php_preflight_install' => [ + 'name' => 'php_preflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_PHP_PREFLIGHT_INSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'add_sales_server' => [ + 'name' => 'add_sales_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_SALES_SERVER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_php_preflight_update' => [ + 'name' => 'add_php_preflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_ADD_PHP_PREFLIGHT_UPDATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_modules', + 'store' => NULL, + 'tab_name' => 'HTML', + ], + ], + 'joomla_plugin' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'class_extends' => [ + 'name' => 'class_extends', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_CLASS_EXTENDS_LABEL', + 'type' => 'classextends', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'joomla_plugin_group' => [ + 'name' => 'joomla_plugin_group', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_JOOMLA_PLUGIN_GROUP_LABEL', + 'type' => 'joomlaplugingroups', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'add_sql' => [ + 'name' => 'add_sql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_SQL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'add_php_method_uninstall' => [ + 'name' => 'add_php_method_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_METHOD_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'add_php_postflight_update' => [ + 'name' => 'add_php_postflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_POSTFLIGHT_UPDATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'add_php_postflight_install' => [ + 'name' => 'add_php_postflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_POSTFLIGHT_INSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'sales_server' => [ + 'name' => 'sales_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_SALES_SERVER_LABEL', + 'type' => 'servers', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_update_server' => [ + 'name' => 'add_update_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_UPDATE_SERVER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'method_selection' => [ + 'name' => 'method_selection', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_METHOD_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'property_selection' => [ + 'name' => 'property_selection', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PROPERTY_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'add_head' => [ + 'name' => 'add_head', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_HEAD_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'add_sql_uninstall' => [ + 'name' => 'add_sql_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_SQL_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'addreadme' => [ + 'name' => 'addreadme', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADDREADME_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Readme', + ], + 'head' => [ + 'name' => 'head', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_HEAD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Code', + ], + 'update_server_target' => [ + 'name' => 'update_server_target', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_UPDATE_SERVER_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'main_class_code' => [ + 'name' => 'main_class_code', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_MAIN_CLASS_CODE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Code', + ], + 'update_server' => [ + 'name' => 'update_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_UPDATE_SERVER_LABEL', + 'type' => 'servers', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'php_postflight_install' => [ + 'name' => 'php_postflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_POSTFLIGHT_INSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'plugin_version' => [ + 'name' => 'plugin_version', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PLUGIN_VERSION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'php_postflight_update' => [ + 'name' => 'php_postflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_POSTFLIGHT_UPDATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'fields' => [ + 'name' => 'fields', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FIELDS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'json', + 'tab_name' => 'Forms & Fields', + ], + 'php_method_uninstall' => [ + 'name' => 'php_method_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_METHOD_UNINSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'add_php_script_construct' => [ + 'name' => 'add_php_script_construct', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_SCRIPT_CONSTRUCT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'sql' => [ + 'name' => 'sql', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_SQL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'php_script_construct' => [ + 'name' => 'php_script_construct', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_SCRIPT_CONSTRUCT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'sql_uninstall' => [ + 'name' => 'sql_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_SQL_UNINSTALL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'add_php_preflight_install' => [ + 'name' => 'add_php_preflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_PREFLIGHT_INSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'readme' => [ + 'name' => 'readme', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_README_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Readme', + ], + 'php_preflight_install' => [ + 'name' => 'php_preflight_install', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_PREFLIGHT_INSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'update_server_url' => [ + 'name' => 'update_server_url', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_UPDATE_SERVER_URL_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'add_php_preflight_update' => [ + 'name' => 'add_php_preflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_PREFLIGHT_UPDATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'php_preflight_update' => [ + 'name' => 'php_preflight_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_PREFLIGHT_UPDATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'add_php_preflight_uninstall' => [ + 'name' => 'add_php_preflight_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_PHP_PREFLIGHT_UNINSTALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Script File', + ], + 'add_sales_server' => [ + 'name' => 'add_sales_server', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_ADD_SALES_SERVER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Dynamic Integration', + ], + 'php_preflight_uninstall' => [ + 'name' => 'php_preflight_uninstall', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_PHP_PREFLIGHT_UNINSTALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => 'base64', + 'tab_name' => 'Script File', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'joomla_plugins', + 'store' => NULL, + 'tab_name' => 'Code', + ], + ], + 'power' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'namespace' => [ + 'name' => 'namespace', + 'label' => 'COM_COMPONENTBUILDER_POWER_NAMESPACE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'type' => [ + 'name' => 'type', + 'label' => 'COM_COMPONENTBUILDER_POWER_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'power_version' => [ + 'name' => 'power_version', + 'label' => 'COM_COMPONENTBUILDER_POWER_POWER_VERSION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'method_selection' => [ + 'name' => 'method_selection', + 'label' => 'COM_COMPONENTBUILDER_POWER_METHOD_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'load_selection' => [ + 'name' => 'load_selection', + 'label' => 'COM_COMPONENTBUILDER_POWER_LOAD_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'licensing_template' => [ + 'name' => 'licensing_template', + 'label' => 'COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'powers', + 'store' => 'base64', + 'tab_name' => 'Licensing', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_POWER_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'composer' => [ + 'name' => 'composer', + 'label' => 'COM_COMPONENTBUILDER_POWER_COMPOSER_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Composer', + ], + 'extends' => [ + 'name' => 'extends', + 'label' => 'COM_COMPONENTBUILDER_POWER_EXTENDS_LABEL', + 'type' => 'classpowers', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'approved' => [ + 'name' => 'approved', + 'label' => 'COM_COMPONENTBUILDER_POWER_APPROVED_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Super Power', + ], + 'property_selection' => [ + 'name' => 'property_selection', + 'label' => 'COM_COMPONENTBUILDER_POWER_PROPERTY_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'add_head' => [ + 'name' => 'add_head', + 'label' => 'COM_COMPONENTBUILDER_POWER_ADD_HEAD_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'extends_custom' => [ + 'name' => 'extends_custom', + 'label' => 'COM_COMPONENTBUILDER_POWER_EXTENDS_CUSTOM_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'implements_custom' => [ + 'name' => 'implements_custom', + 'label' => 'COM_COMPONENTBUILDER_POWER_IMPLEMENTS_CUSTOM_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'implements' => [ + 'name' => 'implements', + 'label' => 'COM_COMPONENTBUILDER_POWER_IMPLEMENTS_LABEL', + 'type' => 'interfacepowers', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'head' => [ + 'name' => 'head', + 'label' => 'COM_COMPONENTBUILDER_POWER_HEAD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'powers', + 'store' => 'base64', + 'tab_name' => 'Code', + ], + 'approved_paths' => [ + 'name' => 'approved_paths', + 'label' => 'COM_COMPONENTBUILDER_POWER_APPROVED_PATHS_LABEL', + 'type' => 'superpowerpaths', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Super Power', + ], + 'use_selection' => [ + 'name' => 'use_selection', + 'label' => 'COM_COMPONENTBUILDER_POWER_USE_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Code', + ], + 'main_class_code' => [ + 'name' => 'main_class_code', + 'label' => 'COM_COMPONENTBUILDER_POWER_MAIN_CLASS_CODE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'powers', + 'store' => 'base64', + 'tab_name' => 'Code', + ], + 'add_licensing_template' => [ + 'name' => 'add_licensing_template', + 'label' => 'COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Licensing', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_POWER_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_POWER_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + ], + 'admin_view' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'name_single' => [ + 'name' => 'name_single', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_SINGLE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'short_description' => [ + 'name' => 'short_description', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_SHORT_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_allowedit' => [ + 'name' => 'php_allowedit', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_ALLOWEDIT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_postsavehook' => [ + 'name' => 'php_postsavehook', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_POSTSAVEHOOK_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_before_save' => [ + 'name' => 'php_before_save', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_BEFORE_SAVE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_getlistquery' => [ + 'name' => 'php_getlistquery', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_GETLISTQUERY_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_import_ext' => [ + 'name' => 'php_import_ext', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_IMPORT_EXT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'icon' => [ + 'name' => 'icon', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ICON_LABEL', + 'type' => 'media', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_after_publish' => [ + 'name' => 'php_after_publish', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_AFTER_PUBLISH_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'add_fadein' => [ + 'name' => 'add_fadein', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_FADEIN_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'icon_category' => [ + 'name' => 'icon_category', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ICON_CATEGORY_LABEL', + 'type' => 'media', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'icon_add' => [ + 'name' => 'icon_add', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ICON_ADD_LABEL', + 'type' => 'media', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_after_cancel' => [ + 'name' => 'php_after_cancel', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_AFTER_CANCEL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'mysql_table_charset' => [ + 'name' => 'mysql_table_charset', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_MYSQL_TABLE_CHARSET_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'php_batchmove' => [ + 'name' => 'php_batchmove', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_BATCHMOVE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'type' => [ + 'name' => 'type', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_after_delete' => [ + 'name' => 'php_after_delete', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_AFTER_DELETE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'source' => [ + 'name' => 'source', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_SOURCE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'php_import' => [ + 'name' => 'php_import', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_IMPORT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'addpermissions' => [ + 'name' => 'addpermissions', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADDPERMISSIONS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'Settings', + ], + 'php_getitems_after_all' => [ + 'name' => 'php_getitems_after_all', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_GETITEMS_AFTER_ALL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_getform' => [ + 'name' => 'php_getform', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_GETFORM_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'addtabs' => [ + 'name' => 'addtabs', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADDTABS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'Settings', + ], + 'php_save' => [ + 'name' => 'php_save', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_SAVE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_allowadd' => [ + 'name' => 'php_allowadd', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_ALLOWADD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_before_cancel' => [ + 'name' => 'php_before_cancel', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_BEFORE_CANCEL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'addlinked_views' => [ + 'name' => 'addlinked_views', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADDLINKED_VIEWS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'Settings', + ], + 'php_batchcopy' => [ + 'name' => 'php_batchcopy', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_BATCHCOPY_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_before_publish' => [ + 'name' => 'php_before_publish', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_BEFORE_PUBLISH_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'alias_builder_type' => [ + 'name' => 'alias_builder_type', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ALIAS_BUILDER_TYPE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Fields', + ], + 'php_before_delete' => [ + 'name' => 'php_before_delete', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_BEFORE_DELETE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_document' => [ + 'name' => 'php_document', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'mysql_table_row_format' => [ + 'name' => 'mysql_table_row_format', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_MYSQL_TABLE_ROW_FORMAT_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'alias_builder' => [ + 'name' => 'alias_builder', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ALIAS_BUILDER_LABEL', + 'type' => 'aliasbuilder', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'Fields', + ], + 'sql' => [ + 'name' => 'sql', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_SQL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'MySQL', + ], + 'php_import_display' => [ + 'name' => 'php_import_display', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_IMPORT_DISPLAY_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'add_category_submenu' => [ + 'name' => 'add_category_submenu', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_CATEGORY_SUBMENU_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Fields', + ], + 'php_import_setdata' => [ + 'name' => 'php_import_setdata', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_IMPORT_SETDATA_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'name_list' => [ + 'name' => 'name_list', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_NAME_LIST_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_php_getlistquery' => [ + 'name' => 'add_php_getlistquery', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_GETLISTQUERY_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_css_view' => [ + 'name' => 'add_css_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_CSS_VIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'CSS', + ], + 'add_php_getform' => [ + 'name' => 'add_php_getform', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_GETFORM_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'css_view' => [ + 'name' => 'css_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_CSS_VIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'CSS', + ], + 'add_php_before_save' => [ + 'name' => 'add_php_before_save', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_BEFORE_SAVE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_css_views' => [ + 'name' => 'add_css_views', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_CSS_VIEWS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'CSS', + ], + 'add_php_save' => [ + 'name' => 'add_php_save', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_SAVE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'css_views' => [ + 'name' => 'css_views', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_CSS_VIEWS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'CSS', + ], + 'add_php_postsavehook' => [ + 'name' => 'add_php_postsavehook', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_POSTSAVEHOOK_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_javascript_view_file' => [ + 'name' => 'add_javascript_view_file', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_JAVASCRIPT_VIEW_FILE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript', + ], + 'add_php_allowadd' => [ + 'name' => 'add_php_allowadd', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_ALLOWADD_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'javascript_view_file' => [ + 'name' => 'javascript_view_file', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_JAVASCRIPT_VIEW_FILE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript', + ], + 'add_php_allowedit' => [ + 'name' => 'add_php_allowedit', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_ALLOWEDIT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_javascript_view_footer' => [ + 'name' => 'add_javascript_view_footer', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_JAVASCRIPT_VIEW_FOOTER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript', + ], + 'add_php_before_cancel' => [ + 'name' => 'add_php_before_cancel', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_BEFORE_CANCEL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'javascript_view_footer' => [ + 'name' => 'javascript_view_footer', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_JAVASCRIPT_VIEW_FOOTER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript', + ], + 'add_php_after_cancel' => [ + 'name' => 'add_php_after_cancel', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_AFTER_CANCEL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_javascript_views_file' => [ + 'name' => 'add_javascript_views_file', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_JAVASCRIPT_VIEWS_FILE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript', + ], + 'add_php_batchcopy' => [ + 'name' => 'add_php_batchcopy', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_BATCHCOPY_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'javascript_views_file' => [ + 'name' => 'javascript_views_file', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_JAVASCRIPT_VIEWS_FILE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript', + ], + 'add_php_batchmove' => [ + 'name' => 'add_php_batchmove', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_BATCHMOVE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_javascript_views_footer' => [ + 'name' => 'add_javascript_views_footer', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_JAVASCRIPT_VIEWS_FOOTER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript', + ], + 'add_php_before_publish' => [ + 'name' => 'add_php_before_publish', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_BEFORE_PUBLISH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'javascript_views_footer' => [ + 'name' => 'javascript_views_footer', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_JAVASCRIPT_VIEWS_FOOTER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript', + ], + 'add_php_after_publish' => [ + 'name' => 'add_php_after_publish', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_AFTER_PUBLISH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_custom_button' => [ + 'name' => 'add_custom_button', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_CUSTOM_BUTTON_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Custom Buttons', + ], + 'add_php_before_delete' => [ + 'name' => 'add_php_before_delete', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_BEFORE_DELETE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'custom_button' => [ + 'name' => 'custom_button', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_CUSTOM_BUTTON_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'Custom Buttons', + ], + 'add_php_after_delete' => [ + 'name' => 'add_php_after_delete', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_AFTER_DELETE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'php_controller' => [ + 'name' => 'php_controller', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_CONTROLLER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + 'add_php_document' => [ + 'name' => 'add_php_document', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'php_model' => [ + 'name' => 'php_model', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_MODEL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + 'mysql_table_engine' => [ + 'name' => 'mysql_table_engine', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_MYSQL_TABLE_ENGINE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'php_controller_list' => [ + 'name' => 'php_controller_list', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_CONTROLLER_LIST_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + 'mysql_table_collate' => [ + 'name' => 'mysql_table_collate', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_MYSQL_TABLE_COLLATE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'php_model_list' => [ + 'name' => 'php_model_list', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_MODEL_LIST_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + 'add_sql' => [ + 'name' => 'add_sql', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_SQL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'MySQL', + ], + 'add_php_ajax' => [ + 'name' => 'add_php_ajax', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_AJAX_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'addtables' => [ + 'name' => 'addtables', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADDTABLES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'MySQL', + ], + 'php_ajaxmethod' => [ + 'name' => 'php_ajaxmethod', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_AJAXMETHOD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'ajax_input' => [ + 'name' => 'ajax_input', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_AJAX_INPUT_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'json', + 'tab_name' => 'PHP', + ], + 'add_custom_import' => [ + 'name' => 'add_custom_import', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_CUSTOM_IMPORT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'Custom Import', + ], + 'add_php_getitem' => [ + 'name' => 'add_php_getitem', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_GETITEM_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'html_import_view' => [ + 'name' => 'html_import_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_HTML_IMPORT_VIEW_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'php_getitem' => [ + 'name' => 'php_getitem', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_GETITEM_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_import_headers' => [ + 'name' => 'php_import_headers', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_IMPORT_HEADERS_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'add_php_getitems' => [ + 'name' => 'add_php_getitems', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_GETITEMS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'php_import_save' => [ + 'name' => 'php_import_save', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_IMPORT_SAVE_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Import', + ], + 'php_getitems' => [ + 'name' => 'php_getitems', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_PHP_GETITEMS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'add_php_getitems_after_all' => [ + 'name' => 'add_php_getitems_after_all', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_VIEW_ADD_PHP_GETITEMS_AFTER_ALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + ], + 'custom_admin_view' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'main_get' => [ + 'name' => 'main_get', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_MAIN_GET_LABEL', + 'type' => 'maingets', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_php_jview_display' => [ + 'name' => 'add_php_jview_display', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_PHP_JVIEW_DISPLAY_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'css_document' => [ + 'name' => 'css_document', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CSS_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'css' => [ + 'name' => 'css', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CSS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'js_document' => [ + 'name' => 'js_document', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_JS_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'javascript_file' => [ + 'name' => 'javascript_file', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_JAVASCRIPT_FILE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'codename' => [ + 'name' => 'codename', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CODENAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'default' => [ + 'name' => 'default', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_DEFAULT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'snippet' => [ + 'name' => 'snippet', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_SNIPPET_LABEL', + 'type' => 'snippets', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'icon' => [ + 'name' => 'icon', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ICON_LABEL', + 'type' => 'media', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_php_jview' => [ + 'name' => 'add_php_jview', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_PHP_JVIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'context' => [ + 'name' => 'context', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CONTEXT_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_js_document' => [ + 'name' => 'add_js_document', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_JS_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'custom_get' => [ + 'name' => 'custom_get', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CUSTOM_GET_LABEL', + 'type' => 'customgets', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'add_javascript_file' => [ + 'name' => 'add_javascript_file', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_JAVASCRIPT_FILE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'php_ajaxmethod' => [ + 'name' => 'php_ajaxmethod', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_AJAXMETHOD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'add_css_document' => [ + 'name' => 'add_css_document', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_CSS_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'add_php_document' => [ + 'name' => 'add_php_document', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_PHP_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_css' => [ + 'name' => 'add_css', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_CSS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'add_php_view' => [ + 'name' => 'add_php_view', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_PHP_VIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_php_ajax' => [ + 'name' => 'add_php_ajax', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_PHP_AJAX_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'libraries' => [ + 'name' => 'libraries', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_LIBRARIES_LABEL', + 'type' => 'libraries', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'ajax_input' => [ + 'name' => 'ajax_input', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_AJAX_INPUT_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'json', + 'tab_name' => 'PHP', + ], + 'dynamic_get' => [ + 'name' => 'dynamic_get', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_DYNAMIC_GET_LABEL', + 'type' => 'dynamicgets', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_document' => [ + 'name' => 'php_document', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_view' => [ + 'name' => 'php_view', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_VIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'add_custom_button' => [ + 'name' => 'add_custom_button', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_ADD_CUSTOM_BUTTON_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Custom Buttons', + ], + 'php_jview_display' => [ + 'name' => 'php_jview_display', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_JVIEW_DISPLAY_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'custom_button' => [ + 'name' => 'custom_button', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_CUSTOM_BUTTON_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'json', + 'tab_name' => 'Custom Buttons', + ], + 'php_jview' => [ + 'name' => 'php_jview', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_JVIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_controller' => [ + 'name' => 'php_controller', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_CONTROLLER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'php_model' => [ + 'name' => 'php_model', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_ADMIN_VIEW_PHP_MODEL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_admin_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + ], + 'site_view' => [ + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'main_get' => [ + 'name' => 'main_get', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_MAIN_GET_LABEL', + 'type' => 'maingets', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_php_jview_display' => [ + 'name' => 'add_php_jview_display', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_PHP_JVIEW_DISPLAY_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_php_document' => [ + 'name' => 'add_php_document', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_PHP_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'add_php_view' => [ + 'name' => 'add_php_view', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_PHP_VIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'js_document' => [ + 'name' => 'js_document', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_JS_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'codename' => [ + 'name' => 'codename', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'javascript_file' => [ + 'name' => 'javascript_file', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_JAVASCRIPT_FILE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'context' => [ + 'name' => 'context', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_CONTEXT_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'default' => [ + 'name' => 'default', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_DEFAULT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'snippet' => [ + 'name' => 'snippet', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_SNIPPET_LABEL', + 'type' => 'snippets', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_php_jview' => [ + 'name' => 'add_php_jview', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_PHP_JVIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'custom_get' => [ + 'name' => 'custom_get', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_CUSTOM_GET_LABEL', + 'type' => 'customgets', + 'title' => false, + 'list' => 'site_views', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'css_document' => [ + 'name' => 'css_document', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_CSS_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'add_javascript_file' => [ + 'name' => 'add_javascript_file', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_JAVASCRIPT_FILE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'css' => [ + 'name' => 'css', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_CSS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'JavaScript & CSS', + ], + 'add_js_document' => [ + 'name' => 'add_js_document', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_JS_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'php_ajaxmethod' => [ + 'name' => 'php_ajaxmethod', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_AJAXMETHOD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'add_css_document' => [ + 'name' => 'add_css_document', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_CSS_DOCUMENT_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'libraries' => [ + 'name' => 'libraries', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_LIBRARIES_LABEL', + 'type' => 'libraries', + 'title' => false, + 'list' => 'site_views', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'add_css' => [ + 'name' => 'add_css', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_CSS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'JavaScript & CSS', + ], + 'dynamic_get' => [ + 'name' => 'dynamic_get', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_DYNAMIC_GET_LABEL', + 'type' => 'dynamicgets', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'add_php_ajax' => [ + 'name' => 'add_php_ajax', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_PHP_AJAX_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'PHP', + ], + 'ajax_input' => [ + 'name' => 'ajax_input', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_AJAX_INPUT_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'site_views', + 'store' => 'json', + 'tab_name' => 'PHP', + ], + 'add_custom_button' => [ + 'name' => 'add_custom_button', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_ADD_CUSTOM_BUTTON_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Custom Buttons', + ], + 'php_document' => [ + 'name' => 'php_document', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_DOCUMENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'button_position' => [ + 'name' => 'button_position', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_BUTTON_POSITION_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'Custom Buttons', + ], + 'php_view' => [ + 'name' => 'php_view', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_VIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_jview_display' => [ + 'name' => 'php_jview_display', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_JVIEW_DISPLAY_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'custom_button' => [ + 'name' => 'custom_button', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_CUSTOM_BUTTON_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'site_views', + 'store' => 'json', + 'tab_name' => 'Custom Buttons', + ], + 'php_jview' => [ + 'name' => 'php_jview', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_JVIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'PHP', + ], + 'php_controller' => [ + 'name' => 'php_controller', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_CONTROLLER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'site_views', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'php_model' => [ + 'name' => 'php_model', + 'label' => 'COM_COMPONENTBUILDER_SITE_VIEW_PHP_MODEL_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'site_views', + 'store' => 'base64', + 'tab_name' => 'Custom Buttons', + ], + ], + 'template' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'templates', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'templates', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'dynamic_get' => [ + 'name' => 'dynamic_get', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_DYNAMIC_GET_LABEL', + 'type' => 'dynamicget', + 'title' => false, + 'list' => 'templates', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_view' => [ + 'name' => 'php_view', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_PHP_VIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'templates', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'add_php_view' => [ + 'name' => 'add_php_view', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_ADD_PHP_VIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'templates', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'template' => [ + 'name' => 'template', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_TEMPLATE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'templates', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'snippet' => [ + 'name' => 'snippet', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_SNIPPET_LABEL', + 'type' => 'snippets', + 'title' => false, + 'list' => 'templates', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'libraries' => [ + 'name' => 'libraries', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_LIBRARIES_LABEL', + 'type' => 'libraries', + 'title' => false, + 'list' => 'templates', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'alias' => [ + 'name' => 'alias', + 'label' => 'COM_COMPONENTBUILDER_TEMPLATE_ALIAS_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'templates', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'layout' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'layouts', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'layouts', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'dynamic_get' => [ + 'name' => 'dynamic_get', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_DYNAMIC_GET_LABEL', + 'type' => 'dynamicget', + 'title' => false, + 'list' => 'layouts', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'snippet' => [ + 'name' => 'snippet', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_SNIPPET_LABEL', + 'type' => 'snippets', + 'title' => false, + 'list' => 'layouts', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'php_view' => [ + 'name' => 'php_view', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_PHP_VIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'layouts', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'add_php_view' => [ + 'name' => 'add_php_view', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_ADD_PHP_VIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'layouts', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'layout' => [ + 'name' => 'layout', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_LAYOUT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'layouts', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'libraries' => [ + 'name' => 'libraries', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_LIBRARIES_LABEL', + 'type' => 'libraries', + 'title' => false, + 'list' => 'layouts', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'alias' => [ + 'name' => 'alias', + 'label' => 'COM_COMPONENTBUILDER_LAYOUT_ALIAS_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'layouts', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'dynamic_get' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'main_source' => [ + 'name' => 'main_source', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_MAIN_SOURCE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'gettype' => [ + 'name' => 'gettype', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_GETTYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'php_router_parse' => [ + 'name' => 'php_router_parse', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_ROUTER_PARSE_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'php_before_getitems' => [ + 'name' => 'php_before_getitems', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_BEFORE_GETITEMS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'php_after_getitems' => [ + 'name' => 'php_after_getitems', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_AFTER_GETITEMS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'php_after_getitem' => [ + 'name' => 'php_after_getitem', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_AFTER_GETITEM_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'php_getlistquery' => [ + 'name' => 'php_getlistquery', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_GETLISTQUERY_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'join_db_table' => [ + 'name' => 'join_db_table', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_JOIN_DB_TABLE_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Joint', + ], + 'view_selection' => [ + 'name' => 'view_selection', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_VIEW_SELECTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'db_table_main' => [ + 'name' => 'db_table_main', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_DB_TABLE_MAIN_LABEL', + 'type' => 'dbtables', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'php_custom_get' => [ + 'name' => 'php_custom_get', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_CUSTOM_GET_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Main', + ], + 'plugin_events' => [ + 'name' => 'plugin_events', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PLUGIN_EVENTS_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Main', + ], + 'db_selection' => [ + 'name' => 'db_selection', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_DB_SELECTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'php_calculation' => [ + 'name' => 'php_calculation', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_CALCULATION_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Abacus', + ], + 'php_before_getitem' => [ + 'name' => 'php_before_getitem', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PHP_BEFORE_GETITEM_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'base64', + 'tab_name' => 'Custom Script', + ], + 'view_table_main' => [ + 'name' => 'view_table_main', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_VIEW_TABLE_MAIN_LABEL', + 'type' => 'adminviews', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'select_all' => [ + 'name' => 'select_all', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_SELECT_ALL_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'add_php_before_getitem' => [ + 'name' => 'add_php_before_getitem', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADD_PHP_BEFORE_GETITEM_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'getcustom' => [ + 'name' => 'getcustom', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_GETCUSTOM_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'add_php_after_getitem' => [ + 'name' => 'add_php_after_getitem', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADD_PHP_AFTER_GETITEM_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'pagination' => [ + 'name' => 'pagination', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_PAGINATION_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Main', + ], + 'add_php_getlistquery' => [ + 'name' => 'add_php_getlistquery', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADD_PHP_GETLISTQUERY_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'add_php_before_getitems' => [ + 'name' => 'add_php_before_getitems', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADD_PHP_BEFORE_GETITEMS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'filter' => [ + 'name' => 'filter', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_FILTER_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Tweak', + ], + 'add_php_after_getitems' => [ + 'name' => 'add_php_after_getitems', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADD_PHP_AFTER_GETITEMS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'where' => [ + 'name' => 'where', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_WHERE_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Tweak', + ], + 'add_php_router_parse' => [ + 'name' => 'add_php_router_parse', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADD_PHP_ROUTER_PARSE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Custom Script', + ], + 'order' => [ + 'name' => 'order', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ORDER_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Tweak', + ], + 'addcalculation' => [ + 'name' => 'addcalculation', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_ADDCALCULATION_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'Abacus', + ], + 'group' => [ + 'name' => 'group', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_GROUP_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Tweak', + ], + 'global' => [ + 'name' => 'global', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_GLOBAL_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Tweak', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'join_view_table' => [ + 'name' => 'join_view_table', + 'label' => 'COM_COMPONENTBUILDER_DYNAMIC_GET_JOIN_VIEW_TABLE_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'dynamic_gets', + 'store' => 'json', + 'tab_name' => 'Joint', + ], + ], + 'custom_code' => [ + 'component' => [ + 'name' => 'component', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_COMPONENT_LABEL', + 'type' => 'joomlacomponent', + 'title' => true, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'path' => [ + 'name' => 'path', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_PATH_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'target' => [ + 'name' => 'target', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'type' => [ + 'name' => 'type', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_TYPE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'comment_type' => [ + 'name' => 'comment_type', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_COMMENT_TYPE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'function_name' => [ + 'name' => 'function_name', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_FUNCTION_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'system_name' => [ + 'name' => 'system_name', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_SYSTEM_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'code' => [ + 'name' => 'code', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_CODE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'custom_codes', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'hashendtarget' => [ + 'name' => 'hashendtarget', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_HASHENDTARGET_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'to_line' => [ + 'name' => 'to_line', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_TO_LINE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'from_line' => [ + 'name' => 'from_line', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_FROM_LINE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'hashtarget' => [ + 'name' => 'hashtarget', + 'label' => 'COM_COMPONENTBUILDER_CUSTOM_CODE_HASHTARGET_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'custom_codes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'class_property' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'class_properties', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'visibility' => [ + 'name' => 'visibility', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_VISIBILITY_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'class_properties', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'extension_type' => [ + 'name' => 'extension_type', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_EXTENSION_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'class_properties', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'class_properties', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'comment' => [ + 'name' => 'comment', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_COMMENT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'class_properties', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'joomla_plugin_group' => [ + 'name' => 'joomla_plugin_group', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_JOOMLA_PLUGIN_GROUP_LABEL', + 'type' => 'joomlaplugingroups', + 'title' => false, + 'list' => 'class_properties', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'default' => [ + 'name' => 'default', + 'label' => 'COM_COMPONENTBUILDER_CLASS_PROPERTY_DEFAULT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'class_properties', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + ], + 'class_method' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'class_methods', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'visibility' => [ + 'name' => 'visibility', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_VISIBILITY_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'class_methods', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'extension_type' => [ + 'name' => 'extension_type', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_EXTENSION_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'class_methods', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'class_methods', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'code' => [ + 'name' => 'code', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_CODE_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'class_methods', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'comment' => [ + 'name' => 'comment', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_COMMENT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'class_methods', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'joomla_plugin_group' => [ + 'name' => 'joomla_plugin_group', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_JOOMLA_PLUGIN_GROUP_LABEL', + 'type' => 'joomlaplugingroups', + 'title' => false, + 'list' => 'class_methods', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'arguments' => [ + 'name' => 'arguments', + 'label' => 'COM_COMPONENTBUILDER_CLASS_METHOD_ARGUMENTS_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'class_methods', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + ], + 'placeholder' => [ + 'target' => [ + 'name' => 'target', + 'label' => 'COM_COMPONENTBUILDER_PLACEHOLDER_TARGET_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'placeholders', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'value' => [ + 'name' => 'value', + 'label' => 'COM_COMPONENTBUILDER_PLACEHOLDER_VALUE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'placeholders', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + ], + 'library' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'libraries', + 'store' => NULL, + 'tab_name' => 'Behaviour', + ], + 'target' => [ + 'name' => 'target', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'libraries', + 'store' => NULL, + 'tab_name' => 'Behaviour', + ], + 'how' => [ + 'name' => 'how', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_HOW_LABEL', + 'type' => 'filebehaviour', + 'title' => false, + 'list' => 'libraries', + 'store' => NULL, + 'tab_name' => 'Behaviour', + ], + 'type' => [ + 'name' => 'type', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_TYPE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'libraries', + 'store' => NULL, + 'tab_name' => 'Behaviour', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'libraries', + 'store' => NULL, + 'tab_name' => 'Behaviour', + ], + 'libraries' => [ + 'name' => 'libraries', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_LIBRARIES_LABEL', + 'type' => 'librariesx', + 'title' => false, + 'list' => 'libraries', + 'store' => 'json', + 'tab_name' => 'Behaviour', + ], + 'php_setdocument' => [ + 'name' => 'php_setdocument', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_PHP_SETDOCUMENT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'libraries', + 'store' => 'base64', + 'tab_name' => 'Behaviour', + ], + 'addconditions' => [ + 'name' => 'addconditions', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_ADDCONDITIONS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries', + 'store' => 'json', + 'tab_name' => 'Behaviour', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'libraries', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + ], + 'snippet' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'url' => [ + 'name' => 'url', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_URL_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'type' => [ + 'name' => 'type', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_TYPE_LABEL', + 'type' => 'snippettype', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'heading' => [ + 'name' => 'heading', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_HEADING_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'library' => [ + 'name' => 'library', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_LIBRARY_LABEL', + 'type' => 'library', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'contributor_email' => [ + 'name' => 'contributor_email', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_CONTRIBUTOR_EMAIL_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Contributor', + ], + 'contributor_name' => [ + 'name' => 'contributor_name', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_CONTRIBUTOR_NAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Contributor', + ], + 'contributor_website' => [ + 'name' => 'contributor_website', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_CONTRIBUTOR_WEBSITE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Contributor', + ], + 'contributor_company' => [ + 'name' => 'contributor_company', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_CONTRIBUTOR_COMPANY_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Contributor', + ], + 'snippet' => [ + 'name' => 'snippet', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_SNIPPET_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'snippets', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'usage' => [ + 'name' => 'usage', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_USAGE_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'snippets', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'validation_rule' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_VALIDATION_RULE_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'validation_rules', + 'store' => NULL, + 'tab_name' => 'Extends FormRule', + ], + 'short_description' => [ + 'name' => 'short_description', + 'label' => 'COM_COMPONENTBUILDER_VALIDATION_RULE_SHORT_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'validation_rules', + 'store' => NULL, + 'tab_name' => 'Extends FormRule', + ], + 'inherit' => [ + 'name' => 'inherit', + 'label' => 'COM_COMPONENTBUILDER_VALIDATION_RULE_INHERIT_LABEL', + 'type' => 'existingvalidationrules', + 'title' => false, + 'list' => 'validation_rules', + 'store' => NULL, + 'tab_name' => 'Extends FormRule', + ], + 'php' => [ + 'name' => 'php', + 'label' => 'COM_COMPONENTBUILDER_VALIDATION_RULE_PHP_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'validation_rules', + 'store' => 'base64', + 'tab_name' => 'Extends FormRule', + ], + ], + 'field' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_FIELD_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Set Properties', + ], + 'fieldtype' => [ + 'name' => 'fieldtype', + 'label' => 'COM_COMPONENTBUILDER_FIELD_FIELDTYPE_LABEL', + 'type' => 'fieldtypes', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Set Properties', + ], + 'datatype' => [ + 'name' => 'datatype', + 'label' => 'COM_COMPONENTBUILDER_FIELD_DATATYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'indexes' => [ + 'name' => 'indexes', + 'label' => 'COM_COMPONENTBUILDER_FIELD_INDEXES_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'null_switch' => [ + 'name' => 'null_switch', + 'label' => 'COM_COMPONENTBUILDER_FIELD_NULL_SWITCH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'store' => [ + 'name' => 'store', + 'label' => 'COM_COMPONENTBUILDER_FIELD_STORE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'catid' => [ + 'name' => 'catid', + 'label' => 'COM_COMPONENTBUILDER_FIELD_CATID_LABEL', + 'type' => 'category', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Set Properties', + ], + 'on_save_model_field' => [ + 'name' => 'on_save_model_field', + 'label' => 'COM_COMPONENTBUILDER_FIELD_ON_SAVE_MODEL_FIELD_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Database', + ], + 'initiator_on_get_model' => [ + 'name' => 'initiator_on_get_model', + 'label' => 'COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_GET_MODEL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Database', + ], + 'initiator_on_save_model' => [ + 'name' => 'initiator_on_save_model', + 'label' => 'COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_SAVE_MODEL_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Database', + ], + 'xml' => [ + 'name' => 'xml', + 'label' => '', + 'type' => 'hidden', + 'title' => false, + 'list' => 'fields', + 'store' => 'json', + 'tab_name' => 'Type Info', + ], + 'datalenght' => [ + 'name' => 'datalenght', + 'label' => 'COM_COMPONENTBUILDER_FIELD_DATALENGHT_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'css_views' => [ + 'name' => 'css_views', + 'label' => 'COM_COMPONENTBUILDER_FIELD_CSS_VIEWS_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Scripts', + ], + 'css_view' => [ + 'name' => 'css_view', + 'label' => 'COM_COMPONENTBUILDER_FIELD_CSS_VIEW_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Scripts', + ], + 'datadefault_other' => [ + 'name' => 'datadefault_other', + 'label' => 'COM_COMPONENTBUILDER_FIELD_DATADEFAULT_OTHER_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'datadefault' => [ + 'name' => 'datadefault', + 'label' => 'COM_COMPONENTBUILDER_FIELD_DATADEFAULT_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'datalenght_other' => [ + 'name' => 'datalenght_other', + 'label' => 'COM_COMPONENTBUILDER_FIELD_DATALENGHT_OTHER_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Database', + ], + 'on_get_model_field' => [ + 'name' => 'on_get_model_field', + 'label' => 'COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Database', + ], + 'javascript_view_footer' => [ + 'name' => 'javascript_view_footer', + 'label' => 'COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEW_FOOTER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Scripts', + ], + 'javascript_views_footer' => [ + 'name' => 'javascript_views_footer', + 'label' => 'COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEWS_FOOTER_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'fields', + 'store' => 'base64', + 'tab_name' => 'Scripts', + ], + 'add_css_view' => [ + 'name' => 'add_css_view', + 'label' => 'COM_COMPONENTBUILDER_FIELD_ADD_CSS_VIEW_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Scripts', + ], + 'add_css_views' => [ + 'name' => 'add_css_views', + 'label' => 'COM_COMPONENTBUILDER_FIELD_ADD_CSS_VIEWS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Scripts', + ], + 'add_javascript_view_footer' => [ + 'name' => 'add_javascript_view_footer', + 'label' => 'COM_COMPONENTBUILDER_FIELD_ADD_JAVASCRIPT_VIEW_FOOTER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Scripts', + ], + 'add_javascript_views_footer' => [ + 'name' => 'add_javascript_views_footer', + 'label' => 'COM_COMPONENTBUILDER_FIELD_ADD_JAVASCRIPT_VIEWS_FOOTER_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'Scripts', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_FIELD_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fields', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + ], + 'fieldtype' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'store' => [ + 'name' => 'store', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_STORE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'null_switch' => [ + 'name' => 'null_switch', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_NULL_SWITCH_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'indexes' => [ + 'name' => 'indexes', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_INDEXES_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'datadefault_other' => [ + 'name' => 'datadefault_other', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_DATADEFAULT_OTHER_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'datadefault' => [ + 'name' => 'datadefault', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_DATADEFAULT_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'short_description' => [ + 'name' => 'short_description', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_SHORT_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'datatype' => [ + 'name' => 'datatype', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_DATATYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'has_defaults' => [ + 'name' => 'has_defaults', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_HAS_DEFAULTS_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'properties' => [ + 'name' => 'properties', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_PROPERTIES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'datalenght' => [ + 'name' => 'datalenght', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_DATALENGHT_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'datalenght_other' => [ + 'name' => 'datalenght_other', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_DATALENGHT_OTHER_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Database (defaults)', + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_GUID_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'publishing', + ], + 'catid' => [ + 'name' => 'catid', + 'label' => 'COM_COMPONENTBUILDER_FIELDTYPE_CATID_LABEL', + 'type' => 'category', + 'title' => false, + 'list' => 'fieldtypes', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'language_translation' => [ + 'source' => [ + 'name' => 'source', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SOURCE_LABEL', + 'type' => 'textarea', + 'title' => true, + 'list' => 'language_translations', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'plugins' => [ + 'name' => 'plugins', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_PLUGINS_LABEL', + 'type' => 'joomlaplugins', + 'title' => false, + 'list' => 'language_translations', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'modules' => [ + 'name' => 'modules', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_MODULES_LABEL', + 'type' => 'joomlamodules', + 'title' => false, + 'list' => 'language_translations', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'components' => [ + 'name' => 'components', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_COMPONENTS_LABEL', + 'type' => 'joomlacomponents', + 'title' => false, + 'list' => 'language_translations', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'translation' => [ + 'name' => 'translation', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_TRANSLATION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'language_translations', + 'store' => 'json', + 'tab_name' => 'Details', + ], + ], + 'language' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'languages', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'langtag' => [ + 'name' => 'langtag', + 'label' => 'COM_COMPONENTBUILDER_LANGUAGE_LANGTAG_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'languages', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'server' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_SERVER_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'servers', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'protocol' => [ + 'name' => 'protocol', + 'label' => 'COM_COMPONENTBUILDER_SERVER_PROTOCOL_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'servers', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'signature' => [ + 'name' => 'signature', + 'label' => 'COM_COMPONENTBUILDER_SERVER_SIGNATURE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'private_key' => [ + 'name' => 'private_key', + 'label' => 'COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'secret' => [ + 'name' => 'secret', + 'label' => 'COM_COMPONENTBUILDER_SERVER_SECRET_LABEL', + 'type' => 'password', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'password' => [ + 'name' => 'password', + 'label' => 'COM_COMPONENTBUILDER_SERVER_PASSWORD_LABEL', + 'type' => 'password', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'private' => [ + 'name' => 'private', + 'label' => 'COM_COMPONENTBUILDER_SERVER_PRIVATE_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'authentication' => [ + 'name' => 'authentication', + 'label' => 'COM_COMPONENTBUILDER_SERVER_AUTHENTICATION_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'servers', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'path' => [ + 'name' => 'path', + 'label' => 'COM_COMPONENTBUILDER_SERVER_PATH_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'port' => [ + 'name' => 'port', + 'label' => 'COM_COMPONENTBUILDER_SERVER_PORT_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'host' => [ + 'name' => 'host', + 'label' => 'COM_COMPONENTBUILDER_SERVER_HOST_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + 'username' => [ + 'name' => 'username', + 'label' => 'COM_COMPONENTBUILDER_SERVER_USERNAME_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'servers', + 'store' => 'basic_encryption', + 'tab_name' => 'Details', + ], + ], + 'help_document' => [ + 'title' => [ + 'name' => 'title', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_TITLE_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'type' => [ + 'name' => 'type', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'groups' => [ + 'name' => 'groups', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_GROUPS_LABEL', + 'type' => 'usergroup', + 'title' => false, + 'list' => 'help_documents', + 'store' => 'json', + 'tab_name' => 'Details', + ], + 'location' => [ + 'name' => 'location', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_LOCATION_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'admin_view' => [ + 'name' => 'admin_view', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_ADMIN_VIEW_LABEL', + 'type' => 'adminviewfolderlist', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'site_view' => [ + 'name' => 'site_view', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_SITE_VIEW_LABEL', + 'type' => 'siteviewfolderlist', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'not_required' => [ + 'name' => 'not_required', + 'label' => '', + 'type' => 'hidden', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'content' => [ + 'name' => 'content', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_CONTENT_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'article' => [ + 'name' => 'article', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_ARTICLE_LABEL', + 'type' => 'articles', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'url' => [ + 'name' => 'url', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_URL_LABEL', + 'type' => 'url', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'target' => [ + 'name' => 'target', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_TARGET_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'alias' => [ + 'name' => 'alias', + 'label' => 'COM_COMPONENTBUILDER_HELP_DOCUMENT_ALIAS_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'help_documents', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'admin_fields' => [ + 'admin_view' => [ + 'name' => 'admin_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_FIELDS_ADMIN_VIEW_LABEL', + 'type' => 'adminviewsreadonly', + 'title' => true, + 'list' => 'admins_fields', + 'store' => NULL, + 'tab_name' => 'Fields', + ], + 'addfields' => [ + 'name' => 'addfields', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_FIELDS_ADDFIELDS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admins_fields', + 'store' => 'json', + 'tab_name' => 'Fields', + ], + ], + 'admin_fields_conditions' => [ + 'admin_view' => [ + 'name' => 'admin_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_FIELDS_CONDITIONS_ADMIN_VIEW_LABEL', + 'type' => 'adminviewsreadonly', + 'title' => true, + 'list' => 'admins_fields_conditions', + 'store' => NULL, + 'tab_name' => 'Conditions', + ], + 'addconditions' => [ + 'name' => 'addconditions', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_FIELDS_CONDITIONS_ADDCONDITIONS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admins_fields_conditions', + 'store' => 'json', + 'tab_name' => 'Conditions', + ], + ], + 'admin_fields_relations' => [ + 'admin_view' => [ + 'name' => 'admin_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_ADMIN_VIEW_LABEL', + 'type' => 'adminviewsreadonly', + 'title' => true, + 'list' => 'admins_fields_relations', + 'store' => NULL, + 'tab_name' => 'Relations', + ], + 'addrelations' => [ + 'name' => 'addrelations', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_FIELDS_RELATIONS_ADDRELATIONS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admins_fields_relations', + 'store' => 'json', + 'tab_name' => 'Relations', + ], + ], + 'admin_custom_tabs' => [ + 'admin_view' => [ + 'name' => 'admin_view', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_CUSTOM_TABS_ADMIN_VIEW_LABEL', + 'type' => 'adminviewsreadonly', + 'title' => true, + 'list' => 'admins_custom_tabs', + 'store' => NULL, + 'tab_name' => 'Tabs', + ], + 'tabs' => [ + 'name' => 'tabs', + 'label' => 'COM_COMPONENTBUILDER_ADMIN_CUSTOM_TABS_TABS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'admins_custom_tabs', + 'store' => 'json', + 'tab_name' => 'Tabs', + ], + ], + 'component_admin_views' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_ADMIN_VIEWS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_admin_views', + 'store' => NULL, + 'tab_name' => 'Views', + ], + 'addadmin_views' => [ + 'name' => 'addadmin_views', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_ADMIN_VIEWS_ADDADMIN_VIEWS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_admin_views', + 'store' => 'json', + 'tab_name' => 'Views', + ], + ], + 'component_site_views' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_SITE_VIEWS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_site_views', + 'store' => NULL, + 'tab_name' => 'Views', + ], + 'addsite_views' => [ + 'name' => 'addsite_views', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_SITE_VIEWS_ADDSITE_VIEWS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_site_views', + 'store' => 'json', + 'tab_name' => 'Views', + ], + ], + 'component_custom_admin_views' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_VIEWS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_custom_admin_views', + 'store' => NULL, + 'tab_name' => 'Views', + ], + 'addcustom_admin_views' => [ + 'name' => 'addcustom_admin_views', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_VIEWS_ADDCUSTOM_ADMIN_VIEWS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_custom_admin_views', + 'store' => 'json', + 'tab_name' => 'Views', + ], + ], + 'component_updates' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_UPDATES_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_updates', + 'store' => NULL, + 'tab_name' => 'Updates', + ], + 'version_update' => [ + 'name' => 'version_update', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_UPDATES_VERSION_UPDATE_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_updates', + 'store' => 'json', + 'tab_name' => 'Updates', + ], + ], + 'component_mysql_tweaks' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_MYSQL_TWEAKS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_mysql_tweaks', + 'store' => NULL, + 'tab_name' => 'Mysql Tweaks', + ], + 'sql_tweak' => [ + 'name' => 'sql_tweak', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_MYSQL_TWEAKS_SQL_TWEAK_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_mysql_tweaks', + 'store' => 'json', + 'tab_name' => 'Mysql Tweaks', + ], + ], + 'component_custom_admin_menus' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_custom_admin_menus', + 'store' => NULL, + 'tab_name' => 'Menus', + ], + 'addcustommenus' => [ + 'name' => 'addcustommenus', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_CUSTOM_ADMIN_MENUS_ADDCUSTOMMENUS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_custom_admin_menus', + 'store' => 'json', + 'tab_name' => 'Menus', + ], + ], + 'component_config' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_CONFIG_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_config', + 'store' => NULL, + 'tab_name' => 'Options', + ], + 'addconfig' => [ + 'name' => 'addconfig', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_CONFIG_ADDCONFIG_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_config', + 'store' => 'json', + 'tab_name' => 'Options', + ], + ], + 'component_dashboard' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_dashboard', + 'store' => NULL, + 'tab_name' => 'Dashboard', + ], + 'dashboard_tab' => [ + 'name' => 'dashboard_tab', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_DASHBOARD_TAB_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_dashboard', + 'store' => 'json', + 'tab_name' => 'Dashboard', + ], + 'php_dashboard_methods' => [ + 'name' => 'php_dashboard_methods', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_DASHBOARD_PHP_DASHBOARD_METHODS_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'components_dashboard', + 'store' => 'base64', + 'tab_name' => 'Dashboard', + ], + ], + 'component_files_folders' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_files_folders', + 'store' => NULL, + 'tab_name' => 'Basic', + ], + 'addfoldersfullpath' => [ + 'name' => 'addfoldersfullpath', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_ADDFOLDERSFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_files_folders', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfilesfullpath' => [ + 'name' => 'addfilesfullpath', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_ADDFILESFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_files_folders', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfolders' => [ + 'name' => 'addfolders', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_ADDFOLDERS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_files_folders', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addfiles' => [ + 'name' => 'addfiles', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_ADDFILES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_files_folders', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + ], + 'component_placeholders' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_placeholders', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'addplaceholders' => [ + 'name' => 'addplaceholders', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_PLACEHOLDERS_ADDPLACEHOLDERS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_placeholders', + 'store' => 'json', + 'tab_name' => 'Details', + ], + ], + 'component_plugins' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_PLUGINS_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_plugins', + 'store' => NULL, + 'tab_name' => 'Plugins', + ], + 'addjoomla_plugins' => [ + 'name' => 'addjoomla_plugins', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_PLUGINS_ADDJOOMLA_PLUGINS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_plugins', + 'store' => 'json', + 'tab_name' => 'Plugins', + ], + ], + 'component_modules' => [ + 'joomla_component' => [ + 'name' => 'joomla_component', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_MODULES_JOOMLA_COMPONENT_LABEL', + 'type' => 'joomlacomponents', + 'title' => true, + 'list' => 'components_modules', + 'store' => NULL, + 'tab_name' => 'Modules', + ], + 'addjoomla_modules' => [ + 'name' => 'addjoomla_modules', + 'label' => 'COM_COMPONENTBUILDER_COMPONENT_MODULES_ADDJOOMLA_MODULES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'components_modules', + 'store' => 'json', + 'tab_name' => 'Modules', + ], + ], + 'snippet_type' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_TYPE_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'snippet_types', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_SNIPPET_TYPE_DESCRIPTION_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'snippet_types', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'library_config' => [ + 'library' => [ + 'name' => 'library', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_CONFIG_LIBRARY_LABEL', + 'type' => 'libraryreadonly', + 'title' => true, + 'list' => 'libraries_config', + 'store' => NULL, + 'tab_name' => 'Tweaks', + ], + 'addconfig' => [ + 'name' => 'addconfig', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_CONFIG_ADDCONFIG_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries_config', + 'store' => 'json', + 'tab_name' => 'Tweaks', + ], + ], + 'library_files_folders_urls' => [ + 'library' => [ + 'name' => 'library', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_LIBRARY_LABEL', + 'type' => 'libraryreadonly', + 'title' => true, + 'list' => 'libraries_files_folders_urls', + 'store' => NULL, + 'tab_name' => 'Basic', + ], + 'addfoldersfullpath' => [ + 'name' => 'addfoldersfullpath', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_ADDFOLDERSFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfilesfullpath' => [ + 'name' => 'addfilesfullpath', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_ADDFILESFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfolders' => [ + 'name' => 'addfolders', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_ADDFOLDERS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addfiles' => [ + 'name' => 'addfiles', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_ADDFILES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addurls' => [ + 'name' => 'addurls', + 'label' => 'COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_ADDURLS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'libraries_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + ], + 'class_extends' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_CLASS_EXTENDS_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'class_extendings', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'extension_type' => [ + 'name' => 'extension_type', + 'label' => 'COM_COMPONENTBUILDER_CLASS_EXTENDS_EXTENSION_TYPE_LABEL', + 'type' => 'list', + 'title' => false, + 'list' => 'class_extendings', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'head' => [ + 'name' => 'head', + 'label' => 'COM_COMPONENTBUILDER_CLASS_EXTENDS_HEAD_LABEL', + 'type' => 'editor', + 'title' => false, + 'list' => 'class_extendings', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + 'comment' => [ + 'name' => 'comment', + 'label' => 'COM_COMPONENTBUILDER_CLASS_EXTENDS_COMMENT_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'class_extendings', + 'store' => 'base64', + 'tab_name' => 'Details', + ], + ], + 'joomla_module_updates' => [ + 'joomla_module' => [ + 'name' => 'joomla_module', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_UPDATES_JOOMLA_MODULE_LABEL', + 'type' => 'joomlamodules', + 'title' => true, + 'list' => 'joomla_modules_updates', + 'store' => NULL, + 'tab_name' => 'Updates', + ], + 'version_update' => [ + 'name' => 'version_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_UPDATES_VERSION_UPDATE_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules_updates', + 'store' => 'json', + 'tab_name' => 'Updates', + ], + ], + 'joomla_module_files_folders_urls' => [ + 'joomla_module' => [ + 'name' => 'joomla_module', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_JOOMLA_MODULE_LABEL', + 'type' => 'joomlamodules', + 'title' => true, + 'list' => 'joomla_modules_files_folders_urls', + 'store' => NULL, + 'tab_name' => 'Basic', + ], + 'addfoldersfullpath' => [ + 'name' => 'addfoldersfullpath', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_ADDFOLDERSFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfilesfullpath' => [ + 'name' => 'addfilesfullpath', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_ADDFILESFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfolders' => [ + 'name' => 'addfolders', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_ADDFOLDERS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addfiles' => [ + 'name' => 'addfiles', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_ADDFILES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addurls' => [ + 'name' => 'addurls', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_ADDURLS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_modules_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + ], + 'joomla_plugin_group' => [ + 'name' => [ + 'name' => 'name', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUP_NAME_LABEL', + 'type' => 'text', + 'title' => true, + 'list' => 'joomla_plugin_groups', + 'store' => NULL, + 'tab_name' => 'Details', + ], + 'class_extends' => [ + 'name' => 'class_extends', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_GROUP_CLASS_EXTENDS_LABEL', + 'type' => 'classextends', + 'title' => false, + 'list' => 'joomla_plugin_groups', + 'store' => NULL, + 'tab_name' => 'Details', + ], + ], + 'joomla_plugin_updates' => [ + 'joomla_plugin' => [ + 'name' => 'joomla_plugin', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_UPDATES_JOOMLA_PLUGIN_LABEL', + 'type' => 'joomlaplugins', + 'title' => true, + 'list' => 'joomla_plugins_updates', + 'store' => NULL, + 'tab_name' => 'Updates', + ], + 'version_update' => [ + 'name' => 'version_update', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_UPDATES_VERSION_UPDATE_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins_updates', + 'store' => 'json', + 'tab_name' => 'Updates', + ], + ], + 'joomla_plugin_files_folders_urls' => [ + 'joomla_plugin' => [ + 'name' => 'joomla_plugin', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_JOOMLA_PLUGIN_LABEL', + 'type' => 'joomlaplugins', + 'title' => true, + 'list' => 'joomla_plugins_files_folders_urls', + 'store' => NULL, + 'tab_name' => 'Basic', + ], + 'addfoldersfullpath' => [ + 'name' => 'addfoldersfullpath', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_ADDFOLDERSFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfilesfullpath' => [ + 'name' => 'addfilesfullpath', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_ADDFILESFULLPATH_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Advance', + ], + 'addfolders' => [ + 'name' => 'addfolders', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_ADDFOLDERS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addfiles' => [ + 'name' => 'addfiles', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_ADDFILES_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + 'addurls' => [ + 'name' => 'addurls', + 'label' => 'COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_ADDURLS_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'joomla_plugins_files_folders_urls', + 'store' => 'json', + 'tab_name' => 'Basic', + ], + ], + ]; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/Constantpaths.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/Constantpaths.php new file mode 100644 index 000000000..3773d873d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/Constantpaths.php @@ -0,0 +1,93 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Utilities; + + +/** + * Utilities Constant Paths + * + * @since 3.2.0 + */ +class Constantpaths +{ + /** + * The array of constant paths + * + * JPATH_SITE is meant to represent the root path of the JSite application, + * just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application. + * + * JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application: + * + * JPATH_BASE == JPATH_ADMINISTRATOR + * + * If you are in the site application: + * + * JPATH_BASE == JPATH_SITE + * + * If you are in the installation application: + * + * JPATH_BASE == JPATH_INSTALLATION. + * + * JPATH_ROOT is the root path for the Joomla install and does not depend upon any application. + * + * @var array + * @since 3.2.0 + */ + protected array $paths = [ + // The path to the administrator folder. + 'JPATH_ADMINISTRATOR' => JPATH_ADMINISTRATOR, + // The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend. + 'JPATH_BASE' => JPATH_BASE, + // The path to the cache folder. + 'JPATH_CACHE' => JPATH_CACHE, + // The path to the administration folder of the current component being executed. + 'JPATH_COMPONENT_ADMINISTRATOR' => JPATH_COMPONENT_ADMINISTRATOR, + // The path to the site folder of the current component being executed. + 'JPATH_COMPONENT_SITE' => JPATH_COMPONENT_SITE, + // The path to the current component being executed. + 'JPATH_COMPONENT' => JPATH_COMPONENT, + // The path to folder containing the configuration.php file. + 'JPATH_CONFIGURATION' => JPATH_CONFIGURATION, + // The path to the installation folder. + 'JPATH_INSTALLATION' => JPATH_INSTALLATION, + // The path to the libraries folder. + 'JPATH_LIBRARIES' => JPATH_LIBRARIES, + // The path to the plugins folder. + 'JPATH_PLUGINS' => JPATH_PLUGINS, + // The path to the installed Joomla! site. + 'JPATH_ROOT' => JPATH_ROOT, + // The path to the installed Joomla! site. + 'JPATH_SITE' => JPATH_SITE, + // The path to the templates folder. + 'JPATH_THEMES' => JPATH_THEMES + ]; + + /** + * get array of constant paths or just one constant path + * + * @param string|null $path The path to get + * + * @return array|string|null + * @since 3.2.0 + */ + public function get(?string $path = null) + { + if (is_null($path)) + { + return $this->paths; + } + + return $this->paths[$path] ?? null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FilterHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FilterHelper.php new file mode 100644 index 000000000..86dec4d31 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FilterHelper.php @@ -0,0 +1,814 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Componentbuilder\Utilities; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Filter Helper + * + * @since 3.2.0 + */ +abstract class FilterHelper +{ + /** + * get extensions grouped list xml + * + * @return string The XML string of Extentions + * @since 3.2.0 + */ + public static function extensions(): string + { + // the extension types + $extensions = array( + 'joomla_component' => 'COM_COMPONENTBUILDER_COMPONENT', + 'joomla_module' => 'COM_COMPONENTBUILDER_MODULE', + 'joomla_plugin' => 'COM_COMPONENTBUILDER_PLUGIN' + ); + + // get the extension values + foreach ($extensions as $extension => $label) + { + ${$extension} = self::names($extension); + } + + $xml = new \DOMDocument(); + $xml->formatOutput = true; + + $root = $xml->createElement('field'); + $root->setAttributeNode(new \DOMAttr('name', 'extension')); + $root->setAttributeNode(new \DOMAttr('type', 'groupedlist')); + $root->setAttributeNode(new \DOMAttr('onchange', 'this.form.submit();')); + + $root + ->appendChild($xml->createElement('option', '- ' . Text::_('COM_COMPONENTBUILDER_SELECT_EXTENSION') . ' -')) + ->setAttributeNode(new \DOMAttr('value', '')); + + foreach ($extensions as $extension => $label) + { + $extension_node = $xml->createElement('group'); + $extension_node->setAttributeNode(new \DOMAttr('label', $label)); + if (!ArrayHelper::check(${$extension})) + { + $extension_node + ->appendChild($xml->createElement('option', '- ' . Text::_('COM_COMPONENTBUILDER_NONE') . ' -')) + ->setAttributeNode(new \DOMAttr('disabled', 'true')); + } + else + { + foreach (${$extension} as $id => $element) + { + $extension_node + ->appendChild($xml->createElement('option', $element)) + ->setAttributeNode(new \DOMAttr('value', $extension . '__' . $id)); + } + } + $root->appendChild($extension_node); + } + $xml->appendChild($root); + + return $xml->saveXML(); + } + + /** + * Get by type the ids and system names + * + * @param string $type The table name to get system names for + * @param string|null $limiter The to limit by limiter table + * + * @return array|null The array of system name and IDs + * @since 3.2.0 + */ + public static function names(string $type, ?string $limiter = null): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + $query + ->select($db->quoteName(array('id', 'system_name'))) + ->from($db->quoteName('#__componentbuilder_' . $type)) + ->where($db->quoteName('published') . ' >= 1') + ->order($db->quoteName('modified') . ' desc') + ->order($db->quoteName('created') . ' desc'); + + // check if we have a limiter for admin views + if ($type === 'admin_view' && $limiter) + { + // first get all views + $admin_view_ids = array(); + + // if this is a plugin or a module, then no views + if (strpos($limiter, 'joomla_component') !== false) + { + $component = (int) str_replace('joomla_component__', '', $limiter); + // get the views of this component + if ($add_views = GetHelper::var('component_admin_views', (int) $component, 'joomla_component', 'addadmin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['adminview'])) + { + $admin_view_ids[(int) $add_view['adminview']] = (int) $add_view['adminview']; + } + } + } + } + } + } + // now check if we still have admin views + if (ArrayHelper::check($admin_view_ids)) + { + $query->where($db->quoteName('id') . ' IN (' . implode(',', $admin_view_ids) . ')'); + } + else + { + return null; + } + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadAssocList('id', 'system_name'); + } + + return null; + } + + /** + * get any area linked IDs + * + * @param int $id The target ID + * @param string $method The target method + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function linked(int $id, string $method): ?array + { + // check if method exist + if (method_exists(__CLASS__, $method)) + { + return self::{$method}($id); + } + + return null; + } + + /** + * get the substrings of the namespace until the last "\" or "." + * + * @return array|null The result substrings + * @since 3.2.0 + **/ + public static function namespaces(): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select( + 'DISTINCT REPLACE(SUBSTRING(' + . $db->quoteName('namespace') + . ', 1, LENGTH(' + . $db->quoteName('namespace') + . ') - LEAST(' + . 'IF(LOCATE(' + . $db->quote('\\') + . ', ' . $db->quoteName('namespace') + . ') > 0, LOCATE(' + . $db->quote('\\') + . ', REVERSE(' + . $db->quoteName('namespace') + . ')), 0), ' + . 'IF(LOCATE(' + . $db->quote('.') + . ', ' . $db->quoteName('namespace') + . ') > 0, LOCATE(' + . $db->quote('.') + . ', REVERSE(' + . $db->quoteName('namespace') + . ')), 0))), ".", "\\\") AS trimmed_namespace' + ) + ->from($db->quoteName('#__componentbuilder_power')) + ->where($db->quoteName('published') . ' = 1') + ->order('LENGTH(trimmed_namespace) ASC, trimmed_namespace ASC'); + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadAssocList('trimmed_namespace', 'trimmed_namespace'); + } + + return null; + } + + /** + * get get IDs of powers matching namespaces + * + * @param string $namespace The target namespace + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function namegroup(string $namespace): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('id'))) + ->from($db->quoteName('#__componentbuilder_power')) + ->where($db->quoteName('published') . ' = 1'); + + // we get only those that match the owner and repo (smaller set) + $paths = explode('\\', $namespace); + foreach ($paths as $path) + { + $query->where($db->quoteName('namespace') . ' REGEXP ' . $db->quote($path)); + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadColumn(); + } + + return null; + } + + /** + * get translation extension ids + * + * @param int $extension The target ID + * @param string $type The target method + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function translation(int $extension, string $type): ?array + { + // only allow these columns (extension types) + $columns = array( + 'joomla_component' => 'components', + 'joomla_module' => 'modules', + 'joomla_plugin' => 'plugins' + ); + + // check if the column name is correct + if (isset($columns[$type])) + { + $column = $columns[$type]; + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('id', $column))) + ->from($db->quoteName('#__componentbuilder_language_translation')) + ->where($db->quoteName($column) . ' != ' . $db->quote('')); + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + $results = $db->loadAssocList(); + $matches = []; + foreach ($results as $k => $v) + { + $value = json_decode($v[$column], true); + if (in_array($extension, $value)) + { + $matches[$v['id']] = $v['id']; + } + } + + // Checks that we found matches + if (ArrayHelper::check($matches)) + { + return array_values($matches); + } + } + } + + return null; + } + + /** + * get translation ids + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function translations($language, $translated = true): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + $query + ->select($db->quoteName('id')) + ->from($db->quoteName('#__componentbuilder_language_translation')); + + // Build the where condition + if ($translated === true) // Translated + { + if ($language === 'all') + { + if (($languages = self::languages()) !== null) + { + $wheres = []; + foreach ($languages as $k => $v) + { + $wheres[] = $db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $k . '%'); + } + $query->where($wheres); + } + } + else + { + $query->where($db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $language . '%')); + } + } + else // Not translated + { + if ($language === 'none') + { + $query->where( + array( + $db->quoteName('translation') . ' = ' . $db->quote(''), + $db->quoteName('translation') . ' = ' . $db->quote('[]'), + $db->quoteName('translation') . ' = ' . $db->quote('{}') + ), 'OR' + ); + } + else + { + $query->where($db->quoteName('translation') . ' NOT LIKE ' . $db->quote('%' . $language . '%')); + } + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return array_unique($db->loadColumn()); + } + + return null; + } + + /** + * get available languages + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function languages(): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('langtag', 'name'))) + ->from($db->quoteName('#__componentbuilder_language')) + ->where($db->quoteName('published') . ' = 1') + ->order($db->quoteName('name') . ' desc'); + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadAssocList('langtag', 'name'); + } + + return null; + } + + /** + * get get IDs of powers link to this path + * + * @param string $path The target PATH + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function paths(string $path): ?array + { + // get all this power ids + $ids = []; + + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('id', 'approved_paths'))) + ->from($db->quoteName('#__componentbuilder_power')) + ->where($db->quoteName('published') . ' = 1'); + + // we get only those that match the owner and repo (smaller set) + if (($pos = strpos($path, '/')) !== false) + { + $owner = substr($path, 0, $pos); + $repo = substr($path, $pos + 1); + $query + ->where($db->quoteName('approved_paths') . ' REGEXP ' . $db->quote($owner)) + ->where($db->quoteName('approved_paths') . ' REGEXP ' . $db->quote($repo)); + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + $result = $db->loadAssocList('id', 'approved_paths'); + foreach ($result as $id => $paths) + { + if (JsonHelper::check($paths)) + { + $paths = json_decode($paths, true); + if (ArrayHelper::check($paths) && in_array($path, $paths, true)) + { + $ids[$id] = $id; + } + } + } + + if (ArrayHelper::check($ids)) + { + return $ids; + } + } + + return null; + } + + /** + * Get a component admin views IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component_admin_views(int $id): ?array + { + // get all this components views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['adminview'])) + { + $admin_view_ids[(int) $add_view['adminview']] = (int) $add_view['adminview']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($admin_view_ids)) + { + return array_values($admin_view_ids); + } + + return null; + } + + /** + * get a component custom admin views IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component_custom_admin_views($id): ?array + { + // get all this components views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_custom_admin_views', (int) $id, 'joomla_component', 'addcustom_admin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['customadminview'])) + { + $admin_view_ids[(int) $add_view['customadminview']] = (int) $add_view['customadminview']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($admin_view_ids)) + { + return array_values($admin_view_ids); + } + + return null; + } + + /** + * get a component site views IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component_site_views($id): ?array + { + // get all this components views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_site_views', (int) $id, 'joomla_component', 'addsite_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['siteview'])) + { + $admin_view_ids[(int) $add_view['siteview']] = (int) $add_view['siteview']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($admin_view_ids)) + { + return array_values($admin_view_ids); + } + + return null; + } + + /** + * get a component fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component($id): ?array + { + // we start the field array + $field_ids = []; + + // first get all views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['adminview'])) + { + $admin_view_ids[(int) $add_view['adminview']] = (int) $add_view['adminview']; + } + } + } + } + } + + // check that we have views + if (ArrayHelper::check($admin_view_ids)) + { + foreach ($admin_view_ids as $admin_view) + { + // get all the fields linked to the admin view + if ($add_fields = GetHelper::var('admin_fields', (int) $admin_view, 'admin_view', 'addfields')) + { + if (JsonHelper::check($add_fields)) + { + $add_fields = json_decode($add_fields, true); + if (ArrayHelper::check($add_fields)) + { + foreach($add_fields as $add_field) + { + if (isset($add_field['field'])) + { + $field_ids[(int) $add_field['field']] = (int) $add_field['field']; + } + } + } + } + } + } + } + + // get config values + if ($add_config = GetHelper::var('component_config', (int) $id, 'joomla_component', 'addconfig')) + { + if (JsonHelper::check($add_config)) + { + $add_config = json_decode($add_config, true); + if (ArrayHelper::check($add_config)) + { + foreach($add_config as $add_conf) + { + if (isset($add_conf['field'])) + { + $field_ids[(int) $add_conf['field']] = (int) $add_conf['field']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + + /** + * get a module fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_module($id): ?array + { + // we start the field array + $field_ids = []; + + if ($fields = GetHelper::var('joomla_module', (int) $id, 'id', 'fields')) + { + if (JsonHelper::check($fields)) + { + $fields = json_decode($fields, true); + if (ArrayHelper::check($fields)) + { + foreach($fields as $form) + { + if (isset($form['fields']) && ArrayHelper::check($form['fields'])) + { + foreach ($form['fields'] as $field) + { + if (isset($field['field'])) + { + $field_ids[(int) $field['field']] = (int) $field['field']; + } + } + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + + /** + * get a plugin fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_plugin($id): ?array + { + // we start the field array + $field_ids = []; + + if ($fields = GetHelper::var('joomla_plugin', (int) $id, 'id', 'fields')) + { + if (JsonHelper::check($fields)) + { + $fields = json_decode($fields, true); + if (ArrayHelper::check($fields)) + { + foreach($fields as $form) + { + if (isset($form['fields']) && ArrayHelper::check($form['fields'])) + { + foreach ($form['fields'] as $field) + { + if (isset($field['field'])) + { + $field_ids[(int) $field['field']] = (int) $field['field']; + } + } + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + + /** + * get an admin view fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function admin_view($id): ?array + { + // we start the field array + $field_ids = []; + + // get all the fields linked to the admin view + if ($add_fields = GetHelper::var('admin_fields', (int) $id, 'admin_view', 'addfields')) + { + if (JsonHelper::check($add_fields)) + { + $add_fields = json_decode($add_fields, true); + if (ArrayHelper::check($add_fields)) + { + foreach($add_fields as $add_field) + { + if (isset($add_field['field'])) + { + $field_ids[(int) $add_field['field']] = (int) $add_field['field']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Database/Insert.php new file mode 100644 index 000000000..bf7611ae4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Database/Insert.php @@ -0,0 +1,290 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Database; + + +use Joomla\CMS\Date\Date; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Interfaces\InsertInterface; +use VDM\Joomla\Abstraction\Database; + + +/** + * Database Insert Class + * + * @since 3.2.0 + */ +final class Insert extends Database implements InsertInterface +{ + /** + * Switch to set the defaults + * + * @var bool + * @since 1.2.0 + **/ + protected bool $defaults = true; + + /** + * Switch to prevent/allow defaults from being added. + * + * @param bool $trigger toggle the defaults + * + * @return void + * @since 3.2.0 + **/ + public function defaults(bool $trigger = true) + { + $this->defaults = $trigger; + } + + /** + * Insert rows to the database (with remapping and filtering columns option) + * + * @param array $data Dataset to store in database [array of arrays (key => value)] + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $table, array $columns = []): bool + { + if (!ArrayHelper::check($data)) + { + return false; + } + + if ($columns === []) + { + $columns = $this->getArrayColumns($data); + } + + return ($columns === []) ? false : $this->insert($data, $table, $columns, true); + } + + /** + * Insert items to the database (with remapping and filtering columns option) + * + * @param array $data Data to store in database (array of objects) + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $table, array $columns = []): bool + { + if (!ArrayHelper::check($data)) + { + return false; + } + + if ($columns === []) + { + $columns = $this->getObjectsColumns($data); + } + + return ($columns === []) ? false : $this->insert($data, $table, $columns, false); + } + + /** + * Insert row to the database + * + * @param array $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added + * + * @return bool + * @since 3.2.0 + **/ + public function row(array $data, string $table): bool + { + return $this->rows([$data], $table); + } + + /** + * Insert item to the database + * + * @param object $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $table): bool + { + return $this->items([$data], $table); + } + + /** + * Get columns from data array + * + * @param array $data Data array + * + * @return array + * @since 3.2.0 + **/ + protected function getArrayColumns(array &$data): array + { + $row = array_values($data)[0]; + + if (!ArrayHelper::check($row)) + { + return []; + } + + $columns = array_keys($row); + + return array_combine($columns, $columns); + } + + /** + * Get columns from data objects + * + * @param array $data Data objects + * + * @return array + * @since 3.2.0 + **/ + protected function getObjectsColumns(array &$data): array + { + $row = array_values($data)[0]; + + if (!is_object($row)) + { + return []; + } + + $columns = get_object_vars($row); + + return array_combine(array_keys($columns), array_keys($columns)); + } + + /** + * Insert data into the database + * + * @param array $data Data to store in database + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * @param bool $isArray Whether the data is an array of arrays or an array of objects + * + * @return bool + * @since 3.2.0 + **/ + protected function insert(array &$data, string $table, array $columns, bool $isArray): bool + { + // set joomla default columns + $add_created = false; + $add_version = false; + $add_published = false; + + // check if we should load the defaults + if ($this->defaults) + { + // get the date + $date = (new Date())->toSql(); + + if (!isset($columns['created'])) + { + $columns['created'] = ' (o_O) '; + $add_created = true; + } + + if (!isset($columns['version'])) + { + $columns['version'] = ' (o_O) '; + $add_version = true; + } + + if (!isset($columns['published'])) + { + $columns['published'] = ' (o_O) '; + $add_published = true; + } + // the (o_O) prevents an empty value from being loaded + } + + // get a query object + $query = $this->db->getQuery(true); + + // set the query targets + $query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns))); + + // limiting factor on the amount of rows to insert before we reset the query + $limit = 300; + + // set the insert values + foreach ($data as $nr => $value) + { + // check the limit + if ($limit <= 1) + { + // execute and reset the query + $this->db->setQuery($query); + $this->db->execute(); + + // reset limit + $limit = 300; + + // get a query object + $query = $this->db->getQuery(true); + + // set the query targets + $query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns))); + } + + $row = []; + foreach ($columns as $column => $key) + { + if (' (o_O) ' !== $key) + { + $row[] = ($isArray && isset($value[$key])) ? $this->quote($value[$key]) + : ((!$isArray && isset($value->{$key})) ? $this->quote($value->{$key}) : ''); + } + } + + // set joomla default columns + if ($add_created) + { + $row[] = $this->db->quote($date); + } + + if ($add_version) + { + $row[] = 1; + } + + if ($add_published) + { + $row[] = 1; + } + + // add to query + $query->values(implode(',', $row)); + + // decrement the limiter + $limit--; + + // clear the data from memory + unset($data[$nr]); + } + + // execute the final query + $this->db->setQuery($query); + $this->db->execute(); + + // always reset the default switch + $this->defaults(); + + return true; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Database/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Database/Load.php new file mode 100644 index 000000000..620f99c7f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Database/Load.php @@ -0,0 +1,469 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Database; + + +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Interfaces\LoadInterface; +use VDM\Joomla\Abstraction\Database; + + +/** + * Database Load + * + * @since 3.2.0 + */ +final class Load extends Database implements LoadInterface +{ + /** + * Load data rows as an array of associated arrays + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * @param int|null $limit Limit the number of values returned + * + * @return array|null + * @since 3.2.0 + **/ + public function rows(array $select, array $tables, ?array $where = null, + ?array $order = null, ?int $limit = null): ?array + { + // set key if found + $key = ''; + if (isset($select['key'])) + { + if (is_string($select['key'])) + { + $key = $select['key']; + } + unset($select['key']); + } + + // check if we can get many rows + if ($this->many($select, $tables, $where, $order, $limit)) + { + // return associated arrays from the table records + return $this->db->loadAssocList($key); + } + + // data does not exist + return null; + } + + /** + * Load data rows as an array of objects + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * @param int|null $limit Limit the number of values returned + * + * @return array|null + * @since 3.2.0 + **/ + public function items(array $select, array $tables, ?array $where = null, + ?array $order = null, ?int $limit = null): ?array + { + // set key if found + $key = ''; + if (isset($select['key'])) + { + if (is_string($select['key'])) + { + $key = $select['key']; + } + unset($select['key']); + } + + // check if we can get many rows + if ($this->many($select, $tables, $where, $order, $limit)) + { + // return associated arrays from the table records + return $this->db->loadObjectList($key); + } + + // data does not exist + return null; + } + + /** + * Load data row as an associated array + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return array|null + * @since 3.2.0 + **/ + public function row(array $select, array $tables, ?array $where = null, ?array $order = null): ?array + { + // check if we can get one row + if ($this->one($select, $tables, $where, $order)) + { + return $this->db->loadAssoc(); + } + + // data does not exist + return null; + } + + /** + * Load data row as an object + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return object|null + * @since 3.2.0 + **/ + public function item(array $select, array $tables, ?array $where = null, ?array $order = null): ?object + { + // check if we can get one row + if ($this->one($select, $tables, $where, $order)) + { + return $this->db->loadObject(); + } + + // data does not exist + return null; + } + + /** + * Get the max value based on a filtered result from a given table + * + * @param string $field The field key + * @param string $tables The tables + * @param array $filter The filter keys + * + * @return int|null + * @since 3.2.0 + **/ + public function max($field, array $tables, array $filter): ?int + { + // only do check if we have the table set + if (isset($tables['a'])) + { + // get the query + $query = $this->query(["all" => "MAX(`$field`)"], $tables, $filter); + + // Load the max number + $this->db->setQuery($query); + $this->db->execute(); + + // check if we have values + if ($this->db->getNumRows()) + { + return (int) $this->db->loadResult(); + } + } + + // data does not exist + return null; + } + + /** + * Count the number of items based on filter result from a given table + * + * @param string $tables The table + * @param array $filter The filter keys + * + * @return int|null + * @since 3.2.0 + **/ + public function count(array $tables, array $filter): ?int + { + // only do check if we have the table set + if (isset($tables['a'])) + { + // get the query + $query = $this->query(["all" => 'COUNT(*)'], $tables, $filter); + + // Load the max number + $this->db->setQuery($query); + $this->db->execute(); + + // check if we have values + if ($this->db->getNumRows()) + { + return (int) $this->db->loadResult(); + } + } + + // data does not exist + return null; + } + + /** + * Load one value from a row + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return mixed + * @since 3.2.0 + **/ + public function value(array $select, array $tables, ?array $where = null, ?array $order = null) + { + // check if we can get one value + if ($this->one($select, $tables, $where, $order)) + { + return $this->db->loadResult(); + } + + // data does not exist + return null; + } + + /** + * Load many + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * @param int|null $limit Limit the number of values returned + * + * @return bool + * @since 3.2.0 + **/ + protected function many(array $select, array $tables, ?array $where = null, + ?array $order = null, ?int $limit = null): bool + { + // only do check if we have the table set + if (isset($tables['a'])) + { + // get the query + $query = $this->query($select, $tables, $where, $order, $limit); + + // Load the items + $this->db->setQuery($query); + $this->db->execute(); + + // check if we have values + if ($this->db->getNumRows()) + { + return true; + } + } + + // data does not exist + return false; + } + + /** + * Load one + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return bool + * @since 3.2.0 + **/ + protected function one(array $select, array $tables, ?array $where = null, ?array $order = null): bool + { + // only do check if we have the table set + if (isset($tables['a'])) + { + // get the query + $query = $this->query($select, $tables, $where, $order); + + // Load the item + $this->db->setQuery($query, 0, 1); + $this->db->execute(); + + // check if we have values + if ($this->db->getNumRows()) + { + return true; + } + } + + // data does not exist + return false; + } + + /** + * Get the query object + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * @param int|null $limit Limit the number of values returned + * + * @return object|null The query object (DatabaseQuery) + * @since 3.2.0 + **/ + protected function query(array $select, array $tables, ?array $where = null, + ?array $order = null, ?int $limit = null): ?object + { + $query = $this->db->getQuery(true); + + // check if we have an all selection set + if (isset($select['all'])) + { + // all selection example array: ['all' => ['a.*', 'b.*']] + if (ArrayHelper::check($select['all'])) + { + foreach ($select['all'] as $select_all) + { + // set target selection + $query->select( + $select_all + ); + } + } + // all selection example string: ['all' =>'a.*'] + elseif (is_string($select['all'])) + { + // set target selection + $query->select( + $select['all'] + ); + } + unset($select['all']); + } + + // load the table where join + if (ArrayHelper::check($select)) + { + // set target selection + $query->select( + $this->db->quoteName( + array_keys($select), + array_values($select) + ) + ); + } + + // set main table + $query->from($this->db->quoteName($this->getTable($tables['a']), 'a')); + + // remove main table + unset($tables['a']); + + // load the table where join + if (ArrayHelper::check($tables)) + { + foreach ($tables as $as => $table) + { + $query->join( + 'LEFT', $this->db->quoteName( + $this->getTable($table['name']), $as + ) . ' ON (' . $this->db->quoteName($table['join_on']) + . ' = ' . $this->db->quoteName($table['as_on']) . ')' + ); + } + } + + // load the table where getters + if (ArrayHelper::check($where)) + { + foreach ($where as $key => $value) + { + if (ArrayHelper::check($value)) + { + if (isset($value['value']) && isset($value['operator'])) + { + // check if value needs to be quoted + $quote = $value['quote'] ?? true; + if (!$quote) + { + if (ArrayHelper::check($value['value'])) + { + // add the where by array + $query->where($this->db->quoteName($key) . ' ' . + $value['operator'] . ' (' . + implode(',', $value['value']) + . ')' + ); + } + else + { + // add the where + $query->where($this->db->quoteName($key) . ' ' . + $value['operator'] . ' ' . $value['value']); + } + } + else + { + if (ArrayHelper::check($value['value'])) + { + // add the where by array + $query->where($this->db->quoteName($key) . ' ' . + $value['operator'] . ' (' . + implode(',', + array_map( + fn($val) => $this->quote($val), + $value['value'] + ) + ) + . ')' + ); + } + else + { + // add the where + $query->where($this->db->quoteName($key) . ' ' . + $value['operator'] . ' ' . $this->quote($value['value'])); + } + } + } + else + { + // we should through an exception + // for security we just return nothing for now + return null; + } + } + else + { + // add the where + $query->where($this->db->quoteName($key) . + ' = ' . $this->quote($value)); + } + } + } + + // load the row ordering + if (ArrayHelper::check($order)) + { + foreach ($order as $key => $direction) + { + // add the ordering + $query->order($this->db->quoteName($key) . + ' ' . $direction); + } + } + + // only return a limited number + if (is_numeric($limit)) + { + $query->setLimit($limit); + } + + return $query; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Database/Update.php b/libraries/jcb_powers/VDM.Joomla/src/Database/Update.php new file mode 100644 index 000000000..6c4a122d9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Database/Update.php @@ -0,0 +1,188 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Database; + + +use VDM\Joomla\Interfaces\UpdateInterface; +use VDM\Joomla\Abstraction\Database; + + +/** + * Database Update Class + * + * @since 3.2.0 + */ +final class Update extends Database implements UpdateInterface +{ + /** + * Update rows in the database (with remapping and filtering columns option) + * + * @param array $data Dataset to update in database [array of arrays (key => value)] + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $key, string $table, array $columns = []): bool + { + // set the update columns + if ($data === [] || strlen($key) == 0) + { + return false; + } + + // set the update values + foreach ($data as $values) + { + if ($columns !== []) + { + // load only what is part of the columns set + $row = []; + foreach ($columns as $column => $key_) + { + if (isset($values[$key_])) + { + $row[$column] = $values[$key_]; + } + } + + // update the row + $this->row($row, $key, $table); + } + else + { + // update the row + $this->row((array) $values, $key, $table); + } + } + + return true; + } + + /** + * Update items in the database (with remapping and filtering columns option) + * + * @param array $data Data to updated in database (array of objects) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being update + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $key, string $table, array $columns = []): bool + { + // set the update columns + if ($data === [] || strlen($key) == 0) + { + return false; + } + + // set the update values + foreach ($data as $nr => $values) + { + if ($columns !== []) + { + // load only what is part of the columns set + $row = []; + foreach ($columns as $column => $key_) + { + if (isset($values->{$key_})) + { + $row[$column] = $values->{$key_}; + } + } + + // update the row + $this->row($row, $key, $table); + } + else + { + // update the row + $this->row((array) $values, $key, $table); + } + } + + return true; + } + + /** + * Update row in the database + * + * @param array $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function row(array $data, string $key, string $table): bool + { + // set the update columns + if ($data === [] || strlen($key) == 0) + { + return false; + } + + // get a query object + $query = $this->db->getQuery(true); + + // set the query targets + $query->update($this->db->quoteName($this->getTable($table))); + + // set the update values + $key_ = null; + foreach ($data as $column => $value) + { + if ($column === $key) + { + $key_ = $value; + } + else + { + $query->set($this->db->quoteName($column) . ' = ' . $this->quote($value)); + } + } + + // add the key condition + if ($key_ !== null) + { + $query->where($this->db->quoteName($key) . ' = ' . $this->quote($key_)); + + // execute the final query + $this->db->setQuery($query); + + return $this->db->execute(); + } + + return false; + } + + /** + * Update item in the database + * + * @param object $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $key, string $table): bool + { + // convert to an array + return $this->row((array) get_object_vars($data), $key, $table); + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Database/index.html b/libraries/jcb_powers/VDM.Joomla/src/Database/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Database/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Activeregistryinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Activeregistryinterface.php new file mode 100644 index 000000000..9fdf2c0a4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Activeregistryinterface.php @@ -0,0 +1,98 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * The Active Registry Interface + * + * @since 3.2.0 + */ +interface Activeregistryinterface +{ + /** + * Check if the registry has any content. + * + * @return bool Returns true if the active array is not empty, false otherwise. + * @since 3.2.0 + */ + public function isActive(): bool; + + /** + * Retrieves all value from the registry. + * + * @return array The values. + * @since 3.2.0 + */ + public function allActive(): array; + + /** + * Sets a value into the registry using multiple keys. + * + * @param mixed $value The value to set. + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return void + * @since 3.2.0 + */ + public function setActive($value, string ...$keys): void; + + /** + * Adds content into the registry. If a key exists, + * it either appends or concatenates based on the value's type. + * + * @param mixed $value The value to set. + * @param bool $asArray Determines if the new value should be treated as an array. + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return void + * @since 3.2.0 + */ + public function addActive($value, bool $asArray, string ...$keys): void; + + /** + * Retrieves a value (or sub-array) from the registry using multiple keys. + * + * @param mixed $default The default value if not set. + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return mixed The value or sub-array from the storage. Null if the location doesn't exist. + * @since 3.2.0 + */ + public function getActive($default, string ...$keys); + + /** + * Removes a value (or sub-array) from the registry using multiple keys. + * + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return void + * @since 3.2.0 + */ + public function removeActive(string ...$keys): void; + + /** + * Checks the existence of a particular location in the registry using multiple keys. + * + * @param string ...$keys The keys to determine the location. + * + * @throws \InvalidArgumentException If any of the keys are not a number or string. + * @return bool True if the location exists, false otherwise. + * @since 3.2.0 + */ + public function existsActive(string ...$keys): bool; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/FactoryInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/FactoryInterface.php new file mode 100644 index 000000000..0dd2e4cf7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/FactoryInterface.php @@ -0,0 +1,41 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +use Joomla\DI\Container; + + +/** + * The Container Factory Interface + */ +interface FactoryInterface +{ + /** + * Get any class from the container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _(string $key); + + /** + * Get the global container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/InsertInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/InsertInterface.php new file mode 100644 index 000000000..c76b97b40 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/InsertInterface.php @@ -0,0 +1,78 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * Database Insert Interface + * + * @since 3.2.0 + */ +interface InsertInterface +{ + /** + * Switch to prevent/allow defaults from being added. + * + * @param bool $trigger toggle the defaults + * + * @return void + * @since 3.2.0 + **/ + public function defaults(bool $trigger = true); + + /** + * Insert rows to the database (with remapping and filtering columns option) + * + * @param array $data Dataset to store in database [array of arrays (key => value)] + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $table, array $columns = []): bool; + + /** + * Insert items to the database (with remapping and filtering columns option) + * + * @param array $data Data to store in database (array of objects) + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $table, array $columns = []): bool; + + /** + * Insert row to the database + * + * @param array $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added + * + * @return bool + * @since 3.2.0 + **/ + public function row(array $data, string $table): bool; + + /** + * Insert item to the database + * + * @param object $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $table): bool; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/LoadInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/LoadInterface.php new file mode 100644 index 000000000..31017c584 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/LoadInterface.php @@ -0,0 +1,114 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * Database Load Interface + * + * @since 3.2.0 + */ +interface LoadInterface +{ + /** + * Load data rows as an array of associated arrays + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * @param int|null $limit Limit the number of values returned + * + * @return array|null + * @since 3.2.0 + **/ + public function rows(array $select, array $tables, ?array $where = null, + ?array $order = null, ?int $limit = null): ?array; + + /** + * Load data rows as an array of objects + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * @param int|null $limit Limit the number of values returned + * + * @return array|null + * @since 3.2.0 + **/ + public function items(array $select, array $tables, ?array $where = null, + ?array $order = null, ?int $limit = null): ?array; + + /** + * Load data row as an associated array + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return array|null + * @since 3.2.0 + **/ + public function row(array $select, array $tables, ?array $where = null, ?array $order = null): ?array; + + /** + * Load data row as an object + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return object|null + * @since 3.2.0 + **/ + public function item(array $select, array $tables, ?array $where = null, ?array $order = null): ?object; + + /** + * Get the max value based on a filtered result from a given table + * + * @param string $field The field key + * @param string $tables The table + * @param array $filter The filter keys + * + * @return int|null + * @since 3.2.0 + **/ + public function max($field, array $tables, array $filter): ?int; + + /** + * Count the number of items based on filter result from a given table + * + * @param string $tables The table + * @param array $filter The filter keys + * + * @return int|null + * @since 3.2.0 + **/ + public function count(array $tables, array $filter): ?int; + + /** + * Load one value from a row + * + * @param array $select Array of selection keys + * @param array $tables Array of tables to search + * @param array|null $where Array of where key=>value match exist + * @param array|null $order Array of how to order the data + * + * @return mixed + * @since 3.2.0 + **/ + public function value(array $select, array $tables, ?array $where = null, ?array $order = null); +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/ModelInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/ModelInterface.php new file mode 100644 index 000000000..51f342455 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/ModelInterface.php @@ -0,0 +1,94 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * Model Interface + * + * @since 3.2.0 + */ +interface ModelInterface +{ + /** + * Model the value + * Example: $this->value(value, 'value_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null); + + /** + * Model the values of an item + * Example: $this->item(Object, 'table_name'); + * + * @param object $item The item object + * @param string|null $table The table + * + * @return object|null + * @since 3.2.0 + */ + public function item(object $item, ?string $table = null): ?object; + + /** + * Model the values of multiple items + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The array of item objects + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function items(?array $items = null, ?string $table = null): ?array; + + /** + * Model the values of an row + * Example: $this->item(Array, 'table_name'); + * + * @param array $item The item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function row(array $item, ?string $table = null): ?array; + + /** + * Model the values of multiple rows + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The array of item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function rows(?array $items = null, ?string $table = null): ?array; + + /** + * Get last modeled ID + * Example: $this->last('table_name'); + * + * @param string|null $table The table + * + * @return int|null + * @since 3.2.0 + */ + public function last(?string $table = null): ?int; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Registryinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Registryinterface.php new file mode 100644 index 000000000..e7a8f0297 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Registryinterface.php @@ -0,0 +1,92 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * The Registry Interface + * + * @since 3.2.0 + */ +interface Registryinterface +{ + /** + * Sets a value into the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * @param mixed $value Value of entry + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return void + * @since 3.2.0 + */ + public function set(string $path, $value): void; + + /** + * Adds content into the registry. If a key exists, + * it either appends or concatenates based on $asArray switch. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * @param mixed $value Value of entry + * @param bool $asArray Determines if the new value should be treated as an array. Default is false. + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return void + * @since 3.2.0 + */ + public function add(string $path, $value, bool $asArray = false): void; + + /** + * Retrieves a value (or sub-array) from the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * @param mixed $default Optional default value, returned if the internal doesn't exist. + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return mixed The value or sub-array from the storage. Null if the location doesn't exist. + * @since 3.2.0 + */ + public function get(string $path, $default = null); + + /** + * Removes a value (or sub-array) from the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return void + * @since 3.2.0 + */ + public function remove(string $path): void; + + /** + * Checks the existence of a particular location in the registry using multiple keys. + * + * @param string $path Registry path (e.g. vdm.content.builder) + * + * @throws \InvalidArgumentException If any of the path values are not a number or string. + * @return bool True if the location exists, false otherwise. + * @since 3.2.0 + */ + public function exists(string $path): bool; + + /** + * Sets a separator value + * + * @param string|null $value The value to set. + * + * @return void + * @since 3.2.0 + */ + public function setSeparator(?string $value): void; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Tableinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Tableinterface.php new file mode 100644 index 000000000..4d8f74115 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/Tableinterface.php @@ -0,0 +1,89 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * The VDM Core Table Interface + */ +interface Tableinterface +{ + /** + * Get any value from a item/field/column of an area/view/table + * Example: $this->get('table_name', 'field_name', 'value_key'); + * Get an item/field/column of an area/view/table + * Example: $this->get('table_name', 'field_name'); + * Get all items/fields/columns of an area/view/table + * Example: $this->get('table_name'); + * Get all areas/views/tables with all their item/field/column details + * Example: $this->get('All'); + * + * @param string $table The table + * @param string|null $field The field + * @param string|null $key The value key + * + * @return mixed + * @since 3.2.0 + */ + public function get(string $table, ?string $field = null, ?string $key = null); + + /** + * Get title field from an area/view/table + * + * @param string $table The area + * + * @return ?array + * @since 3.2.0 + */ + public function title(string $table): ?array; + + /** + * Get title field name + * + * @param string $table The area + * + * @return string + * @since 3.2.0 + */ + public function titleName(string $table): string; + + /** + * Get all tables + * + * @return array + * @since 3.2.0 + */ + public function tables(): array; + + /** + * Check if a table (and field) exist + * + * @param string $table The area + * @param string|null $field The area + * + * @return bool + * @since 3.2.0 + */ + public function exist(string $table, ?string $field = null): bool; + + /** + * Get all fields of an area/view/table + * + * @param string $table The area + * @param bool $default Add the default fields + * + * @return array|null On success an array of fields + * @since 3.2.0 + */ + public function fields(string $table, bool $default = false): ?array; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/UpdateInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/UpdateInterface.php new file mode 100644 index 000000000..3e43b16f3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/UpdateInterface.php @@ -0,0 +1,72 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Interfaces; + + +/** + * Database Update Interface + * + * @since 3.2.0 + */ +interface UpdateInterface +{ + /** + * Update rows in the database (with remapping and filtering columns option) + * + * @param array $data Dataset to update in database [array of arrays (key => value)] + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $key, string $table, array $columns = []): bool; + + /** + * Update items in the database (with remapping and filtering columns option) + * + * @param array $data Data to updated in database (array of objects) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being update + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $key, string $table, array $columns = []): bool; + + /** + * Update row in the database + * + * @param array $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function row(array $data, string $key, string $table): bool; + + /** + * Update item in the database + * + * @param object $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $key, string $table): bool; +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Interfaces/index.html b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Interfaces/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities.php index 221c7dd9e..b473fea4f 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla; diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/ArrayHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/ArrayHelper.php index d5550b7bc..70cc939c8 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/ArrayHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/ArrayHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -24,28 +24,30 @@ abstract class ArrayHelper * * @input array The array to check * - * @returns bool/int number of items in array on success + * @returns int|false number of items in array on success * - * @since 3.0.9 + * @since 3.2.0 */ public static function check($array, $removeEmptyString = false) { - if (is_array($array) && ($nr = count((array)$array)) > 0) + if (is_array($array) && ($nr = count((array) $array)) > 0) { // also make sure the empty strings are removed if ($removeEmptyString) { - foreach ($array as $key => $string) + $array = array_filter($array); + + if ($array === []) { - if (empty($string)) - { - unset($array[$key]); - } + return false; } - return self::check($array, false); + + return count($array); } + return $nr; } + return false; } @@ -54,25 +56,25 @@ abstract class ArrayHelper * * @input array The arrays you would like to merge * - * @returns array on success + * @returns array|null merged array on success * * @since 3.0.9 */ - public static function merge($arrays) + public static function merge($arrays): ?array { if(self::check($arrays)) { - $arrayBuket = array(); + $merged = []; foreach ($arrays as $array) { if (self::check($array)) { - $arrayBuket = array_merge($arrayBuket, $array); + $merged = array_merge($merged, $array); } } - return $arrayBuket; + return $merged; } - return false; + return null; } /** @@ -85,7 +87,7 @@ abstract class ArrayHelper * * @since 3.1.1 */ - public static function intersect($a_array, $b_array) + public static function intersect($a_array, $b_array): bool { // flip the second array $b_array = array_flip($b_array); diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/Base64Helper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/Base64Helper.php new file mode 100644 index 000000000..b33b129b6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/Base64Helper.php @@ -0,0 +1,65 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Utilities; + + +use VDM\Joomla\Utilities\StringHelper; + + +/** + * The Base64 Helper + * + * @since 3.2.0 + */ +abstract class Base64Helper +{ + /** + * open base64 string if stored as base64 (in JCB) + * + * @param string|null $data The base64 string + * @param string|null $key We store the string with that suffix :) + * @param string|null $default The default switch + * + * @return string|null The opened string + * @since 3.2.0 + */ + public static function open(?string $data, ?string $key = '__.o0=base64=Oo.__', ?string $default = 'string'): ?string + { + // check that we have a string + if (StringHelper::check($data)) + { + // check if we have a key + if (StringHelper::check($key)) + { + if (strpos($data, $key) !== false) + { + return base64_decode(str_replace($key, '', $data)); + } + } + + // fallback to this, not perfect method + if (base64_encode(base64_decode($data, true)) === $data) + { + return base64_decode($data); + } + } + + // check if we should just return the string + if ('string' === $default) + { + return $data; + } + + return $default; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/Component/Helper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/Component/Helper.php index 498e3da83..61dbf59f8 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/Component/Helper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/Component/Helper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities\Component; @@ -27,10 +27,10 @@ abstract class Helper /** * The current option * - * @var String + * @var string * @since 3.0.11 */ - public static $option; + public static string $option; /** * The component params list cache @@ -38,19 +38,18 @@ abstract class Helper * @var Registry[] * @since 3.0.11 */ - protected static $params = array(); + protected static array $params = []; /** * Gets the parameter object for the component * - * @param String $option The option for the component. - * - * @return Registry A Registry object. + * @param string|null $option The option for the component. * + * @return Registry A Registry object. * @see Registry * @since 3.0.11 */ - public static function getParams($option = null) + public static function getParams(?string $option = null): Registry { // check that we have an option if (empty($option)) @@ -70,13 +69,12 @@ abstract class Helper /** * Gets the component option * - * @param String|Bool $default The default return value if none is found - * - * @return String|Bool A component option + * @param string|null $default The default return value if none is found * + * @return string|null A component option * @since 3.0.11 */ - public static function getOption($default = 'empty') + public static function getOption(string $default = 'empty'): ?string { if (empty(self::$option)) { @@ -95,14 +93,13 @@ abstract class Helper /** * Gets the component code name * - * @param String $option The option for the component. - * @param String|Bool $default The default return value if none is found - * - * @return String|Mixed A component code name + * @param string|null $option The option for the component. + * @param string|null $default The default return value if none is found * + * @return string|null A component code name * @since 3.0.11 */ - public static function getCode($option = null, $default = null) + public static function getCode(?string $option = null, ?string $default = null): ?string { // check that we have an option if (empty($option)) @@ -121,14 +118,14 @@ abstract class Helper /** * Gets the component abstract helper class * - * @param String $option The option for the component. - * @param String|Bool $default The default return value if none is found + * @param string|null $option The option for the component. + * @param string|null $default The default return value if none is found * - * @return String|Mixed A component helper name + * @return string|null A component helper name * * @since 3.0.11 */ - public static function get($option = null, $default = null) + public static function get(string $option = null, string $default = null): ?string { // check that we have an option // and get the code name from it @@ -149,25 +146,43 @@ abstract class Helper /** * Check if the helper class of this component has a method * - * @param String $method The method name to search for - * @param String $option The option for the component. + * @param string $method The method name to search for + * @param string|null $option The option for the component. * - * @return bool true if method exist + * @return bool true if method exist * * @since 3.0.11 */ - public static function methodExists($method, $option = null) + public static function methodExists(string $method, string $option = null): bool { // get the helper class - if (($helper = self::get($option, false)) !== false) + return ($helper = self::get($option, false)) !== false && + method_exists($helper, $method); + } + + /** + * Check if the helper class of this component has a method, and call it with the arguments + * + * @param string $method The method name to search for + * @param array $arguments The arguments for function. + * @param string|null $option The option for the component. + * + * @return mixed return whatever the method returns or null + * @since 3.2.0 + */ + public static function _(string $method, array $arguments = [], ?string $option = null) + { + // get the helper class + if (($helper = self::get($option, false)) !== false && + method_exists($helper, $method)) { - if (method_exists($helper, $method)) - { - return true; - } + // we know this is not ideal... + // so we need to move these + // functions to their own classes + return call_user_func_array([$helper, $method], $arguments); } - return false; + return null; } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/FileHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/FileHelper.php index 5a7e1cb02..0dd04d81b 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/FileHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/FileHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -48,7 +48,7 @@ abstract class FileHelper * * @since 3.0.9 */ - public static function zip($workingDirectory, &$filepath) + public static function zip($workingDirectory, &$filepath): bool { // store the current joomla working directory $joomla = getcwd(); @@ -65,12 +65,12 @@ abstract class FileHelper // get a list of files in the current directory tree (also the hidden files) $files = Folder::files('.', '', true, true, array('.svn', 'CVS', '.DS_Store', '__MACOSX'), array('.*~')); - $zipArray = array(); + $zipArray = []; // setup the zip array foreach ($files as $file) { - $tmp = array(); - $tmp['name'] = str_replace('./', '', $file); + $tmp = []; + $tmp['name'] = str_replace('./', '', (string) $file); $tmp['data'] = self::getContent($file); $tmp['time'] = filemtime($file); $zipArray[] = $tmp; @@ -80,15 +80,10 @@ abstract class FileHelper chdir($joomla); // get the zip adapter - $adapter = new Archive(); - $zip = $adapter->getAdapter('zip'); + $zip = (new Archive())->getAdapter('zip'); //create the zip file - if ($zip->create($filepath, $zipArray)) - { - return true; - } - return false; + return (bool) $zip->create($filepath, $zipArray); } /** @@ -116,7 +111,7 @@ abstract class FileHelper // start curl $ch = curl_init(); // set the options - $options = array(); + $options = []; $options[CURLOPT_URL] = $path; $options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $options[CURLOPT_RETURNTRANSFER] = TRUE; @@ -137,7 +132,7 @@ abstract class FileHelper elseif (!self::$curlError) { // set the notice - Factory::getApplication()->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_BCOMPONENTBUILDERB_WILL_NOT_FUNCTION_CORRECTLYP'), 'Error'); + Factory::getApplication()->enqueueMessage('

Curl Not Found!

Please setup curl on your system, or the Joomla Component will not function correctly!

', 'Error'); // load this notice only once self::$curlError = true; } @@ -222,7 +217,7 @@ abstract class FileHelper chdir($joomla); // return array of files - return array_map( function($file) { return str_replace('./', '/', $file); }, (array) ArrayHelper::merge($files)); + return array_map( fn($file) => str_replace('./', '/', (string) $file), (array) ArrayHelper::merge($files)); } return false; } @@ -253,7 +248,7 @@ abstract class FileHelper $filePath = Helper::getParams()->get($target, $default); // check the file path (revert to default only of not a hidden file path) - if ('hiddenfilepath' !== $target && strpos($filePath, JPATH_SITE) === false) + if ('hiddenfilepath' !== $target && strpos((string) $filePath, (string) JPATH_SITE) === false) { $filePath = $default; } @@ -297,9 +292,9 @@ abstract class FileHelper // return the url if ('url' === $type) { - if (\strpos($filePath, JPATH_SITE) !== false) + if (\strpos((string) $filePath, (string) JPATH_SITE) !== false) { - $filePath = trim( str_replace( JPATH_SITE, '', $filePath), '/'); + $filePath = trim( str_replace( JPATH_SITE, '', (string) $filePath), '/'); return Uri::root() . $filePath . '/' . $fileName; } @@ -309,7 +304,7 @@ abstract class FileHelper } // sanitize the path - return '/' . trim( $filePath, '/' ) . '/' . $fileName; + return '/' . trim((string) $filePath, '/' ) . '/' . $fileName; } /** diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/FormHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/FormHelper.php new file mode 100644 index 000000000..a2f48fd41 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/FormHelper.php @@ -0,0 +1,187 @@ + + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace VDM\Joomla\Utilities; + + +use Joomla\CMS\Form\FormHelper as JoomlaFormHelper; +use Joomla\CMS\Form\FormField; + + +/** + * Form Helper + * + * @since 3.2.0 + */ +abstract class FormHelper +{ + /** + * get the field xml + * + * @param array $attributes The array of attributes + * @param array $options The options to apply to the XML element + * + * @return \SimpleXMLElement|null + * @since 3.2.0 + */ + public static function xml(array $attributes, ?array $options = null): ?\SimpleXMLElement + { + // make sure we have attributes and a type value + if (ArrayHelper::check($attributes)) + { + // start field xml + $XML = new \SimpleXMLElement(''); + + // load the attributes + self::attributes($XML, $attributes); + + // check if we have options + if (ArrayHelper::check($options)) + { + // load the options + self::options($XML, $options); + } + + // return the field xml + return $XML; + } + + return null; + } + + /** + * xmlAppend + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param mixed $node A SimpleXMLElement node to append to the XML element reference, + * or a stdClass object containing a comment attribute to be injected + * before the XML node and a fieldXML attribute containing a SimpleXMLElement + * + * @return void + * @since 3.2.0 + */ + public static function append(\SimpleXMLElement &$xml, $node) + { + if (!$node) + { + // element was not returned + return; + } + switch (get_class($node)) + { + case 'stdClass': + if (property_exists($node, 'comment')) + { + self::comment($xml, $node->comment); + } + if (property_exists($node, 'fieldXML')) + { + self::append($xml, $node->fieldXML); + } + break; + case 'SimpleXMLElement': + $domXML = \dom_import_simplexml($xml); + $domNode = \dom_import_simplexml($node); + $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); + $xml = \simplexml_import_dom($domXML); + break; + } + } + + /** + * xmlComment + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param string $comment The comment to inject + * + * @return void + * @since 3.2.0 + */ + public static function comment(\SimpleXMLElement &$xml, string $comment) + { + $domXML = \dom_import_simplexml($xml); + $domComment = new \DOMComment($comment); + $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); + $domXML->appendChild($nodeTarget); + $xml = \simplexml_import_dom($domXML); + } + + /** + * xmlAddAttributes + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $attributes The attributes to apply to the XML element + * + * @return void + * @since 3.2.0 + */ + public static function attributes(\SimpleXMLElement &$xml, array $attributes = []) + { + foreach ($attributes as $key => $value) + { + $xml->addAttribute($key, $value); + } + } + + /** + * xmlAddOptions + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $options The options to apply to the XML element + * + * @return void + * @since 3.2.0 + */ + public static function options(\SimpleXMLElement &$xml, array $options = []) + { + foreach ($options as $key => $value) + { + $addOption = $xml->addChild('option'); + $addOption->addAttribute('value', $key); + $addOption[] = $value; + } + } + + /** + * get the field object + * + * @param array $attributes The array of attributes + * @param string $default The default of the field + * @param array $options The options to apply to the XML element + * + * @return FormField|null + * @since 3.2.0 + */ + public static function field(array $attributes, string $default = '', ?array $options = null): ?FormField + { + // make sure we have attributes and a type value + if (ArrayHelper::check($attributes) && isset($attributes['type'])) + { + // get field type + if (($field = JoomlaFormHelper::loadFieldType($attributes['type'], true)) === false) + { + return null; + } + + // get field xml + $XML = self::xml($attributes, $options); + + // setup the field + $field->setup($XML, $default); + + // return the field object + return $field; + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php index 259944d07..f58409767 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -26,18 +26,19 @@ abstract class GetHelper /** * Get a Variable * - * @param string $table The table from which to get the variable - * @param string $where The value where - * @param string $whereString The target/field string where/name - * @param string $what The return field - * @param string $operator The operator between $whereString/field and $where/value - * @param string $main The component in which the table is found + * @param string|null $table The table from which to get the variable + * @param mixed $where The value where + * @param string $whereString The target/field string where/name + * @param string $what The return field + * @param string $operator The operator between $whereString/field and $where/value + * @param string $main The component in which the table is found * - * @return mix string/int/float - * + * @return mixed string/int/float * @since 3.0.9 */ - public static function var($table, $where = null, $whereString = 'user', $what = 'id', $operator = '=', $main = null) + public static function var(?string $table = null, $where = null, + string $whereString = 'user', string $what = 'id', + string $operator = '=', ?string $main = null) { if(empty($where)) { @@ -85,25 +86,27 @@ abstract class GetHelper { return $db->loadResult(); } + return false; } /** * Get array of variables * - * @param string $table The table from which to get the variables - * @param string $where The value where - * @param string $whereString The target/field string where/name - * @param string $what The return field - * @param string $operator The operator between $whereString/field and $where/value - * @param string $main The component in which the table is found - * @param bool $unique The switch to return a unique array + * @param string|null $table The table from which to get the variables + * @param mixed $where The value where + * @param string $whereString The target/field string where/name + * @param string $what The return field + * @param string $operator The operator between $whereString/field and $where/value + * @param string $main The component in which the table is found + * @param bool $unique The switch to return a unique array * - * @return array - * + * @return array|null * @since 3.0.9 */ - public static function vars($table, $where = null, $whereString = 'user', $what = 'id', $operator = 'IN', $main = null, $unique = true) + public static function vars(?string $table = null, $where = null, + string $whereString = 'user', string $what = 'id', string $operator = 'IN', + ?string $main = null, bool $unique = true): ?array { if(empty($where)) { @@ -147,11 +150,11 @@ abstract class GetHelper // add strings to array search if ('IN_STRINGS' === $operator || 'NOT IN_STRINGS' === $operator) { - $query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","',$where) . '")'); + $query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","', $where) . '")'); } else { - $query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',',$where) . ')'); + $query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',', $where) . ')'); } $db->setQuery($query); @@ -166,71 +169,83 @@ abstract class GetHelper return $db->loadColumn(); } } - return false; + + return null; } /** * get all strings between two other strings * - * @param string $content The content to search - * @param string $start The starting value - * @param string $end The ending value + * @param string $content The content to search + * @param string $start The starting value + * @param string $end The ending value * - * @return array On success - * + * @return array|null On success * @since 3.0.9 */ - public static function allBetween($content, $start, $end) + public static function allBetween(string $content, string $start, string $end): ?array { // reset bucket - $bucket = array(); + $bucket = []; for ($i = 0; ; $i++) { // search for string - $found = self::between($content,$start,$end); + $found = self::between($content, $start, $end); + if (StringHelper::check($found)) { // add to bucket $bucket[] = $found; + // build removal string - $remove = $start.$found.$end; + $remove = $start . $found . $end; + // remove from content - $content = str_replace($remove,'',$content); + $content = str_replace($remove, '', $content); } else { break; } + // safety catch if ($i == 500) { break; } } + // only return unique array of values - return array_unique($bucket); + if (ArrayHelper::check($bucket)) + { + return array_unique($bucket); + } + + return null; } /** * get a string between two other strings * - * @param string $content The content to search - * @param string $start The starting value - * @param string $end The ending value - * @param string $default The default value if none found + * @param string $content The content to search + * @param string $start The starting value + * @param string $end The ending value + * @param string $default The default value if none found * * @return string On success / empty string on failure - * * @since 3.0.9 */ - public static function between($content, $start, $end, $default = '') + public static function between(string $content, string $start, string $end, string $default = ''): string { - $r = explode($start, $content); - if (isset($r[1])) + $array = explode($start, $content); + if (isset($array[1]) && strpos($array[1], $end) !== false) { - $r = explode($end, $r[1]); - return $r[0]; + $array = explode($end, $array[1]); + + // return string found between + return $array[0]; } + return $default; } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php index a4aa4a2f8..e21947347 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -39,12 +39,12 @@ abstract class GuidHelper * * @since 3.0.9 */ - public static function get($trim = true) + public static function get(bool $trim = true): string { // Windows - if (function_exists('com_create_guid') === true) + if (function_exists('com_create_guid')) { - if ($trim === true) + if ($trim) { return trim(com_create_guid(), '{}'); } @@ -56,7 +56,7 @@ abstract class GuidHelper $rbrace = $trim ? "" : chr(125); // "}" // OSX/Linux - if (function_exists('openssl_random_pseudo_bytes') === true) + if (function_exists('openssl_random_pseudo_bytes')) { $data = openssl_random_pseudo_bytes(16); $data[6] = chr( ord($data[6]) & 0x0f | 0x40); // set version to 0100 @@ -82,7 +82,7 @@ abstract class GuidHelper * Validate the Globally Unique Identifier ( and check if table already has this identifier) * * @param string $guid - * @param string $table + * @param string|null $table * @param int $id * @param string|null $component * @@ -90,7 +90,7 @@ abstract class GuidHelper * * @since 3.0.9 */ - public static function valid($guid, $table = null, $id = 0, $component = null) + public static function valid($guid, ?string $table = null, int $id = 0, ?string $component = null): bool { // check if we have a string if (self::validate($guid)) @@ -135,60 +135,58 @@ abstract class GuidHelper * * @param string $guid * @param string $table - * @param string/array $what + * @param string|array $what * @param string|null $component * * @return mix * * @since 3.0.9 */ - public static function item($guid, $table, $what = 'a.id', $component = null) + public static function item($guid, $table, $what = 'a.id', ?string $component = null) { // check if we have a string - if (self::validate($guid)) + // check if table already has this identifier + if (self::validate($guid) && StringHelper::check($table)) { - // check if table already has this identifier - if (StringHelper::check($table)) + // check that we have the component code name + if (!is_string($component)) { - // check that we have the component code name - if (!is_string($component)) - { - $component = (string) Helper::getCode(); - } - // Get the database object and a new query object. - $db = Factory::getDbo(); - $query = $db->getQuery(true); + $component = (string) Helper::getCode(); + } + // Get the database object and a new query object. + $db = Factory::getDbo(); + $query = $db->getQuery(true); - if (ArrayHelper::check($what)) + if (ArrayHelper::check($what)) + { + $query->select($db->quoteName($what)); + } + else + { + $query->select($what); + } + + $query->from($db->quoteName('#__' . (string) $component . '_' . (string) $table, 'a')) + ->where($db->quoteName('a.guid') . ' = ' . $db->quote($guid)); + + // Set and query the database. + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + if (ArrayHelper::check($what) || $what === 'a.*') { - $query->select($db->quoteName($what)); + return $db->loadObject(); } else { - $query->select($what); - } - - $query->from($db->quoteName('#__' . (string) $component . '_' . (string) $table, 'a')) - ->where($db->quoteName('a.guid') . ' = ' . $db->quote($guid)); - - // Set and query the database. - $db->setQuery($query); - $db->execute(); - - if ($db->getNumRows()) - { - if (ArrayHelper::check($what) || $what === 'a.*') - { - return $db->loadObject(); - } - else - { - return $db->loadResult(); - } + return $db->loadResult(); } } } - return false; + + return null; } /** diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/JsonHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/JsonHelper.php index 1eaa245cd..47fbd243f 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/JsonHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/JsonHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -32,7 +32,7 @@ abstract class JsonHelper { if (StringHelper::check($string)) { - json_decode($string); + json_decode((string) $string); return (json_last_error() === JSON_ERROR_NONE); } @@ -52,14 +52,14 @@ abstract class JsonHelper { // do some table foot work $external = false; - if (strpos($table, '#__') !== false) + if (is_string($table) && strpos((string) $table, '#__') !== false) { $external = true; - $table = str_replace('#__', '', $table); + $table = str_replace('#__', '', (string) $table); } // check if string is JSON - $result = json_decode($value, true); + $result = json_decode((string) $value, true); if (json_last_error() === JSON_ERROR_NONE) { // is JSON @@ -67,7 +67,7 @@ abstract class JsonHelper { if (StringHelper::check($table)) { - $names = array(); + $names = []; foreach ($result as $val) { if ($external) @@ -92,7 +92,7 @@ abstract class JsonHelper } return (string) implode($separator, $result); } - return (string) json_decode($value); + return (string) json_decode((string) $value); } return $value; } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/MathHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/MathHelper.php index 5e2dae2d8..e407440a5 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/MathHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/MathHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -27,48 +27,47 @@ abstract class MathHelper * @param int $val2 The second value * @param int $scale The scale value * - * @return int + * @return string|int|null|bool * * @since 3.0.9 */ public static function bc($type, $val1, $val2, $scale = 0) { - // build function name + // Validate input + if (!is_numeric($val1) || !is_numeric($val2)) + { + return null; + } + + // Build function name $function = 'bc' . $type; - // use the bcmath function if available - if (function_exists($function)) + + // Use the bcmath function if available + if (is_callable($function)) { return $function($val1, $val2, $scale); } + // if function does not exist we use +-*/ operators (fallback - not ideal) switch ($type) { - // Multiply two numbers case 'mul': return (string) round($val1 * $val2, $scale); - break; - // Divide of two numbers case 'div': + if ($val2 == 0) return null; // Avoid division by zero return (string) round($val1 / $val2, $scale); - break; - // Adding two numbers case 'add': return (string) round($val1 + $val2, $scale); - break; - // Subtract one number from the other case 'sub': return (string) round($val1 - $val2, $scale); - break; - // Raise an arbitrary precision number to another case 'pow': return (string) round(pow($val1, $val2), $scale); - break; - // Compare two arbitrary precision numbers case 'comp': - return (round($val1,2) == round($val2,2)); - break; + $diff = round($val1 - $val2, $scale); + return ($diff > 0) ? 1 : (($diff < 0) ? -1 : 0); } - return false; + + return null; } /** @@ -91,7 +90,7 @@ abstract class MathHelper // loop the values and run bcadd foreach($array as $val) { - $value = bcadd($value, $val, $scale); + $value = bcadd($value, (string) $val, $scale); } return $value; } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/ObjectHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/ObjectHelper.php index e9b88eb7c..2646f7c37 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/ObjectHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/ObjectHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -37,6 +37,42 @@ abstract class ObjectHelper return false; } + + /** + * Compare two objects for equality based on their property values. + * + * Note that this method works only for simple objects that don't + * contain any nested objects or resource references. If you need + * to compare more complex objects, you may need to use a + * more advanced method such as serialization or reflection. + * + * @param object|null $obj1 The first object to compare. + * @param object|null $obj2 The second object to compare. + * + * @return bool True if the objects have the same key-value pairs and false otherwise. + */ + public static function equal(?object $obj1, ?object $obj2): bool + { + // if any is null we return false as that means there is a none object + // we are not comparing null but objects + // but we allow null as some objects while + // not instantiate are still null + if (is_null($obj1) || is_null($obj2)) + { + return false; + } + + // Convert the objects to arrays of their property values using get_object_vars. + $array1 = get_object_vars($obj1); + $array2 = get_object_vars($obj2); + + // Compare the arrays using array_diff_assoc to detect any differences. + $diff1 = array_diff_assoc($array1, $array2); + $diff2 = array_diff_assoc($array2, $array1); + + // If the arrays have the same key-value pairs, they will have no differences, so return true. + return empty($diff1) && empty($diff2); + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/ClassfunctionHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/ClassfunctionHelper.php index 91d17e030..42d21af3e 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/ClassfunctionHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/ClassfunctionHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities\String; @@ -31,16 +31,16 @@ abstract class ClassfunctionHelper * * @since 3.0.9 */ - public static function safe($name) + public static function safe($name): string { // remove numbers if the first character is a number - if (is_numeric(substr($name, 0, 1))) + if (is_numeric(substr((string) $name, 0, 1))) { $name = StringHelper::numbers($name); } // remove all spaces and strange characters - return trim(preg_replace("/[^A-Za-z0-9_-]/", '', $name)); + return trim(preg_replace("/[^A-Za-z0-9_-]/", '', (string) $name)); } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/FieldHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/FieldHelper.php index 5c039a8a9..00a44d2b3 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/FieldHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/FieldHelper.php @@ -1,18 +1,17 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities\String; -use Joomla\CMS\Component\ComponentHelper; use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Utilities\Component\Helper; @@ -57,13 +56,13 @@ abstract class FieldHelper if (StringHelper::check($string)) { // check that the first character is not a number - if (is_numeric(substr($string, 0, 1))) + if (is_numeric(substr((string)$string, 0, 1))) { $string = StringHelper::numbers($string); } // remove all other strange characters - $string = trim($string); + $string = trim((string) $string); $string = preg_replace('/'.$spacer.'+/', ' ', $string); $string = preg_replace('/\s+/', ' ', $string); @@ -71,10 +70,10 @@ abstract class FieldHelper $string = StringHelper::transliterate($string); // remove all and keep only characters and numbers - $string = preg_replace("/[^A-Za-z0-9 ]/", '', $string); + $string = preg_replace("/[^A-Za-z0-9 ]/", '', (string) $string); // replace white space with underscore (SAFEST OPTION) - $string = preg_replace('/\s+/', $spacer, $string); + $string = preg_replace('/\s+/', (string) $spacer, $string); // return all caps if ($allcap) @@ -97,7 +96,6 @@ abstract class FieldHelper // use the default (original behavior/convention) return StringHelper::safe($string); - } - + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/NamespaceHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/NamespaceHelper.php index f27544697..4776fb9fa 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/NamespaceHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/NamespaceHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities\String; @@ -25,35 +25,43 @@ abstract class NamespaceHelper /** * Making namespace safe * - * @input string The you would like to make safe + * @param string $string The namespace string you would like to make safe * - * @returns string on success - * + * @return string on success * @since 3.0.9 */ - public static function safe($string) + public static function safe(string $string): string { - // 0nly continue if we have a string - if (StringHelper::check($string)) + // Remove leading and trailing backslashes + $string = trim($string, '\\'); + + // Split the string into namespace segments + $segments = explode('\\', $string); + + foreach ($segments as &$segment) { - // make sure it has not numbers - $string = StringHelper::numbers($string); + // Check if segment starts with a number + if (preg_match("/^\d/", $segment)) + { + // Extract the starting number(s) + preg_match("/^\d+/", $segment, $matches); - // Transliterate string TODO: look again as this make it lowercase - // $string = StringHelper::transliterate($string); + if (isset($matches[0])) + { + $numberWord = StringHelper::numbers($matches[0]); + $segment = str_replace($matches[0], $numberWord, $segment); + } + } - // first remove all [\] backslashes - $string = str_replace('\\', '1', $string); + // Transliterate string TODO: look again as this makes it lowercase + // $segment = StringHelper::transliterate($segment); - // remove all and keep only characters and [\] backslashes inside of the string - $string = trim( preg_replace("/[^A-Za-z1]/", '', $string), '1'); - - // place the [\] backslashes back - return trim( preg_replace("/1+/", '\\', $string)); + // Make sure segment only contains valid characters + $segment = preg_replace("/[^A-Za-z0-9]/", '', $segment); } - // not a string - return ''; - } - + + // Join the namespace segments back together + return implode('\\', $segments); + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/PluginHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/PluginHelper.php index b170bdd57..1b31ffd78 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/PluginHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/PluginHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities\String; @@ -29,7 +29,7 @@ abstract class PluginHelper * * @since 3.0.9 */ - public static function safeFolderName($codeName, $group) + public static function safeFolderName(string $codeName, string $group): string { // editors-xtd group plugins must have a class with plgButton structure if ($group === 'editors-xtd') @@ -52,7 +52,7 @@ abstract class PluginHelper * * @since 3.0.9 */ - public static function safeClassName($codeName, $group) + public static function safeClassName(string $codeName, string $group): string { // editors-xtd group plugins must have a class with plgButton structure if ($group === 'editors-xtd') @@ -75,7 +75,7 @@ abstract class PluginHelper * * @since 3.0.9 */ - public static function safeInstallClassName($codeName, $group) + public static function safeInstallClassName(string $codeName, string $group): string { // editors-xtd group plugins must have a class with plgButton structure if ($group === 'editors-xtd') @@ -98,7 +98,7 @@ abstract class PluginHelper * * @since 3.0.9 */ - public static function safeLangPrefix($codeName, $group) + public static function safeLangPrefix(string $codeName, string $group): string { // editors-xtd group plugins must have a class with plgButton structure if ($group === 'editors-xtd') diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/TypeHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/TypeHelper.php index a173e8c9d..3c1554d4b 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/TypeHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/String/TypeHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities\String; @@ -65,7 +65,7 @@ abstract class TypeHelper $string = StringHelper::transliterate($string); // remove all and keep only characters and numbers and point (TODO just one point) - $string = trim(preg_replace("/[^A-Za-z0-9\.]/", '', $string)); + $string = trim(preg_replace("/[^A-Za-z0-9_\.]/", '', (string) $string)); // best is to return lower (for all string equality in compiler) return strtolower($string); diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/StringHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/StringHelper.php index ea533415f..3a37f2b9a 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/StringHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/StringHelper.php @@ -1,13 +1,13 @@ - * @git Joomla Component Builder - * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ +/** + * @package Joomla.Component.Builder + * + * @created 3rd September, 2020 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace VDM\Joomla\Utilities; @@ -44,12 +44,7 @@ abstract class StringHelper */ public static function check($string): bool { - if (is_string($string) && strlen($string) > 0) - { - return true; - } - - return false; + return is_string($string) && strlen($string) > 0; } /** @@ -65,8 +60,8 @@ abstract class StringHelper { if (self::check($string)) { - $initial = strlen($string); - $words = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE); + $initial = strlen((string) $string); + $words = preg_split('/([\s\n\r]+)/', (string) $string, null, PREG_SPLIT_DELIM_CAPTURE); $words_count = count((array)$words); $word_length = 0; @@ -82,12 +77,12 @@ abstract class StringHelper $newString = implode(array_slice($words, 0, $last_word)); $final = strlen($newString); - if ($initial != $final && $addTip) + if ($initial !== $final && $addTip) { $title = self::shorten($string, 400 , false); return '' . trim($newString) . '...'; } - elseif ($initial != $final && !$addTip) + elseif ($initial !== $final && !$addTip) { return trim($newString) . '...'; } @@ -118,7 +113,7 @@ abstract class StringHelper if ($type === 'filename') { // make sure VDM is not in the string - $string = str_replace('VDM', 'vDm', $string); + $string = str_replace('VDM', 'vDm', (string) $string); // Remove anything which isn't a word, whitespace, number // or any of the following caracters -_() // If you don't need to handle multi-byte characters @@ -128,10 +123,10 @@ abstract class StringHelper $string = preg_replace("([^\w\s\d\-_\(\)])", '', $string); // http://stackoverflow.com/a/2021729/1429677 - return preg_replace('/\s+/', ' ', $string); + return preg_replace('/\s+/', ' ', (string) $string); } // remove all other characters - $string = trim($string); + $string = trim((string) $string); $string = preg_replace('/'.$spacer.'+/', ' ', $string); $string = preg_replace('/\s+/', ' ', $string); // Transliterate string @@ -139,18 +134,18 @@ abstract class StringHelper // remove all and keep only characters if ($keepOnlyCharacters) { - $string = preg_replace("/[^A-Za-z ]/", '', $string); + $string = preg_replace("/[^A-Za-z ]/", '', (string) $string); } // keep both numbers and characters else { - $string = preg_replace("/[^A-Za-z0-9 ]/", '', $string); + $string = preg_replace("/[^A-Za-z0-9 ]/", '', (string) $string); } // select final adaptations if ($type === 'L' || $type === 'strtolower') { // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); + $string = preg_replace('/\s+/', (string) $spacer, (string) $string); // default is to return lower return strtolower($string); } @@ -177,14 +172,14 @@ abstract class StringHelper elseif ($type === 'U' || $type === 'strtoupper') { // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); + $string = preg_replace('/\s+/', (string) $spacer, $string); // return all upper return strtoupper($string); } elseif ($type === 'F' || $type === 'ucfirst') { // replace white space with underscore - $string = preg_replace('/\s+/', $spacer, $string); + $string = preg_replace('/\s+/', (string) $spacer, $string); // return with first character to upper return ucfirst(strtolower($string)); } @@ -237,7 +232,7 @@ abstract class StringHelper * * @since 3.0.9 */ - public static function html($var, $charset = 'UTF-8', $shorten = false, $length = 40) + public static function html($var, $charset = 'UTF-8', $shorten = false, $length = 40, $addTip = true) { if (self::check($var)) { @@ -245,7 +240,7 @@ abstract class StringHelper $string = $filter->clean( html_entity_decode( htmlentities( - $var, + (string) $var, ENT_COMPAT, $charset ) @@ -254,7 +249,7 @@ abstract class StringHelper ); if ($shorten) { - return self::shorten($string, $length); + return self::shorten($string, $length, $addTip); } return $string; } @@ -276,21 +271,22 @@ abstract class StringHelper public static function numbers($string) { // set numbers array - $numbers = array(); + $numbers = []; + $search_replace= []; // first get all numbers - preg_match_all('!\d+!', $string, $numbers); + preg_match_all('!\d+!', (string) $string, $numbers); // check if we have any numbers if (isset($numbers[0]) && ArrayHelper::check($numbers[0])) { foreach ($numbers[0] as $number) { - $searchReplace[$number] = self::number((int)$number); + $search_replace[$number] = self::number((int)$number); } // now replace numbers in string - $string = str_replace(array_keys($searchReplace), array_values($searchReplace), $string); + $string = str_replace(array_keys($search_replace), array_values($search_replace), (string) $string); // check if we missed any, strange if we did. return self::numbers($string); @@ -396,14 +392,15 @@ abstract class StringHelper /** * Random Key * + * @input int $size The size of the random string + * * @returns a string - * * @since 3.0.9 */ - public static function random($size) + public static function random(int $size): string { $bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ"; - $key = array(); + $key = []; $bagsize = strlen($bag) - 1; for ($i = 0; $i < $size; $i++) diff --git a/libraries/jcb_powers/VDM.Minify/index.html b/libraries/jcb_powers/VDM.Minify/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Minify/src/Abstraction/BasicException.php b/libraries/jcb_powers/VDM.Minify/src/Abstraction/BasicException.php new file mode 100644 index 000000000..f883162ec --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Abstraction/BasicException.php @@ -0,0 +1,26 @@ + + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +namespace VDM\Minify\Abstraction; + + +/** + * Basic exception. + * + * Please report bugs on https://github.com/matthiasmullie/minify/issues + * + * @author Matthias Mullie + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +abstract class BasicException extends \Exception +{ +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Abstraction/Minify.php b/libraries/jcb_powers/VDM.Minify/src/Abstraction/Minify.php new file mode 100644 index 000000000..23a9a450b --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Abstraction/Minify.php @@ -0,0 +1,513 @@ + + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ + +namespace VDM\Minify\Abstraction; + + +use VDM\Minify\Exceptions\IOException; +use VDM\Psr\Cache\CacheItemInterface; + + +/** + * Abstract minifier class. + * + * Please report bugs on https://github.com/matthiasmullie/minify/issues + * + * @author Matthias Mullie + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +abstract class Minify +{ + /** + * The data to be minified. + * + * @var string[] + */ + protected $data = []; + + /** + * Array of patterns to match. + * + * @var string[] + */ + protected $patterns = []; + + /** + * This array will hold content of strings and regular expressions that have + * been extracted from the JS source code, so we can reliably match "code", + * without having to worry about potential "code-like" characters inside. + * + * @internal + * + * @var string[] + */ + public $extracted = []; + + /** + * Init the minify class - optionally, code may be passed along already. + */ + public function __construct(/* $data = null, ... */) + { + // it's possible to add the source through the constructor as well ;) + if (func_num_args()) { + call_user_func_array(array($this, 'add'), func_get_args()); + } + } + + /** + * Add a file or straight-up code to be minified. + * + * @param string|string[] $data + * + * @return static + */ + public function add($data /* $data = null, ... */) + { + // bogus "usage" of parameter $data: scrutinizer warns this variable is + // not used (we're using func_get_args instead to support overloading), + // but it still needs to be defined because it makes no sense to have + // this function without argument :) + $args = array($data) + func_get_args(); + + // this method can be overloaded + foreach ($args as $data) { + if (is_array($data)) { + call_user_func_array(array($this, 'add'), $data); + continue; + } + + // redefine var + $data = (string) $data; + + // load data + $value = $this->load($data); + $key = ($data != $value) ? $data : count($this->data); + + // replace CR linefeeds etc. + // @see https://github.com/matthiasmullie/minify/pull/139 + $value = str_replace(array("\r\n", "\r"), "\n", $value); + + // store data + $this->data[$key] = $value; + } + + return $this; + } + + /** + * Add a file to be minified. + * + * @param string|string[] $data + * + * @return static + * + * @throws IOException + */ + public function addFile($data /* $data = null, ... */) + { + // bogus "usage" of parameter $data: scrutinizer warns this variable is + // not used (we're using func_get_args instead to support overloading), + // but it still needs to be defined because it makes no sense to have + // this function without argument :) + $args = array($data) + func_get_args(); + + // this method can be overloaded + foreach ($args as $path) { + if (is_array($path)) { + call_user_func_array(array($this, 'addFile'), $path); + continue; + } + + // redefine var + $path = (string) $path; + + // check if we can read the file + if (!$this->canImportFile($path)) { + throw new IOException('The file "' . $path . '" could not be opened for reading. Check if PHP has enough permissions.'); + } + + $this->add($path); + } + + return $this; + } + + /** + * Minify the data & (optionally) saves it to a file. + * + * @param string[optional] $path Path to write the data to + * + * @return string The minified data + */ + public function minify($path = null) + { + $content = $this->execute($path); + + // save to path + if ($path !== null) { + $this->save($content, $path); + } + + return $content; + } + + /** + * Minify & gzip the data & (optionally) saves it to a file. + * + * @param string[optional] $path Path to write the data to + * @param int[optional] $level Compression level, from 0 to 9 + * + * @return string The minified & gzipped data + */ + public function gzip($path = null, $level = 9) + { + $content = $this->execute($path); + $content = gzencode($content, $level, FORCE_GZIP); + + // save to path + if ($path !== null) { + $this->save($content, $path); + } + + return $content; + } + + /** + * Minify the data & write it to a CacheItemInterface object. + * + * @param CacheItemInterface $item Cache item to write the data to + * + * @return CacheItemInterface Cache item with the minifier data + */ + public function cache(CacheItemInterface $item) + { + $content = $this->execute(); + $item->set($content); + + return $item; + } + + /** + * Minify the data. + * + * @param string[optional] $path Path to write the data to + * + * @return string The minified data + */ + abstract public function execute($path = null); + + /** + * Load data. + * + * @param string $data Either a path to a file or the content itself + * + * @return string + */ + protected function load($data) + { + // check if the data is a file + if ($this->canImportFile($data)) { + $data = file_get_contents($data); + + // strip BOM, if any + if (substr($data, 0, 3) == "\xef\xbb\xbf") { + $data = substr($data, 3); + } + } + + return $data; + } + + /** + * Save to file. + * + * @param string $content The minified data + * @param string $path The path to save the minified data to + * + * @throws IOException + */ + protected function save($content, $path) + { + $handler = $this->openFileForWriting($path); + + $this->writeToFile($handler, $content); + + @fclose($handler); + } + + /** + * Register a pattern to execute against the source content. + * + * If $replacement is a string, it must be plain text. Placeholders like $1 or \2 don't work. + * If you need that functionality, use a callback instead. + * + * @param string $pattern PCRE pattern + * @param string|callable $replacement Replacement value for matched pattern + */ + protected function registerPattern($pattern, $replacement = '') + { + // study the pattern, we'll execute it more than once + $pattern .= 'S'; + + $this->patterns[] = array($pattern, $replacement); + } + + /** + * We can't "just" run some regular expressions against JavaScript: it's a + * complex language. E.g. having an occurrence of // xyz would be a comment, + * unless it's used within a string. Of you could have something that looks + * like a 'string', but inside a comment. + * The only way to accurately replace these pieces is to traverse the JS one + * character at a time and try to find whatever starts first. + * + * @param string $content The content to replace patterns in + * + * @return string The (manipulated) content + */ + protected function replace($content) + { + $contentLength = strlen($content); + $output = ''; + $processedOffset = 0; + $positions = array_fill(0, count($this->patterns), -1); + $matches = []; + + while ($processedOffset < $contentLength) { + // find first match for all patterns + foreach ($this->patterns as $i => $pattern) { + list($pattern, $replacement) = $pattern; + + // we can safely ignore patterns for positions we've unset earlier, + // because we know these won't show up anymore + if (array_key_exists($i, $positions) == false) { + continue; + } + + // no need to re-run matches that are still in the part of the + // content that hasn't been processed + if ($positions[$i] >= $processedOffset) { + continue; + } + + $match = null; + if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE, $processedOffset)) { + $matches[$i] = $match; + + // we'll store the match position as well; that way, we + // don't have to redo all preg_matches after changing only + // the first (we'll still know where those others are) + $positions[$i] = $match[0][1]; + } else { + // if the pattern couldn't be matched, there's no point in + // executing it again in later runs on this same content; + // ignore this one until we reach end of content + unset($matches[$i], $positions[$i]); + } + } + + // no more matches to find: everything's been processed, break out + if (!$matches) { + // output the remaining content + $output .= substr($content, $processedOffset); + break; + } + + // see which of the patterns actually found the first thing (we'll + // only want to execute that one, since we're unsure if what the + // other found was not inside what the first found) + $matchOffset = min($positions); + $firstPattern = array_search($matchOffset, $positions); + $match = $matches[$firstPattern]; + + // execute the pattern that matches earliest in the content string + list(, $replacement) = $this->patterns[$firstPattern]; + + // add the part of the input between $processedOffset and the first match; + // that content wasn't matched by anything + $output .= substr($content, $processedOffset, $matchOffset - $processedOffset); + // add the replacement for the match + $output .= $this->executeReplacement($replacement, $match); + // advance $processedOffset past the match + $processedOffset = $matchOffset + strlen($match[0][0]); + } + + return $output; + } + + /** + * If $replacement is a callback, execute it, passing in the match data. + * If it's a string, just pass it through. + * + * @param string|callable $replacement Replacement value + * @param array $match Match data, in PREG_OFFSET_CAPTURE form + * + * @return string + */ + protected function executeReplacement($replacement, $match) + { + if (!is_callable($replacement)) { + return $replacement; + } + // convert $match from the PREG_OFFSET_CAPTURE form to the form the callback expects + foreach ($match as &$matchItem) { + $matchItem = $matchItem[0]; + } + + return $replacement($match); + } + + /** + * Strings are a pattern we need to match, in order to ignore potential + * code-like content inside them, but we just want all of the string + * content to remain untouched. + * + * This method will replace all string content with simple STRING# + * placeholder text, so we've rid all strings from characters that may be + * misinterpreted. Original string content will be saved in $this->extracted + * and after doing all other minifying, we can restore the original content + * via restoreStrings(). + * + * @param string[optional] $chars + * @param string[optional] $placeholderPrefix + */ + protected function extractStrings($chars = '\'"', $placeholderPrefix = '') + { + // PHP only supports $this inside anonymous functions since 5.4 + $minifier = $this; + $callback = function ($match) use ($minifier, $placeholderPrefix) { + // check the second index here, because the first always contains a quote + if ($match[2] === '') { + /* + * Empty strings need no placeholder; they can't be confused for + * anything else anyway. + * But we still needed to match them, for the extraction routine + * to skip over this particular string. + */ + return $match[0]; + } + + $count = count($minifier->extracted); + $placeholder = $match[1] . $placeholderPrefix . $count . $match[1]; + $minifier->extracted[$placeholder] = $match[1] . $match[2] . $match[1]; + + return $placeholder; + }; + + /* + * The \\ messiness explained: + * * Don't count ' or " as end-of-string if it's escaped (has backslash + * in front of it) + * * Unless... that backslash itself is escaped (another leading slash), + * in which case it's no longer escaping the ' or " + * * So there can be either no backslash, or an even number + * * multiply all of that times 4, to account for the escaping that has + * to be done to pass the backslash into the PHP string without it being + * considered as escape-char (times 2) and to get it in the regex, + * escaped (times 2) + */ + $this->registerPattern('/([' . $chars . '])(.*?(?extracted. + * + * @param string $content + * + * @return string + */ + protected function restoreExtractedData($content) + { + if (!$this->extracted) { + // nothing was extracted, nothing to restore + return $content; + } + + $content = strtr($content, $this->extracted); + + $this->extracted = []; + + return $content; + } + + /** + * Check if the path is a regular file and can be read. + * + * @param string $path + * + * @return bool + */ + protected function canImportFile($path) + { + $parsed = parse_url($path); + if ( + // file is elsewhere + isset($parsed['host']) || + // file responds to queries (may change, or need to bypass cache) + isset($parsed['query']) + ) { + return false; + } + + return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path); + } + + /** + * Attempts to open file specified by $path for writing. + * + * @param string $path The path to the file + * + * @return resource Specifier for the target file + * + * @throws IOException + */ + protected function openFileForWriting($path) + { + if ($path === '' || ($handler = @fopen($path, 'w')) === false) { + throw new IOException('The file "' . $path . '" could not be opened for writing. Check if PHP has enough permissions.'); + } + + return $handler; + } + + /** + * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions. + * + * @param resource $handler The resource to write to + * @param string $content The content to write + * @param string $path The path to the file (for exception printing only) + * + * @throws IOException + */ + protected function writeToFile($handler, $content, $path = '') + { + if ( + !is_resource($handler) || + ($result = @fwrite($handler, $content)) === false || + ($result < strlen($content)) + ) { + throw new IOException('The file "' . $path . '" could not be written to. Check your disk space and file permissions.'); + } + } + + protected static function str_replace_first($search, $replace, $subject) + { + $pos = strpos((string) $subject, (string) $search); + if ($pos !== false) { + return substr_replace((string) $subject, (string) $replace, $pos, strlen((string) $search)); + } + + return $subject; + } +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Abstraction/index.html b/libraries/jcb_powers/VDM.Minify/src/Abstraction/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Abstraction/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Minify/src/Css.php b/libraries/jcb_powers/VDM.Minify/src/Css.php new file mode 100644 index 000000000..baee09933 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Css.php @@ -0,0 +1,754 @@ + + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +namespace VDM\Minify; + + +use VDM\Minify\Exceptions\FileImportException; +use VDM\Minify\Path\Converter; +use VDM\Minify\Path\Interfaces\ConverterInterface; +use VDM\Minify\Abstraction\Minify; + + +/** + * CSS minifier. + * + * Please report bugs on https://github.com/matthiasmullie/minify/issues + * + * @author Matthias Mullie + * @author Tijs Verkoyen + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +class Css extends Minify +{ + /** + * @var int maximum inport size in kB + */ + protected $maxImportSize = 5; + + /** + * @var string[] valid import extensions + */ + protected $importExtensions = array( + 'gif' => 'data:image/gif', + 'png' => 'data:image/png', + 'jpe' => 'data:image/jpeg', + 'jpg' => 'data:image/jpeg', + 'jpeg' => 'data:image/jpeg', + 'svg' => 'data:image/svg+xml', + 'woff' => 'data:application/x-font-woff', + 'woff2' => 'data:application/x-font-woff2', + 'avif' => 'data:image/avif', + 'apng' => 'data:image/apng', + 'webp' => 'data:image/webp', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'xbm' => 'image/x-xbitmap', + ); + + /** + * Set the maximum size if files to be imported. + * + * Files larger than this size (in kB) will not be imported into the CSS. + * Importing files into the CSS as data-uri will save you some connections, + * but we should only import relatively small decorative images so that our + * CSS file doesn't get too bulky. + * + * @param int $size Size in kB + */ + public function setMaxImportSize($size) + { + $this->maxImportSize = $size; + } + + /** + * Set the type of extensions to be imported into the CSS (to save network + * connections). + * Keys of the array should be the file extensions & respective values + * should be the data type. + * + * @param string[] $extensions Array of file extensions + */ + public function setImportExtensions(array $extensions) + { + $this->importExtensions = $extensions; + } + + /** + * Move any import statements to the top. + * + * @param string $content Nearly finished CSS content + * + * @return string + */ + protected function moveImportsToTop($content) + { + if (preg_match_all('/(;?)(@import (?url\()?(?P["\']?).+?(?P=quotes)(?(url)\)));?/', $content, $matches)) { + // remove from content + foreach ($matches[0] as $import) { + $content = str_replace($import, '', $content); + } + + // add to top + $content = implode(';', $matches[2]) . ';' . trim($content, ';'); + } + + return $content; + } + + /** + * Combine CSS from import statements. + * + * Import statements will be loaded and their content merged into the original + * file, to save HTTP requests. + * + * @param string $source The file to combine imports for + * @param string $content The CSS content to combine imports for + * @param string[] $parents Parent paths, for circular reference checks + * + * @return string + * + * @throws FileImportException + */ + protected function combineImports($source, $content, $parents) + { + $importRegexes = array( + // @import url(xxx) + '/ + # import statement + @import + # whitespace + \s+ + # open url() + url\( + # (optional) open path enclosure + (?P["\']?) + # fetch path + (?P.+?) + # (optional) close path enclosure + (?P=quotes) + # close url() + \) + # (optional) trailing whitespace + \s* + # (optional) media statement(s) + (?P[^;]*) + # (optional) trailing whitespace + \s* + # (optional) closing semi-colon + ;? + /ix', + + // @import 'xxx' + '/ + # import statement + @import + # whitespace + \s+ + # open path enclosure + (?P["\']) + # fetch path + (?P.+?) + # close path enclosure + (?P=quotes) + # (optional) trailing whitespace + \s* + # (optional) media statement(s) + (?P[^;]*) + # (optional) trailing whitespace + \s* + # (optional) closing semi-colon + ;? + /ix', + ); + + // find all relative imports in css + $matches = []; + foreach ($importRegexes as $importRegex) { + if (preg_match_all($importRegex, $content, $regexMatches, PREG_SET_ORDER)) { + $matches = [...$matches, ...$regexMatches]; + } + } + + $search = []; + $replace = []; + + // loop the matches + foreach ($matches as $match) { + // get the path for the file that will be imported + $importPath = dirname($source) . '/' . $match['path']; + + // only replace the import with the content if we can grab the + // content of the file + if (!$this->canImportByPath($match['path']) || !$this->canImportFile($importPath)) { + continue; + } + + // check if current file was not imported previously in the same + // import chain. + if (in_array($importPath, $parents)) { + throw new FileImportException('Failed to import file "' . $importPath . '": circular reference detected.'); + } + + // grab referenced file & minify it (which may include importing + // yet other @import statements recursively) + $minifier = new self($importPath); + $minifier->setMaxImportSize($this->maxImportSize); + $minifier->setImportExtensions($this->importExtensions); + $importContent = $minifier->execute($source, $parents); + + // check if this is only valid for certain media + if (!empty($match['media'])) { + $importContent = '@media ' . $match['media'] . '{' . $importContent . '}'; + } + + // add to replacement array + $search[] = $match[0]; + $replace[] = $importContent; + } + + // replace the import statements + return str_replace($search, $replace, $content); + } + + /** + * Import files into the CSS, base64-ized. + * + * @url(image.jpg) images will be loaded and their content merged into the + * original file, to save HTTP requests. + * + * @param string $source The file to import files for + * @param string $content The CSS content to import files for + * + * @return string + */ + protected function importFiles($source, $content) + { + $regex = '/url\((["\']?)(.+?)\\1\)/i'; + if ($this->importExtensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { + $search = []; + $replace = []; + + // loop the matches + foreach ($matches as $match) { + $extension = substr(strrchr($match[2], '.'), 1); + if ($extension && !array_key_exists($extension, $this->importExtensions)) { + continue; + } + + // get the path for the file that will be imported + $path = $match[2]; + $path = dirname($source) . '/' . $path; + + // only replace the import with the content if we're able to get + // the content of the file, and it's relatively small + if ($this->canImportFile($path) && $this->canImportBySize($path)) { + // grab content && base64-ize + $importContent = $this->load($path); + $importContent = base64_encode($importContent); + + // build replacement + $search[] = $match[0]; + $replace[] = 'url(' . $this->importExtensions[$extension] . ';base64,' . $importContent . ')'; + } + } + + // replace the import statements + $content = str_replace($search, $replace, $content); + } + + return $content; + } + + /** + * Minify the data. + * Perform CSS optimizations. + * + * @param string[optional] $path Path to write the data to + * @param string[] $parents Parent paths, for circular reference checks + * + * @return string The minified data + */ + public function execute($path = null, $parents = []) + { + $content = ''; + + // loop CSS data (raw data and files) + foreach ($this->data as $source => $css) { + /* + * Let's first take out strings & comments, since we can't just + * remove whitespace anywhere. If whitespace occurs inside a string, + * we should leave it alone. E.g.: + * p { content: "a test" } + */ + $this->extractStrings(); + $this->stripComments(); + $this->extractMath(); + $this->extractCustomProperties(); + $css = $this->replace($css); + + $css = $this->stripWhitespace($css); + $css = $this->shortenColors($css); + $css = $this->shortenZeroes($css); + $css = $this->shortenFontWeights($css); + $css = $this->stripEmptyTags($css); + + // restore the string we've extracted earlier + $css = $this->restoreExtractedData($css); + + $source = is_int($source) ? '' : $source; + $parents = $source ? array_merge($parents, array($source)) : $parents; + $css = $this->combineImports($source, $css, $parents); + $css = $this->importFiles($source, $css); + + /* + * If we'll save to a new path, we'll have to fix the relative paths + * to be relative no longer to the source file, but to the new path. + * If we don't write to a file, fall back to same path so no + * conversion happens (because we still want it to go through most + * of the move code, which also addresses url() & @import syntax...) + */ + $converter = $this->getPathConverter($source, $path ?: $source); + $css = $this->move($converter, $css); + + // combine css + $content .= $css; + } + + $content = $this->moveImportsToTop($content); + + return $content; + } + + /** + * Moving a css file should update all relative urls. + * Relative references (e.g. ../images/image.gif) in a certain css file, + * will have to be updated when a file is being saved at another location + * (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper). + * + * @param ConverterInterface $converter Relative path converter + * @param string $content The CSS content to update relative urls for + * + * @return string + */ + protected function move(ConverterInterface $converter, $content) + { + /* + * Relative path references will usually be enclosed by url(). @import + * is an exception, where url() is not necessary around the path (but is + * allowed). + * This *could* be 1 regular expression, where both regular expressions + * in this array are on different sides of a |. But we're using named + * patterns in both regexes, the same name on both regexes. This is only + * possible with a (?J) modifier, but that only works after a fairly + * recent PCRE version. That's why I'm doing 2 separate regular + * expressions & combining the matches after executing of both. + */ + $relativeRegexes = array( + // url(xxx) + '/ + # open url() + url\( + \s* + # open path enclosure + (?P["\'])? + # fetch path + (?P.+?) + # close path enclosure + (?(quotes)(?P=quotes)) + \s* + # close url() + \) + /ix', + + // @import "xxx" + '/ + # import statement + @import + # whitespace + \s+ + # we don\'t have to check for @import url(), because the + # condition above will already catch these + # open path enclosure + (?P["\']) + # fetch path + (?P.+?) + # close path enclosure + (?P=quotes) + /ix', + ); + + // find all relative urls in css + $matches = []; + foreach ($relativeRegexes as $relativeRegex) { + if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) { + $matches = [...$matches, ...$regexMatches]; + } + } + + $search = []; + $replace = []; + + // loop all urls + foreach ($matches as $match) { + // determine if it's a url() or an @import match + $type = (strpos($match[0], '@import') === 0 ? 'import' : 'url'); + + $url = $match['path']; + if ($this->canImportByPath($url)) { + // attempting to interpret GET-params makes no sense, so let's discard them for awhile + $params = strrchr($url, '?'); + $url = $params ? substr($url, 0, -strlen($params)) : $url; + + // fix relative url + $url = $converter->convert($url); + + // now that the path has been converted, re-apply GET-params + $url .= $params; + } + + /* + * Urls with control characters above 0x7e should be quoted. + * According to Mozilla's parser, whitespace is only allowed at the + * end of unquoted urls. + * Urls with `)` (as could happen with data: uris) should also be + * quoted to avoid being confused for the url() closing parentheses. + * And urls with a # have also been reported to cause issues. + * Urls with quotes inside should also remain escaped. + * + * @see https://developer.mozilla.org/nl/docs/Web/CSS/url#The_url()_functional_notation + * @see https://hg.mozilla.org/mozilla-central/rev/14abca4e7378 + * @see https://github.com/matthiasmullie/minify/issues/193 + */ + $url = trim($url); + if (preg_match('/[\s\)\'"#\x{7f}-\x{9f}]/u', $url)) { + $url = $match['quotes'] . $url . $match['quotes']; + } + + // build replacement + $search[] = $match[0]; + if ($type === 'url') { + $replace[] = 'url(' . $url . ')'; + } elseif ($type === 'import') { + $replace[] = '@import "' . $url . '"'; + } + } + + // replace urls + return str_replace($search, $replace, $content); + } + + /** + * Shorthand hex color codes. + * #FF0000 -> #F00. + * + * @param string $content The CSS content to shorten the hex color codes for + * + * @return string + */ + protected function shortenColors($content) + { + $content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?:([0-9a-z])\\4)?(?=[; }])/i', '#$1$2$3$4', $content); + + // remove alpha channel if it's pointless... + $content = preg_replace('/(?<=[: ])#([0-9a-z]{6})ff?(?=[; }])/i', '#$1', $content); + $content = preg_replace('/(?<=[: ])#([0-9a-z]{3})f?(?=[; }])/i', '#$1', $content); + + $colors = array( + // we can shorten some even more by replacing them with their color name + '#F0FFFF' => 'azure', + '#F5F5DC' => 'beige', + '#A52A2A' => 'brown', + '#FF7F50' => 'coral', + '#FFD700' => 'gold', + '#808080' => 'gray', + '#008000' => 'green', + '#4B0082' => 'indigo', + '#FFFFF0' => 'ivory', + '#F0E68C' => 'khaki', + '#FAF0E6' => 'linen', + '#800000' => 'maroon', + '#000080' => 'navy', + '#808000' => 'olive', + '#CD853F' => 'peru', + '#FFC0CB' => 'pink', + '#DDA0DD' => 'plum', + '#800080' => 'purple', + '#F00' => 'red', + '#FA8072' => 'salmon', + '#A0522D' => 'sienna', + '#C0C0C0' => 'silver', + '#FFFAFA' => 'snow', + '#D2B48C' => 'tan', + '#FF6347' => 'tomato', + '#EE82EE' => 'violet', + '#F5DEB3' => 'wheat', + // or the other way around + 'WHITE' => '#fff', + 'BLACK' => '#000', + ); + + return preg_replace_callback( + '/(?<=[: ])(' . implode('|', array_keys($colors)) . ')(?=[; }])/i', + fn($match) => $colors[strtoupper((string) $match[0])], + $content + ); + } + + /** + * Shorten CSS font weights. + * + * @param string $content The CSS content to shorten the font weights for + * + * @return string + */ + protected function shortenFontWeights($content) + { + $weights = array( + 'normal' => 400, + 'bold' => 700, + ); + + $callback = fn($match) => $match[1] . $weights[$match[2]]; + + return preg_replace_callback('/(font-weight\s*:\s*)(' . implode('|', array_keys($weights)) . ')(?=[;}])/', $callback, $content); + } + + /** + * Shorthand 0 values to plain 0, instead of e.g. -0em. + * + * @param string $content The CSS content to shorten the zero values for + * + * @return string + */ + protected function shortenZeroes($content) + { + // we don't want to strip units in `calc()` expressions: + // `5px - 0px` is valid, but `5px - 0` is not + // `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but + // `10 * 0` is invalid + // we've extracted calcs earlier, so we don't need to worry about this + + // reusable bits of code throughout these regexes: + // before & after are used to make sure we don't match lose unintended + // 0-like values (e.g. in #000, or in http://url/1.0) + // units can be stripped from 0 values, or used to recognize non 0 + // values (where wa may be able to strip a .0 suffix) + $before = '(?<=[:(, ])'; + $after = '(?=[ ,);}])'; + $units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)'; + + // strip units after zeroes (0px -> 0) + // NOTE: it should be safe to remove all units for a 0 value, but in + // practice, Webkit (especially Safari) seems to stumble over at least + // 0%, potentially other units as well. Only stripping 'px' for now. + // @see https://github.com/matthiasmullie/minify/issues/60 + $content = preg_replace('/' . $before . '(-?0*(\.0+)?)(?<=0)px' . $after . '/', '\\1', $content); + + // strip 0-digits (.0 -> 0) + $content = preg_replace('/' . $before . '\.0+' . $units . '?' . $after . '/', '0\\1', $content); + // strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px + $content = preg_replace('/' . $before . '(-?[0-9]+\.[0-9]+)0+' . $units . '?' . $after . '/', '\\1\\2', $content); + // strip trailing 0: 50.00 -> 50, 50.00px -> 50px + $content = preg_replace('/' . $before . '(-?[0-9]+)\.0+' . $units . '?' . $after . '/', '\\1\\2', $content); + // strip leading 0: 0.1 -> .1, 01.1 -> 1.1 + $content = preg_replace('/' . $before . '(-?)0+([0-9]*\.[0-9]+)' . $units . '?' . $after . '/', '\\1\\2\\3', $content); + + // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0) + $content = preg_replace('/' . $before . '-?0+' . $units . '?' . $after . '/', '0\\1', $content); + + // IE doesn't seem to understand a unitless flex-basis value (correct - + // it goes against the spec), so let's add it in again (make it `%`, + // which is only 1 char: 0%, 0px, 0 anything, it's all just the same) + // @see https://developer.mozilla.org/nl/docs/Web/CSS/flex + $content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content); + $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content); + + return $content; + } + + /** + * Strip empty tags from source code. + * + * @param string $content + * + * @return string + */ + protected function stripEmptyTags($content) + { + $content = preg_replace('/(?<=^)[^\{\};]+\{\s*\}/', '', $content); + $content = preg_replace('/(?<=(\}|;))[^\{\};]+\{\s*\}/', '', $content); + + return $content; + } + + /** + * Strip comments from source code. + */ + protected function stripComments() + { + // PHP only supports $this inside anonymous functions since 5.4 + $minifier = $this; + $callback = function ($match) use ($minifier) { + $count = count($minifier->extracted); + $placeholder = '/*' . $count . '*/'; + $minifier->extracted[$placeholder] = $match[0]; + + return $placeholder; + }; + $this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback); + + $this->registerPattern('/\/\*.*?\*\//s', ''); + } + + /** + * Strip whitespace. + * + * @param string $content The CSS content to strip the whitespace for + * + * @return string + */ + protected function stripWhitespace($content) + { + // remove leading & trailing whitespace + $content = preg_replace('/^\s*/m', '', $content); + $content = preg_replace('/\s*$/m', '', $content); + + // replace newlines with a single space + $content = preg_replace('/\s+/', ' ', $content); + + // remove whitespace around meta characters + // inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex + $content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content); + $content = preg_replace('/([\[(:>\+])\s+/', '$1', $content); + $content = preg_replace('/\s+([\]\)>\+])/', '$1', $content); + $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content); + + // whitespace around + and - can only be stripped inside some pseudo- + // classes, like `:nth-child(3+2n)` + // not in things like `calc(3px + 2px)`, shorthands like `3px -2px`, or + // selectors like `div.weird- p` + $pseudos = array('nth-child', 'nth-last-child', 'nth-last-of-type', 'nth-of-type'); + $content = preg_replace('/:(' . implode('|', $pseudos) . ')\(\s*([+-]?)\s*(.+?)\s*([+-]?)\s*(.*?)\s*\)/', ':$1($2$3$4$5)', $content); + + // remove semicolon/whitespace followed by closing bracket + $content = str_replace(';}', '}', $content); + + return trim($content); + } + + /** + * Replace all occurrences of functions that may contain math, where + * whitespace around operators needs to be preserved (e.g. calc, clamp). + */ + protected function extractMath() + { + $functions = array('calc', 'clamp', 'min', 'max'); + $pattern = '/\b(' . implode('|', $functions) . ')(\(.+?)(?=$|;|})/m'; + + // PHP only supports $this inside anonymous functions since 5.4 + $minifier = $this; + $callback = function ($match) use ($minifier, $pattern, &$callback) { + $function = $match[1]; + $length = strlen((string) $match[2]); + $expr = ''; + $opened = 0; + + // the regular expression for extracting math has 1 significant problem: + // it can't determine the correct closing parenthesis... + // instead, it'll match a larger portion of code to where it's certain that + // the calc() musts have ended, and we'll figure out which is the correct + // closing parenthesis here, by counting how many have opened + for ($i = 0; $i < $length; ++$i) { + $char = $match[2][$i]; + $expr .= $char; + if ($char === '(') { + ++$opened; + } elseif ($char === ')' && --$opened === 0) { + break; + } + } + + // now that we've figured out where the calc() starts and ends, extract it + $count = count($minifier->extracted); + $placeholder = 'math(' . $count . ')'; + $minifier->extracted[$placeholder] = $function . '(' . trim(substr($expr, 1, -1)) . ')'; + + // and since we've captured more code than required, we may have some leftover + // calc() in here too - go recursive on the remaining but of code to go figure + // that out and extract what is needed + $rest = $minifier->str_replace_first($function . $expr, '', $match[0]); + $rest = preg_replace_callback($pattern, $callback, $rest); + + return $placeholder . $rest; + }; + + $this->registerPattern($pattern, $callback); + } + + /** + * Replace custom properties, whose values may be used in scenarios where + * we wouldn't want them to be minified (e.g. inside calc). + */ + protected function extractCustomProperties() + { + // PHP only supports $this inside anonymous functions since 5.4 + $minifier = $this; + $this->registerPattern( + '/(?<=^|[;}{])\s*(--[^:;{}"\'\s]+)\s*:([^;{}]+)/m', + function ($match) use ($minifier) { + $placeholder = '--custom-' . count($minifier->extracted) . ':0'; + $minifier->extracted[$placeholder] = $match[1] . ':' . trim((string) $match[2]); + + return $placeholder; + } + ); + } + + /** + * Check if file is small enough to be imported. + * + * @param string $path The path to the file + * + * @return bool + */ + protected function canImportBySize($path) + { + return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024; + } + + /** + * Check if file a file can be imported, going by the path. + * + * @param string $path + * + * @return bool + */ + protected function canImportByPath($path) + { + return preg_match('/^(data:|https?:|\\/)/', $path) === 0; + } + + /** + * Return a converter to update relative paths to be relative to the new + * destination. + * + * @param string $source + * @param string $target + * + * @return ConverterInterface + */ + protected function getPathConverter($source, $target) + { + return new Converter($source, $target); + } +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Exceptions/FileImportException.php b/libraries/jcb_powers/VDM.Minify/src/Exceptions/FileImportException.php new file mode 100644 index 000000000..73be9bb71 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Exceptions/FileImportException.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +namespace VDM\Minify\Exceptions; + + +use VDM\Minify\Abstraction\BasicException; + + +/** + * File Import Exception Class. + * + * @author Matthias Mullie + */ +class FileImportException extends BasicException +{ +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Exceptions/IOException.php b/libraries/jcb_powers/VDM.Minify/src/Exceptions/IOException.php new file mode 100644 index 000000000..11bd955df --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Exceptions/IOException.php @@ -0,0 +1,25 @@ + + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +namespace VDM\Minify\Exceptions; + + +use VDM\Minify\Abstraction\BasicException; + + +/** + * IO Exception Class. + * + * @author Matthias Mullie + */ +class IOException extends BasicException +{ +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Exceptions/index.html b/libraries/jcb_powers/VDM.Minify/src/Exceptions/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Exceptions/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/helpers/js.php b/libraries/jcb_powers/VDM.Minify/src/JavaScript.php similarity index 57% rename from admin/helpers/js.php rename to libraries/jcb_powers/VDM.Minify/src/JavaScript.php index 47d0f75cd..fd226d31b 100644 --- a/admin/helpers/js.php +++ b/libraries/jcb_powers/VDM.Minify/src/JavaScript.php @@ -1,64 +1,116 @@ - @github Joomla Component Builder - @copyright Copyright (C) 2015. All Rights Reserved - @license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html - - Builds Complex Joomla Components - -/-----------------------------------------------------------------------------------------------------------------------------*/ - -// No direct access to this file -defined('_JEXEC') or die('Restricted access'); - -require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/minify.php'; - /** * JavaScript minifier. * * Please report bugs on https://github.com/matthiasmullie/minify/issues * * @author Matthias Mullie - * @author Tijs Verkoyen - * - * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved. + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved * @license MIT License - */ -class JS extends Minify -{ + */ +namespace VDM\Minify; + + +use VDM\Minify\Abstraction\Minify; + + +/** + * JavaScript Minifier Class. + * + * Please report bugs on https://github.com/matthiasmullie/minify/issues + * + * @author Matthias Mullie + * @author Tijs Verkoyen + * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved + * @license MIT License + */ +class JavaScript extends Minify +{ /** - * Var-matching regex based on http://stackoverflow.com/a/9337047/802993 + * Var-matching regex based on http://stackoverflow.com/a/9337047/802993. * * Note that regular expressions using that bit must have the PCRE_UTF8 * pattern modifier (/u) set. * + * @internal + * * @var string */ const REGEX_VARIABLE = '\b[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}0-9\x{0300}-\x{036f}\x{0483}-\x{0487}\x{0591}-\x{05bd}\x{05bf}\x{05c1}\x{05c2}\x{05c4}\x{05c5}\x{05c7}\x{0610}-\x{061a}\x{064b}-\x{0669}\x{0670}\x{06d6}-\x{06dc}\x{06df}-\x{06e4}\x{06e7}\x{06e8}\x{06ea}-\x{06ed}\x{06f0}-\x{06f9}\x{0711}\x{0730}-\x{074a}\x{07a6}-\x{07b0}\x{07c0}-\x{07c9}\x{07eb}-\x{07f3}\x{0816}-\x{0819}\x{081b}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082d}\x{0859}-\x{085b}\x{08e4}-\x{08fe}\x{0900}-\x{0903}\x{093a}-\x{093c}\x{093e}-\x{094f}\x{0951}-\x{0957}\x{0962}\x{0963}\x{0966}-\x{096f}\x{0981}-\x{0983}\x{09bc}\x{09be}-\x{09c4}\x{09c7}\x{09c8}\x{09cb}-\x{09cd}\x{09d7}\x{09e2}\x{09e3}\x{09e6}-\x{09ef}\x{0a01}-\x{0a03}\x{0a3c}\x{0a3e}-\x{0a42}\x{0a47}\x{0a48}\x{0a4b}-\x{0a4d}\x{0a51}\x{0a66}-\x{0a71}\x{0a75}\x{0a81}-\x{0a83}\x{0abc}\x{0abe}-\x{0ac5}\x{0ac7}-\x{0ac9}\x{0acb}-\x{0acd}\x{0ae2}\x{0ae3}\x{0ae6}-\x{0aef}\x{0b01}-\x{0b03}\x{0b3c}\x{0b3e}-\x{0b44}\x{0b47}\x{0b48}\x{0b4b}-\x{0b4d}\x{0b56}\x{0b57}\x{0b62}\x{0b63}\x{0b66}-\x{0b6f}\x{0b82}\x{0bbe}-\x{0bc2}\x{0bc6}-\x{0bc8}\x{0bca}-\x{0bcd}\x{0bd7}\x{0be6}-\x{0bef}\x{0c01}-\x{0c03}\x{0c3e}-\x{0c44}\x{0c46}-\x{0c48}\x{0c4a}-\x{0c4d}\x{0c55}\x{0c56}\x{0c62}\x{0c63}\x{0c66}-\x{0c6f}\x{0c82}\x{0c83}\x{0cbc}\x{0cbe}-\x{0cc4}\x{0cc6}-\x{0cc8}\x{0cca}-\x{0ccd}\x{0cd5}\x{0cd6}\x{0ce2}\x{0ce3}\x{0ce6}-\x{0cef}\x{0d02}\x{0d03}\x{0d3e}-\x{0d44}\x{0d46}-\x{0d48}\x{0d4a}-\x{0d4d}\x{0d57}\x{0d62}\x{0d63}\x{0d66}-\x{0d6f}\x{0d82}\x{0d83}\x{0dca}\x{0dcf}-\x{0dd4}\x{0dd6}\x{0dd8}-\x{0ddf}\x{0df2}\x{0df3}\x{0e31}\x{0e34}-\x{0e3a}\x{0e47}-\x{0e4e}\x{0e50}-\x{0e59}\x{0eb1}\x{0eb4}-\x{0eb9}\x{0ebb}\x{0ebc}\x{0ec8}-\x{0ecd}\x{0ed0}-\x{0ed9}\x{0f18}\x{0f19}\x{0f20}-\x{0f29}\x{0f35}\x{0f37}\x{0f39}\x{0f3e}\x{0f3f}\x{0f71}-\x{0f84}\x{0f86}\x{0f87}\x{0f8d}-\x{0f97}\x{0f99}-\x{0fbc}\x{0fc6}\x{102b}-\x{103e}\x{1040}-\x{1049}\x{1056}-\x{1059}\x{105e}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106d}\x{1071}-\x{1074}\x{1082}-\x{108d}\x{108f}-\x{109d}\x{135d}-\x{135f}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17d3}\x{17dd}\x{17e0}-\x{17e9}\x{180b}-\x{180d}\x{1810}-\x{1819}\x{18a9}\x{1920}-\x{192b}\x{1930}-\x{193b}\x{1946}-\x{194f}\x{19b0}-\x{19c0}\x{19c8}\x{19c9}\x{19d0}-\x{19d9}\x{1a17}-\x{1a1b}\x{1a55}-\x{1a5e}\x{1a60}-\x{1a7c}\x{1a7f}-\x{1a89}\x{1a90}-\x{1a99}\x{1b00}-\x{1b04}\x{1b34}-\x{1b44}\x{1b50}-\x{1b59}\x{1b6b}-\x{1b73}\x{1b80}-\x{1b82}\x{1ba1}-\x{1bad}\x{1bb0}-\x{1bb9}\x{1be6}-\x{1bf3}\x{1c24}-\x{1c37}\x{1c40}-\x{1c49}\x{1c50}-\x{1c59}\x{1cd0}-\x{1cd2}\x{1cd4}-\x{1ce8}\x{1ced}\x{1cf2}-\x{1cf4}\x{1dc0}-\x{1de6}\x{1dfc}-\x{1dff}\x{200c}\x{200d}\x{203f}\x{2040}\x{2054}\x{20d0}-\x{20dc}\x{20e1}\x{20e5}-\x{20f0}\x{2cef}-\x{2cf1}\x{2d7f}\x{2de0}-\x{2dff}\x{302a}-\x{302f}\x{3099}\x{309a}\x{a620}-\x{a629}\x{a66f}\x{a674}-\x{a67d}\x{a69f}\x{a6f0}\x{a6f1}\x{a802}\x{a806}\x{a80b}\x{a823}-\x{a827}\x{a880}\x{a881}\x{a8b4}-\x{a8c4}\x{a8d0}-\x{a8d9}\x{a8e0}-\x{a8f1}\x{a900}-\x{a909}\x{a926}-\x{a92d}\x{a947}-\x{a953}\x{a980}-\x{a983}\x{a9b3}-\x{a9c0}\x{a9d0}-\x{a9d9}\x{aa29}-\x{aa36}\x{aa43}\x{aa4c}\x{aa4d}\x{aa50}-\x{aa59}\x{aa7b}\x{aab0}\x{aab2}-\x{aab4}\x{aab7}\x{aab8}\x{aabe}\x{aabf}\x{aac1}\x{aaeb}-\x{aaef}\x{aaf5}\x{aaf6}\x{abe3}-\x{abea}\x{abec}\x{abed}\x{abf0}-\x{abf9}\x{fb1e}\x{fe00}-\x{fe0f}\x{fe20}-\x{fe26}\x{fe33}\x{fe34}\x{fe4d}-\x{fe4f}\x{ff10}-\x{ff19}\x{ff3f}]*\b'; /** * Full list of JavaScript reserved words. - * Will be loaded from /data/js/keywords_reserved.txt + * Will be loaded from /data/js/keywords_reserved.txt. * * @see https://mathiasbynens.be/notes/reserved-keywords + * * @var string[] */ - protected $keywordsReserved = array(); + protected $keywordsReserved = [ + 'do', + 'if', + 'in', + 'for', + 'let', + 'new', + 'try', + 'var', + 'case', + 'else', + 'enum', + 'eval', + 'null', + 'this', + 'true', + 'void', + 'with', + 'break', + 'catch', + 'class', + 'const', + 'false', + 'super', + 'throw', + 'while', + 'yield', + 'delete', + 'export', + 'import', + 'public', + 'return', + 'static', + 'switch', + 'typeof', + 'default', + 'extends', + 'finally', + 'package', + 'private', + 'continue', + 'debugger', + 'function', + 'arguments', + 'interface', + 'protected', + 'implements', + 'instanceof', + 'abstract', + 'boolean', + 'byte', + 'char', + 'double', + 'final', + 'float', + 'goto', + 'int', + 'long', + 'native', + 'short', + 'synchronized', + 'throws', + 'transient', + 'volatile' + ]; /** * List of JavaScript reserved words that accept a @@ -73,7 +125,34 @@ class JS extends Minify * * @var string[] */ - protected $keywordsBefore = array(); + protected $keywordsBefore = [ + 'do', + 'in', + 'let', + 'new', + 'var', + 'case', + 'else', + 'enum', + 'void', + 'with', + 'class', + 'const', + 'yield', + 'delete', + 'export', + 'import', + 'public', + 'static', + 'typeof', + 'extends', + 'package', + 'private', + 'function', + 'protected', + 'implements', + 'instanceof' + ]; /** * List of JavaScript reserved words that accept a @@ -88,31 +167,141 @@ class JS extends Minify * * @var string[] */ - protected $keywordsAfter = array(); + protected $keywordsAfter = [ + 'in', + 'public', + 'extends', + 'private', + 'protected', + 'implements', + 'instanceof' + ]; + + /** + * List of all JavaScript operators. + * + * Will be loaded from /data/js/operators.txt + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators + * + * @var string[] + */ + protected $operators = [ + '+', + '-', + '*', + '/', + '%', + '=', + '+=', + '-=', + '*=', + '/=', + '%=', + '<<=', + '>>=', + '>>>=', + '&=', + '^=', + '|=', + '&', + '|', + '^', + '~', + '<<', + '>>', + '>>>', + '==', + '===', + '!=', + '!==', + '>', + '<', + '>=', + '<=', + '&&', + '||', + '!', + '.', + '[', + ']', + '?', + ':', + ',', + ';', + '(', + ')', + '{', + '}' + ]; /** * List of JavaScript operators that accept a after * them. Some end of lines are not the end of a statement, like with these * operators. - * - * Note: Most operators are fine, we've only removed !, ++ and --. - * There can't be a newline separating ! and whatever it is negating. + * Note: Most operators are fine, we've only removed ++ and --. * ++ & -- have to be joined with the value they're in-/decrementing. * * Will be loaded from /data/js/operators_before.txt * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators + * * @var string[] */ - protected $operatorsBefore = array(); + protected $operatorsBefore = [ + '+', + '-', + '*', + '/', + '%', + '=', + '+=', + '-=', + '*=', + '/=', + '%=', + '<<=', + '>>=', + '>>>=', + '&=', + '^=', + '|=', + '&', + '|', + '^', + '~', + '<<', + '>>', + '>>>', + '==', + '===', + '!=', + '!==', + '>', + '<', + '>=', + '<=', + '&&', + '||', + '!', + '.', + '[', + '?', + ':', + ',', + ';', + '(', + '{', + ]; /** * List of JavaScript operators that accept a before * them. Some end of lines are not the end of a statement, like when * continued by one of these operators on the newline. * - * Note: Most operators are fine, we've only removed ), ], ++ and --. + * Note: Most operators are fine, we've only removed ), ], ++, --, ! and ~. + * There can't be a newline separating ! or ~ and whatever it is negating. * ++ & -- have to be joined with the value they're in-/decrementing. * ) & ] are "special" in that they have lots or usecases. () for example * is used for function calls, for grouping, in if () and for (), ... @@ -120,50 +309,67 @@ class JS extends Minify * Will be loaded from /data/js/operators_after.txt * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators + * * @var string[] */ - protected $operatorsAfter = array(); - - /** - * {@inheritDoc} - */ - public function __construct() - { - call_user_func_array(array('parent', '__construct'), func_get_args()); - - $dataDir = JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/'; - $options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; - $this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options); - $this->keywordsBefore = file($dataDir.'keywords_before.txt', $options); - $this->keywordsAfter = file($dataDir.'keywords_after.txt', $options); - $this->operatorsBefore = file($dataDir.'operators_before.txt', $options); - $this->operatorsAfter = file($dataDir.'operators_after.txt', $options); - } + protected $operatorsAfter = [ + '+', + '-', + '*', + '/', + '%', + '=', + '+=', + '-=', + '*=', + '/=', + '%=', + '<<=', + '>>=', + '>>>=', + '&=', + '^=', + '|=', + '&', + '|', + '^', + '<<', + '>>', + '>>>', + '==', + '===', + '!=', + '!==', + '>', + '<', + '>=', + '<=', + '&&', + '||', + '.', + '[', + ']', + '?', + ':', + ',', + ';', + '(', + ')', + '}', + ]; /** * Minify the data. * Perform JS optimizations. * - * @param string[optional] $path Path to write the data to. - * @return string The minified data. + * @param string[optional] $path Path to write the data to + * + * @return string The minified data */ public function execute($path = null) { $content = ''; - // loop files - foreach ($this->data as $source => $js) { - /* - * Combine js: separating the scripts by a ; - * I'm also adding a newline: it will be eaten when whitespace is - * stripped, but we need to make sure we're not just appending - * a new script right after a previous script that ended with a - * singe-line comment on the last line (in which case it would also - * be seen as part of that comment) - */ - $content .= $js."\n;"; - } - /* * Let's first take out strings, comments and regular expressions. * All of these can contain JS code-like characters, and we should make @@ -178,11 +384,24 @@ class JS extends Minify $this->extractStrings('\'"`'); $this->stripComments(); $this->extractRegex(); - $content = $this->replace($content); - $content = $this->stripWhitespace($content); - $content = $this->propertyNotation($content); - $content = $this->shortenBools($content); + // loop files + foreach ($this->data as $source => $js) { + // take out strings, comments & regex (for which we've registered + // the regexes just a few lines earlier) + $js = $this->replace($js); + + $js = $this->propertyNotation($js); + $js = $this->shortenBools($js); + $js = $this->stripWhitespace($js); + + // combine js: separating the scripts by a ; + $content .= $js . ';'; + } + + // clean up leftover `;`s from the combination of multiple scripts + $content = ltrim($content, ';'); + $content = (string) substr($content, 0, -1); /* * Earlier, we extracted strings & regular expressions and replaced them @@ -198,15 +417,35 @@ class JS extends Minify */ protected function stripComments() { - // single-line comments - $this->registerPattern('/\/\/.*$/m', ''); + // PHP only supports $this inside anonymous functions since 5.4 + $minifier = $this; + $callback = function ($match) use ($minifier) { + if ( + substr((string) $match[2], 0, 1) === '!' || + strpos((string) $match[2], '@license') !== false || + strpos((string) $match[2], '@preserve') !== false + ) { + // preserve multi-line comments that start with /*! + // or contain @license or @preserve annotations + $count = count($minifier->extracted); + $placeholder = '/*' . $count . '*/'; + $minifier->extracted[$placeholder] = $match[0]; + + return $match[1] . $placeholder . $match[3]; + } + + return $match[1] . $match[3]; + }; // multi-line comments - $this->registerPattern('/\/\*.*?\*\//s', ''); + $this->registerPattern('/(\n?)\/\*(.*?)\*\/(\n?)/s', $callback); + + // single-line comments + $this->registerPattern('/\/\/.*$/m', ''); } /** - * JS can have /-delimited regular expressions, like: /ab+c/.match(string) + * JS can have /-delimited regular expressions, like: /ab+c/.match(string). * * The content inside the regex can contain characters that may be confused * for JS code: e.g. it could contain whitespace it needs to match & we @@ -228,17 +467,71 @@ class JS extends Minify $minifier = $this; $callback = function ($match) use ($minifier) { $count = count($minifier->extracted); - $placeholder = '/'.$count.'/'; - $minifier->extracted[$placeholder] = '/'.$match[1].'/'; + $placeholder = '"' . $count . '"'; + $minifier->extracted[$placeholder] = $match[0]; return $placeholder; }; - // it's a regex if we can find an opening (not preceded by variable, - // value or similar) & (non-escaped) closing /, - $before = $this->getOperatorsForRegex($this->operatorsBefore, '/'); - $this->registerPattern('/^\s*+\K\/(.*?(?registerPattern('/(?:'.implode('|', $before).')\s*+\K\/(.*?(?registerPattern('/' . $before . '\K' . $pattern . $after . '/', $callback); + + // regular expressions following a `)` are rather annoying to detect... + // quite often, `/` after `)` is a division operator & if it happens to + // be followed by another one (or a comment), it is likely to be + // confused for a regular expression + // however, it's perfectly possible for a regex to follow a `)`: after + // a single-line `if()`, `while()`, ... statement, for example + // since, when they occur like that, they're always the start of a + // statement, there's only a limited amount of ways they can be useful: + // by calling the regex methods directly + // if a regex following `)` is not followed by `.`, + // it's quite likely not a regex + $before = '\)\s*'; + $after = '(?=\s*\.(' . implode('|', $propertiesAndMethods) . '))'; + $this->registerPattern('/' . $before . '\K' . $pattern . $after . '/', $callback); + + // 1 more edge case: a regex can be followed by a lot more operators or + // keywords if there's a newline (ASI) in between, where the operator + // actually starts a new statement + // (https://github.com/matthiasmullie/minify/issues/56) + $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/'); + $operators += $this->getOperatorsForRegex($this->keywordsReserved, '/'); + $after = '(?=\s*\n\s*(' . implode('|', $operators) . '))'; + $this->registerPattern('/' . $pattern . $after . '/', $callback); } /** @@ -253,7 +546,8 @@ class JS extends Minify * Because it's sometimes hard to tell if a newline is part of a statement * that should be terminated or not, we'll just leave some of them alone. * - * @param string $content The content to strip the whitespace for. + * @param string $content The content to strip the whitespace for + * * @return string */ protected function stripWhitespace($content) @@ -270,16 +564,37 @@ class JS extends Minify // collapse consecutive line feeds into just 1 $content = preg_replace('/\n+/', "\n", $content); + $operatorsBefore = $this->getOperatorsForRegex($this->operatorsBefore, '/'); + $operatorsAfter = $this->getOperatorsForRegex($this->operatorsAfter, '/'); + $operators = $this->getOperatorsForRegex($this->operators, '/'); + $keywordsBefore = $this->getKeywordsForRegex($this->keywordsBefore, '/'); + $keywordsAfter = $this->getKeywordsForRegex($this->keywordsAfter, '/'); + // strip whitespace that ends in (or next line begin with) an operator // that allows statements to be broken up over multiple lines - $before = $this->getOperatorsForRegex($this->operatorsBefore, '/'); - $after = $this->getOperatorsForRegex($this->operatorsAfter, '/'); - $content = preg_replace('/('.implode('|', $before).')\s+/', '\\1', $content); - $content = preg_replace('/\s+('.implode('|', $after).')/', '\\1', $content); + unset($operatorsBefore['+'], $operatorsBefore['-'], $operatorsAfter['+'], $operatorsAfter['-']); + $content = preg_replace( + array( + '/(' . implode('|', $operatorsBefore) . ')\s+/', + '/\s+(' . implode('|', $operatorsAfter) . ')/', + ), + '\\1', + $content + ); // make sure + and - can't be mistaken for, or joined into ++ and -- - $content = preg_replace('/(?getOperatorsForRegex($this->operatorsBefore + $this->operatorsAfter, '/'); - $content = preg_replace('/([\}\)\]])[^\S\n]+(?!'.implode('|', $operators).')/', '\\1', $content); + $operatorsDiffBefore = array_diff($operators, $operatorsBefore); + $operatorsDiffAfter = array_diff($operators, $operatorsAfter); + $content = preg_replace('/(' . implode('|', $operatorsDiffBefore) . ')[^\S\n]+/', '\\1', $content); + $content = preg_replace('/[^\S\n]+(' . implode('|', $operatorsDiffAfter) . ')/', '\\1', $content); - // collapse whitespace around reserved words into single space - $before = $this->getKeywordsForRegex($this->keywordsBefore, '/'); - $after = $this->getKeywordsForRegex($this->keywordsAfter, '/'); - $content = preg_replace('/(^|[;\}\s])\K('.implode('|', $before).')\s+/', '\\2 ', $content); - $content = preg_replace('/\s+('.implode('|', $after).')(?=([;\{\s]|$))/', ' \\1', $content); + /* + * Whitespace after `return` can be omitted in a few occasions + * (such as when followed by a string or regex) + * Same for whitespace in between `)` and `{`, or between `{` and some + * keywords. + */ + $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content); + $content = preg_replace('/\)\s+\{/', '){', $content); + $content = preg_replace('/}\n(else|catch|finally)\b/', '}$1', $content); - // get rid of double semicolons, except when followed by closing-), - // where semicolons can be used like: "for(v=1,_=b;;)" - $content = preg_replace('/;+(?!\))/', ';', $content); + /* + * Get rid of double semicolons, except where they can be used like: + * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))". + * I'll safeguard these double semicolons inside for-loops by + * temporarily replacing them with an invalid condition: they won't have + * a double semicolon and will be easy to spot to restore afterwards. + */ + $content = preg_replace('/\bfor\(([^;]*);;([^;]*)\)/', 'for(\\1;-;\\2)', $content); + $content = preg_replace('/;+/', ';', $content); + $content = preg_replace('/\bfor\(([^;]*);-;([^;]*)\)/', 'for(\\1;;\\2)', $content); /* * Next, we'll be removing all semicolons where ASI kicks in. * for-loops however, can have an empty body (ending in only a - * semicolon), like: `for(i=1;i<3;i++);` + * semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);` * Here, nothing happens during the loop; it's just used to keep * increasing `i`. With that ; omitted, the next line would be expected - * to be the for-loop's body... + * to be the for-loop's body... Same goes for while loops. * I'm going to double that semicolon (if any) so after the next line, * which strips semicolons here & there, we're still left with this one. + * Note the special recursive construct in the three inner parts of the for: + * (\{([^\{\}]*(?-2))*[^\{\}]*\})? - it is intended to match inline + * functions bodies, e.g.: i%&|', $delimiter); + $operators['='] = '(? '\b' . $value . '\b'); $keywords = array_combine($keywords, $escaped); @@ -376,9 +743,10 @@ class JS extends Minify } /** - * Replaces all occurrences of array['key'] by array.key + * Replaces all occurrences of array['key'] by array.key. + * + * @param string $content * - * @param string $content * @return string */ protected function propertyNotation($content) @@ -403,11 +771,11 @@ class JS extends Minify * array['key-here'] can't be replaced by array.key-here since '-' * is not a valid character there. */ - if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) { + if (!preg_match('/^' . $minifier::REGEX_VARIABLE . '$/u', $property)) { return $match[0]; } - return '.'.$property; + return '.' . $property; }; /* @@ -415,7 +783,7 @@ class JS extends Minify * we want to use property notation on) - this is to make sure * standalone ['value'] arrays aren't confused for keys-of-an-array. * We can (and only have to) check the last character, because PHP's - * regex implementation doesn't allow un-fixed-length lookbehind + * regex implementation doesn't allow unfixed-length look-behind * assertions. */ preg_match('/(\[[^\]]+\])[^\]]*$/', static::REGEX_VARIABLE, $previousChar); @@ -424,28 +792,70 @@ class JS extends Minify /* * Make sure word preceding the ['value'] is not a keyword, e.g. * return['x']. Because -again- PHP's regex implementation doesn't allow - * un-fixed-length lookbehind assertions, I'm just going to do a lot of - * separate lookbehind assertions, one for each keyword. + * unfixed-length look-behind assertions, I'm just going to do a lot of + * separate look-behind assertions, one for each keyword. */ $keywords = $this->getKeywordsForRegex($keywords); - $keywords = '(? + * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved + * @license MIT License + */ +namespace VDM\Minify\Path; + + +use VDM\Minify\Path\Interfaces\ConverterInterface; + +class Converter implements ConverterInterface +{ + /** + * @var string + */ + protected $from; + + /** + * @var string + */ + protected $to; + + /** + * @param string $from The original base path (directory, not file!) + * @param string $to The new base path (directory, not file!) + * @param string $root Root directory (defaults to `getcwd`) + */ + public function __construct($from, $to, $root = '') + { + $shared = $this->shared($from, $to); + if ($shared === '') { + // when both paths have nothing in common, one of them is probably + // absolute while the other is relative + $root = $root ?: getcwd(); + $from = strpos($from, $root) === 0 ? $from : preg_replace('/\/+/', '/', $root . '/' . $from); + $to = strpos($to, $root) === 0 ? $to : preg_replace('/\/+/', '/', $root . '/' . $to); + + // or traveling the tree via `..` + // attempt to resolve path, or assume it's fine if it doesn't exist + $from = @realpath($from) ?: $from; + $to = @realpath($to) ?: $to; + } + + $from = $this->dirname($from); + $to = $this->dirname($to); + + $from = $this->normalize($from); + $to = $this->normalize($to); + + $this->from = $from; + $this->to = $to; + } + + /** + * Normalize path. + * + * @param string $path + * + * @return string + */ + protected function normalize($path) + { + // deal with different operating systems' directory structure + $path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/'); + + // remove leading current directory. + if (substr($path, 0, 2) === './') { + $path = substr($path, 2); + } + + // remove references to current directory in the path. + $path = str_replace('/./', '/', $path); + + /* + * Example: + * /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif + * to + * /home/forkcms/frontend/core/layout/images/img.gif + */ + do { + $path = preg_replace('/[^\/]+(? $chunk) { + if (isset($path2[$i]) && $path1[$i] == $path2[$i]) { + $shared[] = $chunk; + } else { + break; + } + } + + return implode('/', $shared); + } + + /** + * Convert paths relative from 1 file to another. + * + * E.g. + * ../images/img.gif relative to /home/forkcms/frontend/core/layout/css + * should become: + * ../../core/layout/images/img.gif relative to + * /home/forkcms/frontend/cache/minified_css + * + * @param string $path The relative path that needs to be converted + * + * @return string The new relative path + */ + public function convert($path) + { + // quit early if conversion makes no sense + if ($this->from === $this->to) { + return $path; + } + + $path = $this->normalize($path); + // if we're not dealing with a relative path, just return absolute + if (strpos($path, '/') === 0) { + return $path; + } + + // normalize paths + $path = $this->normalize($this->from . '/' . $path); + + // strip shared ancestor paths + $shared = $this->shared($path, $this->to); + $path = mb_substr($path, mb_strlen($shared)); + $to = mb_substr($this->to, mb_strlen($shared)); + + // add .. for every directory that needs to be traversed to new path + $to = str_repeat('../', count(array_filter(explode('/', $to)))); + + return $to . ltrim($path, '/'); + } + + /** + * Attempt to get the directory name from a path. + * + * @param string $path + * + * @return string + */ + protected function dirname($path) + { + if (@is_file($path)) { + return dirname($path); + } + + if (@is_dir($path)) { + return rtrim($path, '/'); + } + + // no known file/dir, start making assumptions + + // ends in / = dir + if (mb_substr($path, -1) === '/') { + return rtrim($path, '/'); + } + + // has a dot in the name, likely a file + if (preg_match('/.*\..*$/', basename($path)) !== 0) { + return dirname($path); + } + + // you're on your own here! + return $path; + } +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Path/Interfaces/ConverterInterface.php b/libraries/jcb_powers/VDM.Minify/src/Path/Interfaces/ConverterInterface.php new file mode 100644 index 000000000..e64774dd4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Path/Interfaces/ConverterInterface.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved + * @license MIT License + */ +namespace VDM\Minify\Path\Interfaces; + +interface ConverterInterface +{ + /** + * Convert file paths. + * + * @param string $path The path to be converted + * + * @return string The new path + */ + public function convert($path); +} + diff --git a/libraries/jcb_powers/VDM.Minify/src/Path/Interfaces/index.html b/libraries/jcb_powers/VDM.Minify/src/Path/Interfaces/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Path/Interfaces/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Minify/src/Path/index.html b/libraries/jcb_powers/VDM.Minify/src/Path/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/Path/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Minify/src/index.html b/libraries/jcb_powers/VDM.Minify/src/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Minify/src/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Psr/index.html b/libraries/jcb_powers/VDM.Psr/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Psr/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Psr/src/Cache/CacheItemInterface.php b/libraries/jcb_powers/VDM.Psr/src/Cache/CacheItemInterface.php new file mode 100644 index 000000000..458e1dbe4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Psr/src/Cache/CacheItemInterface.php @@ -0,0 +1,114 @@ + + * @git Caching Interface + * @license MIT + */ +namespace VDM\Psr\Cache; + + +/** + * CacheItemInterface defines an interface for interacting with objects inside a cache. + * + * Each Item object MUST be associated with a specific key, which can be set + * according to the implementing system and is typically passed by the + * Cache\CacheItemPoolInterface object. + * + * The Cache\CacheItemInterface object encapsulates the storage and retrieval of + * cache items. Each Cache\CacheItemInterface is generated by a + * Cache\CacheItemPoolInterface object, which is responsible for any required + * setup as well as associating the object with a unique Key. + * Cache\CacheItemInterface objects MUST be able to store and retrieve any type + * of PHP value defined in the Data section of the specification. + * + * Calling Libraries MUST NOT instantiate Item objects themselves. They may only + * be requested from a Pool object via the getItem() method. Calling Libraries + * SHOULD NOT assume that an Item created by one Implementing Library is + * compatible with a Pool from another Implementing Library. + */ +interface CacheItemInterface +{ + /** + * Returns the key for the current cache item. + * + * The key is loaded by the Implementing Library, but should be available to + * the higher level callers when needed. + * + * @return string + * The key string for this cache item. + */ + public function getKey(): string; + + /** + * Retrieves the value of the item from the cache associated with this object's key. + * + * The value returned must be identical to the value originally stored by set(). + * + * If isHit() returns false, this method MUST return null. Note that null + * is a legitimate cached value, so the isHit() method SHOULD be used to + * differentiate between "null value was found" and "no value was found." + * + * @return mixed + * The value corresponding to this cache item's key, or null if not found. + */ + public function get(): mixed; + + /** + * Confirms if the cache item lookup resulted in a cache hit. + * + * Note: This method MUST NOT have a race condition between calling isHit() + * and calling get(). + * + * @return bool + * True if the request resulted in a cache hit. False otherwise. + */ + public function isHit(): bool; + + /** + * Sets the value represented by this cache item. + * + * The $value argument may be any item that can be serialized by PHP, + * although the method of serialization is left up to the Implementing + * Library. + * + * @param mixed $value + * The serializable value to be stored. + * + * @return static + * The invoked object. + */ + public function set(mixed $value): static; + + /** + * Sets the expiration time for this cache item. + * + * @param ?\DateTimeInterface $expiration + * The point in time after which the item MUST be considered expired. + * If null is passed explicitly, a default value MAY be used. If none is set, + * the value should be stored permanently or for as long as the + * implementation allows. + * + * @return static + * The called object. + */ + public function expiresAt(?\DateTimeInterface $expiration): static; + + /** + * Sets the expiration time for this cache item. + * + * @param int|\DateInterval|null $time + * The period of time from the present after which the item MUST be considered + * expired. An integer parameter is understood to be the time in seconds until + * expiration. If null is passed explicitly, a default value MAY be used. + * If none is set, the value should be stored permanently or for as long as the + * implementation allows. + * + * @return static + * The called object. + */ + public function expiresAfter(int|\DateInterval|null $time): static; +} + diff --git a/libraries/jcb_powers/VDM.Psr/src/Cache/index.html b/libraries/jcb_powers/VDM.Psr/src/Cache/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Psr/src/Cache/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/phpseclib/vendor/composer/autoload_psr4.php b/libraries/phpseclib/vendor/composer/autoload_psr4.php deleted file mode 100644 index 38756ce7e..000000000 --- a/libraries/phpseclib/vendor/composer/autoload_psr4.php +++ /dev/null @@ -1,10 +0,0 @@ - array($vendorDir . '/phpseclib/phpseclib/phpseclib'), -); diff --git a/libraries/phpseclib/vendor/composer/installed.json b/libraries/phpseclib/vendor/composer/installed.json deleted file mode 100644 index 7a6f24266..000000000 --- a/libraries/phpseclib/vendor/composer/installed.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "packages": [ - { - "name": "phpseclib/phpseclib", - "version": "2.0.35", - "version_normalized": "2.0.35.0", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4e16cf3f5f927a7d3f5317820af795c0366c0420" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4e16cf3f5f927a7d3f5317820af795c0366c0420", - "reference": "4e16cf3f5f927a7d3f5317820af795c0366c0420", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", - "squizlabs/php_codesniffer": "~2.0" - }, - "suggest": { - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "time": "2021-11-28T23:30:39+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-JĂŒrgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "funding": [ - { - "url": "https://github.com/terrafrost", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpseclib", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", - "type": "tidelift" - } - ], - "install-path": "../phpseclib/phpseclib" - } - ], - "dev": true, - "dev-package-names": [] -} diff --git a/libraries/phpseclib/vendor/composer/installed.php b/libraries/phpseclib/vendor/composer/installed.php deleted file mode 100644 index 8c4ca830b..000000000 --- a/libraries/phpseclib/vendor/composer/installed.php +++ /dev/null @@ -1,32 +0,0 @@ - array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'reference' => NULL, - 'name' => '__root__', - 'dev' => true, - ), - 'versions' => array( - '__root__' => array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'reference' => NULL, - 'dev_requirement' => false, - ), - 'phpseclib/phpseclib' => array( - 'pretty_version' => '2.0.35', - 'version' => '2.0.35.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../phpseclib/phpseclib', - 'aliases' => array(), - 'reference' => '4e16cf3f5f927a7d3f5317820af795c0366c0420', - 'dev_requirement' => false, - ), - ), -); diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/appveyor.yml b/libraries/phpseclib/vendor/phpseclib/phpseclib/appveyor.yml deleted file mode 100644 index 210a90347..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/appveyor.yml +++ /dev/null @@ -1,27 +0,0 @@ -build: false -shallow_clone: false -platform: - - x86 - - x64 -clone_folder: C:\projects\phpseclib - -install: - - cinst -y OpenSSL.Light - - SET PATH=C:\Program Files\OpenSSL;%PATH% - - sc config wuauserv start= auto - - net start wuauserv - - cinst -y php --version 5.6.30 - - cd c:\tools\php56 - - copy php.ini-production php.ini - - echo date.timezone="UTC" >> php.ini - - echo extension_dir=ext >> php.ini - - echo extension=php_openssl.dll >> php.ini - - echo extension=php_gmp.dll >> php.ini - - cd C:\projects\phpseclib - - SET PATH=C:\tools\php56;%PATH% - - php.exe -r "readfile('http://getcomposer.org/installer');" | php.exe - - php.exe composer.phar install --prefer-source --no-interaction - -test_script: - - cd C:\projects\phpseclib - - vendor\bin\phpunit.bat tests/Windows32Test.php \ No newline at end of file diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php deleted file mode 100644 index 74cc49de8..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php +++ /dev/null @@ -1,571 +0,0 @@ - - * setKey('12345678901234567890123456789012'); - * - * $plaintext = str_repeat('a', 1024); - * - * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); - * ?> - * - * - * @category Crypt - * @package Blowfish - * @author Jim Wigginton - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Crypt; - -/** - * Pure-PHP implementation of Blowfish. - * - * @package Blowfish - * @author Jim Wigginton - * @author Hans-Juergen Petrich - * @access public - */ -class Blowfish extends Base -{ - /** - * Block Length of the cipher - * - * @see \phpseclib\Crypt\Base::block_size - * @var int - * @access private - */ - var $block_size = 8; - - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt - * @var string - * @access private - */ - var $cipher_name_mcrypt = 'blowfish'; - - /** - * Optimizing value while CFB-encrypting - * - * @see \phpseclib\Crypt\Base::cfb_init_len - * @var int - * @access private - */ - var $cfb_init_len = 500; - - /** - * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each - * - * S-Box 0 - * - * @access private - * @var array - */ - var $sbox0 = array( - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - ); - - /** - * S-Box 1 - * - * @access private - * @var array - */ - var $sbox1 = array( - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - ); - - /** - * S-Box 2 - * - * @access private - * @var array - */ - var $sbox2 = array( - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - ); - - /** - * S-Box 3 - * - * @access private - * @var array - */ - var $sbox3 = array( - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ); - - /** - * P-Array consists of 18 32-bit subkeys - * - * @var array - * @access private - */ - var $parray = array( - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, - 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b - ); - - /** - * The BCTX-working Array - * - * Holds the expanded key [p] and the key-depended s-boxes [sb] - * - * @var array - * @access private - */ - var $bctx; - - /** - * Holds the last used key - * - * @var array - * @access private - */ - var $kl; - - /** - * The Key Length (in bytes) - * - * @see \phpseclib\Crypt\Base::setKeyLength() - * @var int - * @access private - * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk - * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could - * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once. - */ - var $key_length = 16; - - /** - * Sets the key length. - * - * Key lengths can be between 32 and 448 bits. - * - * @access public - * @param int $length - */ - function setKeyLength($length) - { - if ($length < 32) { - $this->key_length = 4; - } elseif ($length > 448) { - $this->key_length = 56; - } else { - $this->key_length = $length >> 3; - } - - parent::setKeyLength($length); - } - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() - * - * @see \phpseclib\Crypt\Base::isValidEngine() - * @param int $engine - * @access public - * @return bool - */ - function isValidEngine($engine) - { - if ($engine == self::ENGINE_OPENSSL) { - if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) { - return false; - } - if ($this->key_length < 16) { - return false; - } - $this->cipher_name_openssl_ecb = 'bf-ecb'; - $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode(); - } - - return parent::isValidEngine($engine); - } - - /** - * Setup the key (expansion) - * - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private - */ - function _setupKey() - { - if (isset($this->kl['key']) && $this->key === $this->kl['key']) { - // already expanded - return; - } - $this->kl = array('key' => $this->key); - - /* key-expanding p[] and S-Box building sb[] */ - $this->bctx = array( - 'p' => array(), - 'sb' => array( - $this->sbox0, - $this->sbox1, - $this->sbox2, - $this->sbox3 - ) - ); - - // unpack binary string in unsigned chars - $key = array_values(unpack('C*', $this->key)); - $keyl = count($key); - for ($j = 0, $i = 0; $i < 18; ++$i) { - // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ... - for ($data = 0, $k = 0; $k < 4; ++$k) { - $data = ($data << 8) | $key[$j]; - if (++$j >= $keyl) { - $j = 0; - } - } - $this->bctx['p'][] = $this->parray[$i] ^ $data; - } - - // encrypt the zero-string, replace P1 and P2 with the encrypted data, - // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys - $data = "\0\0\0\0\0\0\0\0"; - for ($i = 0; $i < 18; $i += 2) { - list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data))); - $this->bctx['p'][$i ] = $l; - $this->bctx['p'][$i + 1] = $r; - } - for ($i = 0; $i < 4; ++$i) { - for ($j = 0; $j < 256; $j += 2) { - list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data))); - $this->bctx['sb'][$i][$j ] = $l; - $this->bctx['sb'][$i][$j + 1] = $r; - } - } - } - - /** - * Encrypts a block - * - * @access private - * @param string $in - * @return string - */ - function _encryptBlock($in) - { - $p = $this->bctx["p"]; - // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower - $sb_0 = $this->bctx["sb"][0]; - $sb_1 = $this->bctx["sb"][1]; - $sb_2 = $this->bctx["sb"][2]; - $sb_3 = $this->bctx["sb"][3]; - - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - - for ($i = 0; $i < 16; $i+= 2) { - $l^= $p[$i]; - $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]); - - $r^= $p[$i + 1]; - $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]); - } - return pack("N*", $r ^ $p[17], $l ^ $p[16]); - } - - /** - * Decrypts a block - * - * @access private - * @param string $in - * @return string - */ - function _decryptBlock($in) - { - $p = $this->bctx["p"]; - $sb_0 = $this->bctx["sb"][0]; - $sb_1 = $this->bctx["sb"][1]; - $sb_2 = $this->bctx["sb"][2]; - $sb_3 = $this->bctx["sb"][3]; - - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - - for ($i = 17; $i > 2; $i-= 2) { - $l^= $p[$i]; - $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]); - - $r^= $p[$i - 1]; - $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]); - } - return pack("N*", $r ^ $p[0], $l ^ $p[1]); - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * @see \phpseclib\Crypt\Base::_setupInlineCrypt() - * @access private - */ - function _setupInlineCrypt() - { - $lambda_functions =& self::_getLambdaFunctions(); - - // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. - // (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit) - // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. - $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); - - // Generation of a unique hash for our generated code - $code_hash = "Crypt_Blowfish, {$this->mode}"; - if ($gen_hi_opt_code) { - $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); - } - - $safeint = $this->safe_intval_inline(); - - if (!isset($lambda_functions[$code_hash])) { - switch (true) { - case $gen_hi_opt_code: - $p = $this->bctx['p']; - $init_crypt = ' - static $sb_0, $sb_1, $sb_2, $sb_3; - if (!$sb_0) { - $sb_0 = $self->bctx["sb"][0]; - $sb_1 = $self->bctx["sb"][1]; - $sb_2 = $self->bctx["sb"][2]; - $sb_3 = $self->bctx["sb"][3]; - } - '; - break; - default: - $p = array(); - for ($i = 0; $i < 18; ++$i) { - $p[] = '$p_' . $i; - } - $init_crypt = ' - list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"]; - list(' . implode(',', $p) . ') = $self->bctx["p"]; - - '; - } - - // Generating encrypt code: - $encrypt_block = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - '; - for ($i = 0; $i < 16; $i+= 2) { - $encrypt_block.= ' - $l^= ' . $p[$i] . '; - $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]') . '; - - $r^= ' . $p[$i + 1] . '; - $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]') . '; - '; - } - $encrypt_block.= ' - $in = pack("N*", - $r ^ ' . $p[17] . ', - $l ^ ' . $p[16] . ' - ); - '; - - // Generating decrypt code: - $decrypt_block = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - '; - - for ($i = 17; $i > 2; $i-= 2) { - $decrypt_block.= ' - $l^= ' . $p[$i] . '; - $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]') . '; - - $r^= ' . $p[$i - 1] . '; - $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]') . '; - '; - } - - $decrypt_block.= ' - $in = pack("N*", - $r ^ ' . $p[0] . ', - $l ^ ' . $p[1] . ' - ); - '; - - $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( - array( - 'init_crypt' => $init_crypt, - 'init_encrypt' => '', - 'init_decrypt' => '', - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ) - ); - } - $this->inline_crypt = $lambda_functions[$code_hash]; - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php deleted file mode 100644 index 248b65ef7..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php +++ /dev/null @@ -1,893 +0,0 @@ - - * setKey('abcdefg'); - * - * echo base64_encode($hash->hash('abcdefg')); - * ?> - * - * - * @category Crypt - * @package Hash - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Crypt; - -use phpseclib\Math\BigInteger; - -/** - * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions. - * - * @package Hash - * @author Jim Wigginton - * @access public - */ -class Hash -{ - /**#@+ - * @access private - * @see \phpseclib\Crypt\Hash::__construct() - */ - /** - * Toggles the internal implementation - */ - const MODE_INTERNAL = 1; - /** - * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+. - */ - const MODE_MHASH = 2; - /** - * Toggles the hash() implementation, which works on PHP 5.1.2+. - */ - const MODE_HASH = 3; - /**#@-*/ - - /** - * Hash Parameter - * - * @see self::setHash() - * @var int - * @access private - */ - var $hashParam; - - /** - * Byte-length of compression blocks / key (Internal HMAC) - * - * @see self::setAlgorithm() - * @var int - * @access private - */ - var $b; - - /** - * Byte-length of hash output (Internal HMAC) - * - * @see self::setHash() - * @var int - * @access private - */ - var $l = false; - - /** - * Hash Algorithm - * - * @see self::setHash() - * @var string - * @access private - */ - var $hash; - - /** - * Key - * - * @see self::setKey() - * @var string - * @access private - */ - var $key = false; - - /** - * Computed Key - * - * @see self::_computeKey() - * @var string - * @access private - */ - var $computedKey = false; - - /** - * Outer XOR (Internal HMAC) - * - * @see self::setKey() - * @var string - * @access private - */ - var $opad; - - /** - * Inner XOR (Internal HMAC) - * - * @see self::setKey() - * @var string - * @access private - */ - var $ipad; - - /** - * Engine - * - * @see self::setHash() - * @var string - * @access private - */ - var $engine; - - /** - * Default Constructor. - * - * @param string $hash - * @return \phpseclib\Crypt\Hash - * @access public - */ - function __construct($hash = 'sha1') - { - if (!defined('CRYPT_HASH_MODE')) { - switch (true) { - case extension_loaded('hash'): - define('CRYPT_HASH_MODE', self::MODE_HASH); - break; - case extension_loaded('mhash'): - define('CRYPT_HASH_MODE', self::MODE_MHASH); - break; - default: - define('CRYPT_HASH_MODE', self::MODE_INTERNAL); - } - } - - $this->setHash($hash); - } - - /** - * Sets the key for HMACs - * - * Keys can be of any length. - * - * @access public - * @param string $key - */ - function setKey($key = false) - { - $this->key = $key; - $this->_computeKey(); - } - - /** - * Pre-compute the key used by the HMAC - * - * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes - * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." - * - * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ - * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during - * every call - * - * @access private - */ - function _computeKey() - { - if ($this->key === false) { - $this->computedKey = false; - return; - } - - if (strlen($this->key) <= $this->b) { - $this->computedKey = $this->key; - return; - } - - switch ($this->engine) { - case self::MODE_MHASH: - $this->computedKey = mhash($this->hash, $this->key); - break; - case self::MODE_HASH: - $this->computedKey = hash($this->hash, $this->key, true); - break; - case self::MODE_INTERNAL: - $this->computedKey = call_user_func($this->hash, $this->key); - } - } - - /** - * Gets the hash function. - * - * As set by the constructor or by the setHash() method. - * - * @access public - * @return string - */ - function getHash() - { - return $this->hashParam; - } - - /** - * Sets the hash function. - * - * @access public - * @param string $hash - */ - function setHash($hash) - { - $this->hashParam = $hash = strtolower($hash); - switch ($hash) { - case 'md5-96': - case 'sha1-96': - case 'sha256-96': - case 'sha512-96': - $hash = substr($hash, 0, -3); - $this->l = 12; // 96 / 8 = 12 - break; - case 'md2': - case 'md5': - $this->l = 16; - break; - case 'sha1': - $this->l = 20; - break; - case 'sha256': - $this->l = 32; - break; - case 'sha384': - $this->l = 48; - break; - case 'sha512': - $this->l = 64; - } - - switch ($hash) { - case 'md2-96': - case 'md2': - $this->b = 16; - case 'md5-96': - case 'sha1-96': - case 'sha224-96': - case 'sha256-96': - case 'md2': - case 'md5': - case 'sha1': - case 'sha224': - case 'sha256': - $this->b = 64; - break; - default: - $this->b = 128; - } - - switch ($hash) { - case 'md2': - $this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ? - self::MODE_HASH : self::MODE_INTERNAL; - break; - case 'sha384': - case 'sha512': - $this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE; - break; - default: - $this->engine = CRYPT_HASH_MODE; - } - - switch ($this->engine) { - case self::MODE_MHASH: - switch ($hash) { - case 'md5': - $this->hash = MHASH_MD5; - break; - case 'sha256': - $this->hash = MHASH_SHA256; - break; - case 'sha1': - default: - $this->hash = MHASH_SHA1; - } - $this->_computeKey(self::MODE_MHASH); - return; - case self::MODE_HASH: - switch ($hash) { - case 'md5': - $this->hash = 'md5'; - return; - case 'md2': - case 'sha256': - case 'sha384': - case 'sha512': - $this->hash = $hash; - return; - case 'sha1': - default: - $this->hash = 'sha1'; - } - $this->_computeKey(self::MODE_HASH); - return; - } - - switch ($hash) { - case 'md2': - $this->hash = array($this, '_md2'); - break; - case 'md5': - $this->hash = array($this, '_md5'); - break; - case 'sha256': - $this->hash = array($this, '_sha256'); - break; - case 'sha384': - case 'sha512': - $this->hash = array($this, '_sha512'); - break; - case 'sha1': - default: - $this->hash = array($this, '_sha1'); - } - - $this->ipad = str_repeat(chr(0x36), $this->b); - $this->opad = str_repeat(chr(0x5C), $this->b); - - $this->_computeKey(self::MODE_INTERNAL); - } - - /** - * Compute the HMAC. - * - * @access public - * @param string $text - * @return string - */ - function hash($text) - { - if (!empty($this->key) || is_string($this->key)) { - switch ($this->engine) { - case self::MODE_MHASH: - $output = mhash($this->hash, $text, $this->computedKey); - break; - case self::MODE_HASH: - $output = hash_hmac($this->hash, $text, $this->computedKey, true); - break; - case self::MODE_INTERNAL: - $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1 - $temp = $this->ipad ^ $key; // step 2 - $temp .= $text; // step 3 - $temp = call_user_func($this->hash, $temp); // step 4 - $output = $this->opad ^ $key; // step 5 - $output.= $temp; // step 6 - $output = call_user_func($this->hash, $output); // step 7 - } - } else { - switch ($this->engine) { - case self::MODE_MHASH: - $output = mhash($this->hash, $text); - break; - case self::MODE_HASH: - $output = hash($this->hash, $text, true); - break; - case self::MODE_INTERNAL: - $output = call_user_func($this->hash, $text); - } - } - - return substr($output, 0, $this->l); - } - - /** - * Returns the hash length (in bytes) - * - * @access public - * @return int - */ - function getLength() - { - return $this->l; - } - - /** - * Wrapper for MD5 - * - * @access private - * @param string $m - */ - function _md5($m) - { - return pack('H*', md5($m)); - } - - /** - * Wrapper for SHA1 - * - * @access private - * @param string $m - */ - function _sha1($m) - { - return pack('H*', sha1($m)); - } - - /** - * Pure-PHP implementation of MD2 - * - * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}. - * - * @access private - * @param string $m - */ - function _md2($m) - { - static $s = array( - 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, - 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, - 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, - 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, - 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, - 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, - 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, - 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, - 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, - 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, - 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, - 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, - 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, - 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, - 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, - 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, - 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, - 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 - ); - - // Step 1. Append Padding Bytes - $pad = 16 - (strlen($m) & 0xF); - $m.= str_repeat(chr($pad), $pad); - - $length = strlen($m); - - // Step 2. Append Checksum - $c = str_repeat(chr(0), 16); - $l = chr(0); - for ($i = 0; $i < $length; $i+= 16) { - for ($j = 0; $j < 16; $j++) { - // RFC1319 incorrectly states that C[j] should be set to S[c xor L] - //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]); - // per , however, C[j] should be set to S[c xor L] xor C[j] - $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j])); - $l = $c[$j]; - } - } - $m.= $c; - - $length+= 16; - - // Step 3. Initialize MD Buffer - $x = str_repeat(chr(0), 48); - - // Step 4. Process Message in 16-Byte Blocks - for ($i = 0; $i < $length; $i+= 16) { - for ($j = 0; $j < 16; $j++) { - $x[$j + 16] = $m[$i + $j]; - $x[$j + 32] = $x[$j + 16] ^ $x[$j]; - } - $t = chr(0); - for ($j = 0; $j < 18; $j++) { - for ($k = 0; $k < 48; $k++) { - $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]); - //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]); - } - $t = chr(ord($t) + $j); - } - } - - // Step 5. Output - return substr($x, 0, 16); - } - - /** - * Pure-PHP implementation of SHA256 - * - * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}. - * - * @access private - * @param string $m - */ - function _sha256($m) - { - if (extension_loaded('suhosin')) { - return pack('H*', sha256($m)); - } - - // Initialize variables - $hash = array( - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 - ); - // Initialize table of round constants - // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311) - static $k = array( - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - ); - - // Pre-processing - $length = strlen($m); - // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64 - $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F)); - $m[$length] = chr(0x80); - // we don't support hashing strings 512MB long - $m.= pack('N2', 0, $length << 3); - - // Process the message in successive 512-bit chunks - $chunks = str_split($m, 64); - foreach ($chunks as $chunk) { - $w = array(); - for ($i = 0; $i < 16; $i++) { - extract(unpack('Ntemp', $this->_string_shift($chunk, 4))); - $w[] = $temp; - } - - // Extend the sixteen 32-bit words into sixty-four 32-bit words - for ($i = 16; $i < 64; $i++) { - // @codingStandardsIgnoreStart - $s0 = $this->_rightRotate($w[$i - 15], 7) ^ - $this->_rightRotate($w[$i - 15], 18) ^ - $this->_rightShift( $w[$i - 15], 3); - $s1 = $this->_rightRotate($w[$i - 2], 17) ^ - $this->_rightRotate($w[$i - 2], 19) ^ - $this->_rightShift( $w[$i - 2], 10); - // @codingStandardsIgnoreEnd - $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1); - } - - // Initialize hash value for this chunk - list($a, $b, $c, $d, $e, $f, $g, $h) = $hash; - - // Main loop - for ($i = 0; $i < 64; $i++) { - $s0 = $this->_rightRotate($a, 2) ^ - $this->_rightRotate($a, 13) ^ - $this->_rightRotate($a, 22); - $maj = ($a & $b) ^ - ($a & $c) ^ - ($b & $c); - $t2 = $this->_add($s0, $maj); - - $s1 = $this->_rightRotate($e, 6) ^ - $this->_rightRotate($e, 11) ^ - $this->_rightRotate($e, 25); - $ch = ($e & $f) ^ - ($this->_not($e) & $g); - $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]); - - $h = $g; - $g = $f; - $f = $e; - $e = $this->_add($d, $t1); - $d = $c; - $c = $b; - $b = $a; - $a = $this->_add($t1, $t2); - } - - // Add this chunk's hash to result so far - $hash = array( - $this->_add($hash[0], $a), - $this->_add($hash[1], $b), - $this->_add($hash[2], $c), - $this->_add($hash[3], $d), - $this->_add($hash[4], $e), - $this->_add($hash[5], $f), - $this->_add($hash[6], $g), - $this->_add($hash[7], $h) - ); - } - - // Produce the final hash value (big-endian) - return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]); - } - - /** - * Pure-PHP implementation of SHA384 and SHA512 - * - * @access private - * @param string $m - */ - function _sha512($m) - { - static $init384, $init512, $k; - - if (!isset($k)) { - // Initialize variables - $init384 = array( // initial values for SHA384 - 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939', - '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4' - ); - $init512 = array( // initial values for SHA512 - '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1', - '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179' - ); - - for ($i = 0; $i < 8; $i++) { - $init384[$i] = new BigInteger($init384[$i], 16); - $init384[$i]->setPrecision(64); - $init512[$i] = new BigInteger($init512[$i], 16); - $init512[$i]->setPrecision(64); - } - - // Initialize table of round constants - // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) - $k = array( - '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', - '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', - 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', - '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', - 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', - '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', - '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', - 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', - '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', - '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', - 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', - 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', - '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', - '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', - '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', - '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', - 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', - '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', - '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', - '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' - ); - - for ($i = 0; $i < 80; $i++) { - $k[$i] = new BigInteger($k[$i], 16); - } - } - - $hash = $this->l == 48 ? $init384 : $init512; - - // Pre-processing - $length = strlen($m); - // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 - $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); - $m[$length] = chr(0x80); - // we don't support hashing strings 512MB long - $m.= pack('N4', 0, 0, 0, $length << 3); - - // Process the message in successive 1024-bit chunks - $chunks = str_split($m, 128); - foreach ($chunks as $chunk) { - $w = array(); - for ($i = 0; $i < 16; $i++) { - $temp = new BigInteger($this->_string_shift($chunk, 8), 256); - $temp->setPrecision(64); - $w[] = $temp; - } - - // Extend the sixteen 32-bit words into eighty 32-bit words - for ($i = 16; $i < 80; $i++) { - $temp = array( - $w[$i - 15]->bitwise_rightRotate(1), - $w[$i - 15]->bitwise_rightRotate(8), - $w[$i - 15]->bitwise_rightShift(7) - ); - $s0 = $temp[0]->bitwise_xor($temp[1]); - $s0 = $s0->bitwise_xor($temp[2]); - $temp = array( - $w[$i - 2]->bitwise_rightRotate(19), - $w[$i - 2]->bitwise_rightRotate(61), - $w[$i - 2]->bitwise_rightShift(6) - ); - $s1 = $temp[0]->bitwise_xor($temp[1]); - $s1 = $s1->bitwise_xor($temp[2]); - $w[$i] = $w[$i - 16]->copy(); - $w[$i] = $w[$i]->add($s0); - $w[$i] = $w[$i]->add($w[$i - 7]); - $w[$i] = $w[$i]->add($s1); - } - - // Initialize hash value for this chunk - $a = $hash[0]->copy(); - $b = $hash[1]->copy(); - $c = $hash[2]->copy(); - $d = $hash[3]->copy(); - $e = $hash[4]->copy(); - $f = $hash[5]->copy(); - $g = $hash[6]->copy(); - $h = $hash[7]->copy(); - - // Main loop - for ($i = 0; $i < 80; $i++) { - $temp = array( - $a->bitwise_rightRotate(28), - $a->bitwise_rightRotate(34), - $a->bitwise_rightRotate(39) - ); - $s0 = $temp[0]->bitwise_xor($temp[1]); - $s0 = $s0->bitwise_xor($temp[2]); - $temp = array( - $a->bitwise_and($b), - $a->bitwise_and($c), - $b->bitwise_and($c) - ); - $maj = $temp[0]->bitwise_xor($temp[1]); - $maj = $maj->bitwise_xor($temp[2]); - $t2 = $s0->add($maj); - - $temp = array( - $e->bitwise_rightRotate(14), - $e->bitwise_rightRotate(18), - $e->bitwise_rightRotate(41) - ); - $s1 = $temp[0]->bitwise_xor($temp[1]); - $s1 = $s1->bitwise_xor($temp[2]); - $temp = array( - $e->bitwise_and($f), - $g->bitwise_and($e->bitwise_not()) - ); - $ch = $temp[0]->bitwise_xor($temp[1]); - $t1 = $h->add($s1); - $t1 = $t1->add($ch); - $t1 = $t1->add($k[$i]); - $t1 = $t1->add($w[$i]); - - $h = $g->copy(); - $g = $f->copy(); - $f = $e->copy(); - $e = $d->add($t1); - $d = $c->copy(); - $c = $b->copy(); - $b = $a->copy(); - $a = $t1->add($t2); - } - - // Add this chunk's hash to result so far - $hash = array( - $hash[0]->add($a), - $hash[1]->add($b), - $hash[2]->add($c), - $hash[3]->add($d), - $hash[4]->add($e), - $hash[5]->add($f), - $hash[6]->add($g), - $hash[7]->add($h) - ); - } - - // Produce the final hash value (big-endian) - // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) - $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . - $hash[4]->toBytes() . $hash[5]->toBytes(); - if ($this->l != 48) { - $temp.= $hash[6]->toBytes() . $hash[7]->toBytes(); - } - - return $temp; - } - - /** - * Right Rotate - * - * @access private - * @param int $int - * @param int $amt - * @see self::_sha256() - * @return int - */ - function _rightRotate($int, $amt) - { - $invamt = 32 - $amt; - $mask = (1 << $invamt) - 1; - return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask); - } - - /** - * Right Shift - * - * @access private - * @param int $int - * @param int $amt - * @see self::_sha256() - * @return int - */ - function _rightShift($int, $amt) - { - $mask = (1 << (32 - $amt)) - 1; - return ($int >> $amt) & $mask; - } - - /** - * Not - * - * @access private - * @param int $int - * @see self::_sha256() - * @return int - */ - function _not($int) - { - return ~$int & 0xFFFFFFFF; - } - - /** - * Add - * - * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the - * possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster. - * - * @return int - * @see self::_sha256() - * @access private - */ - function _add() - { - static $mod; - if (!isset($mod)) { - $mod = pow(2, 32); - } - - $result = 0; - $arguments = func_get_args(); - foreach ($arguments as $argument) { - $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument; - } - - if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') { - return fmod($result, $mod); - } - - return (fmod($result, 0x80000000) & 0x7FFFFFFF) | - ((fmod(floor($result / 0x80000000), 2) & 1) << 31); - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php deleted file mode 100644 index 22387be3a..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +++ /dev/null @@ -1,3265 +0,0 @@ - - * createKey()); - * - * $plaintext = 'terrafrost'; - * - * $rsa->loadKey($privatekey); - * $ciphertext = $rsa->encrypt($plaintext); - * - * $rsa->loadKey($publickey); - * echo $rsa->decrypt($ciphertext); - * ?> - * - * - * Here's an example of how to create signatures and verify signatures with this library: - * - * createKey()); - * - * $plaintext = 'terrafrost'; - * - * $rsa->loadKey($privatekey); - * $signature = $rsa->sign($plaintext); - * - * $rsa->loadKey($publickey); - * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified'; - * ?> - * - * - * @category Crypt - * @package RSA - * @author Jim Wigginton - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Crypt; - -use phpseclib\Math\BigInteger; - -/** - * Pure-PHP PKCS#1 compliant implementation of RSA. - * - * @package RSA - * @author Jim Wigginton - * @access public - */ -class RSA -{ - /**#@+ - * @access public - * @see self::encrypt() - * @see self::decrypt() - */ - /** - * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} - * (OAEP) for encryption / decryption. - * - * Uses sha1 by default. - * - * @see self::setHash() - * @see self::setMGFHash() - */ - const ENCRYPTION_OAEP = 1; - /** - * Use PKCS#1 padding. - * - * Although self::ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards - * compatibility with protocols (like SSH-1) written before OAEP's introduction. - */ - const ENCRYPTION_PKCS1 = 2; - /** - * Do not use any padding - * - * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy - * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. - */ - const ENCRYPTION_NONE = 3; - /**#@-*/ - - /**#@+ - * @access public - * @see self::sign() - * @see self::verify() - * @see self::setHash() - */ - /** - * Use the Probabilistic Signature Scheme for signing - * - * Uses sha1 by default. - * - * @see self::setSaltLength() - * @see self::setMGFHash() - */ - const SIGNATURE_PSS = 1; - /** - * Use the PKCS#1 scheme by default. - * - * Although self::SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards - * compatibility with protocols (like SSH-2) written before PSS's introduction. - */ - const SIGNATURE_PKCS1 = 2; - /**#@-*/ - - /**#@+ - * @access private - * @see \phpseclib\Crypt\RSA::createKey() - */ - /** - * ASN1 Integer - */ - const ASN1_INTEGER = 2; - /** - * ASN1 Bit String - */ - const ASN1_BITSTRING = 3; - /** - * ASN1 Octet String - */ - const ASN1_OCTETSTRING = 4; - /** - * ASN1 Object Identifier - */ - const ASN1_OBJECT = 6; - /** - * ASN1 Sequence (with the constucted bit set) - */ - const ASN1_SEQUENCE = 48; - /**#@-*/ - - /**#@+ - * @access private - * @see \phpseclib\Crypt\RSA::__construct() - */ - /** - * To use the pure-PHP implementation - */ - const MODE_INTERNAL = 1; - /** - * To use the OpenSSL library - * - * (if enabled; otherwise, the internal implementation will be used) - */ - const MODE_OPENSSL = 2; - /**#@-*/ - - /**#@+ - * @access public - * @see \phpseclib\Crypt\RSA::createKey() - * @see \phpseclib\Crypt\RSA::setPrivateKeyFormat() - */ - /** - * PKCS#1 formatted private key - * - * Used by OpenSSH - */ - const PRIVATE_FORMAT_PKCS1 = 0; - /** - * PuTTY formatted private key - */ - const PRIVATE_FORMAT_PUTTY = 1; - /** - * XML formatted private key - */ - const PRIVATE_FORMAT_XML = 2; - /** - * PKCS#8 formatted private key - */ - const PRIVATE_FORMAT_PKCS8 = 8; - /** - * OpenSSH formatted private key - */ - const PRIVATE_FORMAT_OPENSSH = 9; - /**#@-*/ - - /**#@+ - * @access public - * @see \phpseclib\Crypt\RSA::createKey() - * @see \phpseclib\Crypt\RSA::setPublicKeyFormat() - */ - /** - * Raw public key - * - * An array containing two \phpseclib\Math\BigInteger objects. - * - * The exponent can be indexed with any of the following: - * - * 0, e, exponent, publicExponent - * - * The modulus can be indexed with any of the following: - * - * 1, n, modulo, modulus - */ - const PUBLIC_FORMAT_RAW = 3; - /** - * PKCS#1 formatted public key (raw) - * - * Used by File/X509.php - * - * Has the following header: - * - * -----BEGIN RSA PUBLIC KEY----- - * - * Analogous to ssh-keygen's pem format (as specified by -m) - */ - const PUBLIC_FORMAT_PKCS1 = 4; - const PUBLIC_FORMAT_PKCS1_RAW = 4; - /** - * XML formatted public key - */ - const PUBLIC_FORMAT_XML = 5; - /** - * OpenSSH formatted public key - * - * Place in $HOME/.ssh/authorized_keys - */ - const PUBLIC_FORMAT_OPENSSH = 6; - /** - * PKCS#1 formatted public key (encapsulated) - * - * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set) - * - * Has the following header: - * - * -----BEGIN PUBLIC KEY----- - * - * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8 - * is specific to private keys it's basically creating a DER-encoded wrapper - * for keys. This just extends that same concept to public keys (much like ssh-keygen) - */ - const PUBLIC_FORMAT_PKCS8 = 7; - /**#@-*/ - - /** - * Precomputed Zero - * - * @var \phpseclib\Math\BigInteger - * @access private - */ - var $zero; - - /** - * Precomputed One - * - * @var \phpseclib\Math\BigInteger - * @access private - */ - var $one; - - /** - * Private Key Format - * - * @var int - * @access private - */ - var $privateKeyFormat = self::PRIVATE_FORMAT_PKCS1; - - /** - * Public Key Format - * - * @var int - * @access public - */ - var $publicKeyFormat = self::PUBLIC_FORMAT_PKCS8; - - /** - * Modulus (ie. n) - * - * @var \phpseclib\Math\BigInteger - * @access private - */ - var $modulus; - - /** - * Modulus length - * - * @var \phpseclib\Math\BigInteger - * @access private - */ - var $k; - - /** - * Exponent (ie. e or d) - * - * @var \phpseclib\Math\BigInteger - * @access private - */ - var $exponent; - - /** - * Primes for Chinese Remainder Theorem (ie. p and q) - * - * @var array - * @access private - */ - var $primes; - - /** - * Exponents for Chinese Remainder Theorem (ie. dP and dQ) - * - * @var array - * @access private - */ - var $exponents; - - /** - * Coefficients for Chinese Remainder Theorem (ie. qInv) - * - * @var array - * @access private - */ - var $coefficients; - - /** - * Hash name - * - * @var string - * @access private - */ - var $hashName; - - /** - * Hash function - * - * @var \phpseclib\Crypt\Hash - * @access private - */ - var $hash; - - /** - * Length of hash function output - * - * @var int - * @access private - */ - var $hLen; - - /** - * Length of salt - * - * @var int - * @access private - */ - var $sLen; - - /** - * Hash function for the Mask Generation Function - * - * @var \phpseclib\Crypt\Hash - * @access private - */ - var $mgfHash; - - /** - * Length of MGF hash function output - * - * @var int - * @access private - */ - var $mgfHLen; - - /** - * Encryption mode - * - * @var int - * @access private - */ - var $encryptionMode = self::ENCRYPTION_OAEP; - - /** - * Signature mode - * - * @var int - * @access private - */ - var $signatureMode = self::SIGNATURE_PSS; - - /** - * Public Exponent - * - * @var mixed - * @access private - */ - var $publicExponent = false; - - /** - * Password - * - * @var string - * @access private - */ - var $password = false; - - /** - * Components - * - * For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions - - * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't. - * - * @see self::_start_element_handler() - * @var array - * @access private - */ - var $components = array(); - - /** - * Current String - * - * For use with parsing XML formatted keys. - * - * @see self::_character_handler() - * @see self::_stop_element_handler() - * @var mixed - * @access private - */ - var $current; - - /** - * OpenSSL configuration file name. - * - * Set to null to use system configuration file. - * @see self::createKey() - * @var mixed - * @Access public - */ - var $configFile; - - /** - * Public key comment field. - * - * @var string - * @access private - */ - var $comment = 'phpseclib-generated-key'; - - /** - * The constructor - * - * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason - * \phpseclib\Crypt\RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires - * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late. - * - * @return \phpseclib\Crypt\RSA - * @access public - */ - function __construct() - { - $this->configFile = dirname(__FILE__) . '/../openssl.cnf'; - - if (!defined('CRYPT_RSA_MODE')) { - switch (true) { - // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular, - // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger - // can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either. - case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'): - define('CRYPT_RSA_MODE', self::MODE_INTERNAL); - break; - case extension_loaded('openssl') && file_exists($this->configFile): - // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work - $versions = array(); - - // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems) - if (strpos(ini_get('disable_functions'), 'phpinfo') === false) { - ob_start(); - @phpinfo(); - $content = ob_get_contents(); - ob_end_clean(); - - preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches); - - if (!empty($matches[1])) { - for ($i = 0; $i < count($matches[1]); $i++) { - $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i]))); - - // Remove letter part in OpenSSL version - if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) { - $versions[$matches[1][$i]] = $fullVersion; - } else { - $versions[$matches[1][$i]] = $m[0]; - } - } - } - } - - // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+ - switch (true) { - case !isset($versions['Header']): - case !isset($versions['Library']): - case $versions['Header'] == $versions['Library']: - case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0: - define('CRYPT_RSA_MODE', self::MODE_OPENSSL); - break; - default: - define('CRYPT_RSA_MODE', self::MODE_INTERNAL); - define('MATH_BIGINTEGER_OPENSSL_DISABLE', true); - } - break; - default: - define('CRYPT_RSA_MODE', self::MODE_INTERNAL); - } - } - - $this->zero = new BigInteger(); - $this->one = new BigInteger(1); - - $this->hash = new Hash('sha1'); - $this->hLen = $this->hash->getLength(); - $this->hashName = 'sha1'; - $this->mgfHash = new Hash('sha1'); - $this->mgfHLen = $this->mgfHash->getLength(); - } - - /** - * Create public / private key pair - * - * Returns an array with the following three elements: - * - 'privatekey': The private key. - * - 'publickey': The public key. - * - 'partialkey': A partially computed key (if the execution time exceeded $timeout). - * Will need to be passed back to \phpseclib\Crypt\RSA::createKey() as the third parameter for further processing. - * - * @access public - * @param int $bits - * @param int $timeout - * @param array $partial - */ - function createKey($bits = 1024, $timeout = false, $partial = array()) - { - if (!defined('CRYPT_RSA_EXPONENT')) { - // http://en.wikipedia.org/wiki/65537_%28number%29 - define('CRYPT_RSA_EXPONENT', '65537'); - } - // per , this number ought not result in primes smaller - // than 256 bits. as a consequence if the key you're trying to create is 1024 bits and you've set CRYPT_RSA_SMALLEST_PRIME - // to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). at least if - // CRYPT_RSA_MODE is set to self::MODE_INTERNAL. if CRYPT_RSA_MODE is set to self::MODE_OPENSSL then - // CRYPT_RSA_SMALLEST_PRIME is ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key - // generation when there's a chance neither gmp nor OpenSSL are installed) - if (!defined('CRYPT_RSA_SMALLEST_PRIME')) { - define('CRYPT_RSA_SMALLEST_PRIME', 4096); - } - - // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum - if (CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) { - $config = array(); - if (isset($this->configFile)) { - $config['config'] = $this->configFile; - } - $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config); - openssl_pkey_export($rsa, $privatekey, null, $config); - $publickey = openssl_pkey_get_details($rsa); - $publickey = $publickey['key']; - - $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, self::PRIVATE_FORMAT_PKCS1))); - $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1))); - - // clear the buffer of error strings stemming from a minimalistic openssl.cnf - while (openssl_error_string() !== false) { - } - - return array( - 'privatekey' => $privatekey, - 'publickey' => $publickey, - 'partialkey' => false - ); - } - - static $e; - if (!isset($e)) { - $e = new BigInteger(CRYPT_RSA_EXPONENT); - } - - extract($this->_generateMinMax($bits)); - $absoluteMin = $min; - $temp = $bits >> 1; // divide by two to see how many bits P and Q would be - if ($temp > CRYPT_RSA_SMALLEST_PRIME) { - $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME); - $temp = CRYPT_RSA_SMALLEST_PRIME; - } else { - $num_primes = 2; - } - extract($this->_generateMinMax($temp + $bits % $temp)); - $finalMax = $max; - extract($this->_generateMinMax($temp)); - - $generator = new BigInteger(); - - $n = $this->one->copy(); - if (!empty($partial)) { - extract(unserialize($partial)); - } else { - $exponents = $coefficients = $primes = array(); - $lcm = array( - 'top' => $this->one->copy(), - 'bottom' => false - ); - } - - $start = time(); - $i0 = count($primes) + 1; - - do { - for ($i = $i0; $i <= $num_primes; $i++) { - if ($timeout !== false) { - $timeout-= time() - $start; - $start = time(); - if ($timeout <= 0) { - return array( - 'privatekey' => '', - 'publickey' => '', - 'partialkey' => serialize(array( - 'primes' => $primes, - 'coefficients' => $coefficients, - 'lcm' => $lcm, - 'exponents' => $exponents - )) - ); - } - } - - if ($i == $num_primes) { - list($min, $temp) = $absoluteMin->divide($n); - if (!$temp->equals($this->zero)) { - $min = $min->add($this->one); // ie. ceil() - } - $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout); - } else { - $primes[$i] = $generator->randomPrime($min, $max, $timeout); - } - - if ($primes[$i] === false) { // if we've reached the timeout - if (count($primes) > 1) { - $partialkey = ''; - } else { - array_pop($primes); - $partialkey = serialize(array( - 'primes' => $primes, - 'coefficients' => $coefficients, - 'lcm' => $lcm, - 'exponents' => $exponents - )); - } - - return array( - 'privatekey' => '', - 'publickey' => '', - 'partialkey' => $partialkey - ); - } - - // the first coefficient is calculated differently from the rest - // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) - if ($i > 2) { - $coefficients[$i] = $n->modInverse($primes[$i]); - } - - $n = $n->multiply($primes[$i]); - - $temp = $primes[$i]->subtract($this->one); - - // textbook RSA implementations use Euler's totient function instead of the least common multiple. - // see http://en.wikipedia.org/wiki/Euler%27s_totient_function - $lcm['top'] = $lcm['top']->multiply($temp); - $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); - - $exponents[$i] = $e->modInverse($temp); - } - - list($temp) = $lcm['top']->divide($lcm['bottom']); - $gcd = $temp->gcd($e); - $i0 = 1; - } while (!$gcd->equals($this->one)); - - $d = $e->modInverse($temp); - - $coefficients[2] = $primes[2]->modInverse($primes[1]); - - // from : - // RSAPrivateKey ::= SEQUENCE { - // version Version, - // modulus INTEGER, -- n - // publicExponent INTEGER, -- e - // privateExponent INTEGER, -- d - // prime1 INTEGER, -- p - // prime2 INTEGER, -- q - // exponent1 INTEGER, -- d mod (p-1) - // exponent2 INTEGER, -- d mod (q-1) - // coefficient INTEGER, -- (inverse of q) mod p - // otherPrimeInfos OtherPrimeInfos OPTIONAL - // } - - return array( - 'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients), - 'publickey' => $this->_convertPublicKey($n, $e), - 'partialkey' => false - ); - } - - /** - * Convert a private key to the appropriate format. - * - * @access private - * @see self::setPrivateKeyFormat() - * @param Math_BigInteger $n - * @param Math_BigInteger $e - * @param Math_BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @return string - */ - function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients) - { - $signed = $this->privateKeyFormat != self::PRIVATE_FORMAT_XML; - $num_primes = count($primes); - $raw = array( - 'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi - 'modulus' => $n->toBytes($signed), - 'publicExponent' => $e->toBytes($signed), - 'privateExponent' => $d->toBytes($signed), - 'prime1' => $primes[1]->toBytes($signed), - 'prime2' => $primes[2]->toBytes($signed), - 'exponent1' => $exponents[1]->toBytes($signed), - 'exponent2' => $exponents[2]->toBytes($signed), - 'coefficient' => $coefficients[2]->toBytes($signed) - ); - - // if the format in question does not support multi-prime rsa and multi-prime rsa was used, - // call _convertPublicKey() instead. - switch ($this->privateKeyFormat) { - case self::PRIVATE_FORMAT_XML: - if ($num_primes != 2) { - return false; - } - return "\r\n" . - ' ' . base64_encode($raw['modulus']) . "\r\n" . - ' ' . base64_encode($raw['publicExponent']) . "\r\n" . - '

' . base64_encode($raw['prime1']) . "

\r\n" . - ' ' . base64_encode($raw['prime2']) . "\r\n" . - ' ' . base64_encode($raw['exponent1']) . "\r\n" . - ' ' . base64_encode($raw['exponent2']) . "\r\n" . - ' ' . base64_encode($raw['coefficient']) . "\r\n" . - ' ' . base64_encode($raw['privateExponent']) . "\r\n" . - '
'; - break; - case self::PRIVATE_FORMAT_PUTTY: - if ($num_primes != 2) { - return false; - } - $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: "; - $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none'; - $key.= $encryption; - $key.= "\r\nComment: " . $this->comment . "\r\n"; - $public = pack( - 'Na*Na*Na*', - strlen('ssh-rsa'), - 'ssh-rsa', - strlen($raw['publicExponent']), - $raw['publicExponent'], - strlen($raw['modulus']), - $raw['modulus'] - ); - $source = pack( - 'Na*Na*Na*Na*', - strlen('ssh-rsa'), - 'ssh-rsa', - strlen($encryption), - $encryption, - strlen($this->comment), - $this->comment, - strlen($public), - $public - ); - $public = base64_encode($public); - $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; - $key.= chunk_split($public, 64); - $private = pack( - 'Na*Na*Na*Na*', - strlen($raw['privateExponent']), - $raw['privateExponent'], - strlen($raw['prime1']), - $raw['prime1'], - strlen($raw['prime2']), - $raw['prime2'], - strlen($raw['coefficient']), - $raw['coefficient'] - ); - if (empty($this->password) && !is_string($this->password)) { - $source.= pack('Na*', strlen($private), $private); - $hashkey = 'putty-private-key-file-mac-key'; - } else { - $private.= Random::string(16 - (strlen($private) & 15)); - $source.= pack('Na*', strlen($private), $private); - $sequence = 0; - $symkey = ''; - while (strlen($symkey) < 32) { - $temp = pack('Na*', $sequence++, $this->password); - $symkey.= pack('H*', sha1($temp)); - } - $symkey = substr($symkey, 0, 32); - $crypto = new AES(); - - $crypto->setKey($symkey); - $crypto->disablePadding(); - $private = $crypto->encrypt($private); - $hashkey = 'putty-private-key-file-mac-key' . $this->password; - } - - $private = base64_encode($private); - $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; - $key.= chunk_split($private, 64); - $hash = new Hash('sha1'); - $hash->setKey(pack('H*', sha1($hashkey))); - $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n"; - - return $key; - case self::PRIVATE_FORMAT_OPENSSH: - if ($num_primes != 2) { - return false; - } - $publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']); - $privateKey = pack( - 'Na*Na*Na*Na*Na*Na*Na*', - strlen('ssh-rsa'), - 'ssh-rsa', - strlen($raw['modulus']), - $raw['modulus'], - strlen($raw['publicExponent']), - $raw['publicExponent'], - strlen($raw['privateExponent']), - $raw['privateExponent'], - strlen($raw['coefficient']), - $raw['coefficient'], - strlen($raw['prime1']), - $raw['prime1'], - strlen($raw['prime2']), - $raw['prime2'] - ); - $checkint = Random::string(4); - $paddedKey = pack( - 'a*Na*', - $checkint . $checkint . $privateKey, - strlen($this->comment), - $this->comment - ); - $paddingLength = (7 * strlen($paddedKey)) % 8; - for ($i = 1; $i <= $paddingLength; $i++) { - $paddedKey.= chr($i); - } - $key = pack( - 'Na*Na*Na*NNa*Na*', - strlen('none'), - 'none', - strlen('none'), - 'none', - 0, - '', - 1, - strlen($publicKey), - $publicKey, - strlen($paddedKey), - $paddedKey - ); - $key = "openssh-key-v1\0$key"; - - return "-----BEGIN OPENSSH PRIVATE KEY-----\n" . - chunk_split(base64_encode($key), 70, "\n") . - "-----END OPENSSH PRIVATE KEY-----\n"; - default: // eg. self::PRIVATE_FORMAT_PKCS1 - $components = array(); - foreach ($raw as $name => $value) { - $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value); - } - - $RSAPrivateKey = implode('', $components); - - if ($num_primes > 2) { - $OtherPrimeInfos = ''; - for ($i = 3; $i <= $num_primes; $i++) { - // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo - // - // OtherPrimeInfo ::= SEQUENCE { - // prime INTEGER, -- ri - // exponent INTEGER, -- di - // coefficient INTEGER -- ti - // } - $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true)); - $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true)); - $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true)); - $OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo); - } - $RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos); - } - - $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); - - if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) { - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA - $RSAPrivateKey = pack( - 'Ca*a*Ca*a*', - self::ASN1_INTEGER, - "\01\00", - $rsaOID, - 4, - $this->_encodeLength(strlen($RSAPrivateKey)), - $RSAPrivateKey - ); - $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); - if (!empty($this->password) || is_string($this->password)) { - $salt = Random::string(8); - $iterationCount = 2048; - - $crypto = new DES(); - $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); - $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey); - - $parameters = pack( - 'Ca*a*Ca*N', - self::ASN1_OCTETSTRING, - $this->_encodeLength(strlen($salt)), - $salt, - self::ASN1_INTEGER, - $this->_encodeLength(4), - $iterationCount - ); - $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03"; - - $encryptionAlgorithm = pack( - 'Ca*a*Ca*a*', - self::ASN1_OBJECT, - $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), - $pbeWithMD5AndDES_CBC, - self::ASN1_SEQUENCE, - $this->_encodeLength(strlen($parameters)), - $parameters - ); - - $RSAPrivateKey = pack( - 'Ca*a*Ca*a*', - self::ASN1_SEQUENCE, - $this->_encodeLength(strlen($encryptionAlgorithm)), - $encryptionAlgorithm, - self::ASN1_OCTETSTRING, - $this->_encodeLength(strlen($RSAPrivateKey)), - $RSAPrivateKey - ); - - $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); - - $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . - '-----END ENCRYPTED PRIVATE KEY-----'; - } else { - $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . - '-----END PRIVATE KEY-----'; - } - return $RSAPrivateKey; - } - - if (!empty($this->password) || is_string($this->password)) { - $iv = Random::string(8); - $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key - $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8); - $des = new TripleDES(); - $des->setKey($symkey); - $des->setIV($iv); - $iv = strtoupper(bin2hex($iv)); - $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . - "Proc-Type: 4,ENCRYPTED\r\n" . - "DEK-Info: DES-EDE3-CBC,$iv\r\n" . - "\r\n" . - chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) . - '-----END RSA PRIVATE KEY-----'; - } else { - $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . - '-----END RSA PRIVATE KEY-----'; - } - - return $RSAPrivateKey; - } - } - - /** - * Convert a public key to the appropriate format - * - * @access private - * @see self::setPublicKeyFormat() - * @param Math_BigInteger $n - * @param Math_BigInteger $e - * @return string|array - */ - function _convertPublicKey($n, $e) - { - $signed = $this->publicKeyFormat != self::PUBLIC_FORMAT_XML; - - $modulus = $n->toBytes($signed); - $publicExponent = $e->toBytes($signed); - - switch ($this->publicKeyFormat) { - case self::PUBLIC_FORMAT_RAW: - return array('e' => $e->copy(), 'n' => $n->copy()); - case self::PUBLIC_FORMAT_XML: - return "\r\n" . - ' ' . base64_encode($modulus) . "\r\n" . - ' ' . base64_encode($publicExponent) . "\r\n" . - ''; - break; - case self::PUBLIC_FORMAT_OPENSSH: - // from : - // string "ssh-rsa" - // mpint e - // mpint n - $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus); - $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment; - - return $RSAPublicKey; - default: // eg. self::PUBLIC_FORMAT_PKCS1_RAW or self::PUBLIC_FORMAT_PKCS1 - // from : - // RSAPublicKey ::= SEQUENCE { - // modulus INTEGER, -- n - // publicExponent INTEGER -- e - // } - $components = array( - 'modulus' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus), - 'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent) - ); - - $RSAPublicKey = pack( - 'Ca*a*a*', - self::ASN1_SEQUENCE, - $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])), - $components['modulus'], - $components['publicExponent'] - ); - - if ($this->publicKeyFormat == self::PUBLIC_FORMAT_PKCS1_RAW) { - $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($RSAPublicKey), 64) . - '-----END RSA PUBLIC KEY-----'; - } else { - // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption. - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA - $RSAPublicKey = chr(0) . $RSAPublicKey; - $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey; - - $RSAPublicKey = pack( - 'Ca*a*', - self::ASN1_SEQUENCE, - $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), - $rsaOID . $RSAPublicKey - ); - - $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($RSAPublicKey), 64) . - '-----END PUBLIC KEY-----'; - } - - return $RSAPublicKey; - } - } - - /** - * Break a public or private key down into its constituant components - * - * @access private - * @see self::_convertPublicKey() - * @see self::_convertPrivateKey() - * @param string|array $key - * @param int $type - * @return array|bool - */ - function _parseKey($key, $type) - { - if ($type != self::PUBLIC_FORMAT_RAW && !is_string($key)) { - return false; - } - - switch ($type) { - case self::PUBLIC_FORMAT_RAW: - if (!is_array($key)) { - return false; - } - $components = array(); - switch (true) { - case isset($key['e']): - $components['publicExponent'] = $key['e']->copy(); - break; - case isset($key['exponent']): - $components['publicExponent'] = $key['exponent']->copy(); - break; - case isset($key['publicExponent']): - $components['publicExponent'] = $key['publicExponent']->copy(); - break; - case isset($key[0]): - $components['publicExponent'] = $key[0]->copy(); - } - switch (true) { - case isset($key['n']): - $components['modulus'] = $key['n']->copy(); - break; - case isset($key['modulo']): - $components['modulus'] = $key['modulo']->copy(); - break; - case isset($key['modulus']): - $components['modulus'] = $key['modulus']->copy(); - break; - case isset($key[1]): - $components['modulus'] = $key[1]->copy(); - } - return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false; - case self::PRIVATE_FORMAT_PKCS1: - case self::PRIVATE_FORMAT_PKCS8: - case self::PUBLIC_FORMAT_PKCS1: - /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is - "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to - protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding - two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: - - http://tools.ietf.org/html/rfc1421#section-4.6.1.1 - http://tools.ietf.org/html/rfc1421#section-4.6.1.3 - - DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. - DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation - function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's - own implementation. ie. the implementation *is* the standard and any bugs that may exist in that - implementation are part of the standard, as well. - - * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ - if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { - $iv = pack('H*', trim($matches[2])); - $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key - $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8))); - // remove the Proc-Type / DEK-Info sections as they're no longer needed - $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); - $ciphertext = $this->_extractBER($key); - if ($ciphertext === false) { - $ciphertext = $key; - } - switch ($matches[1]) { - case 'AES-256-CBC': - $crypto = new AES(); - break; - case 'AES-128-CBC': - $symkey = substr($symkey, 0, 16); - $crypto = new AES(); - break; - case 'DES-EDE3-CFB': - $crypto = new TripleDES(Base::MODE_CFB); - break; - case 'DES-EDE3-CBC': - $symkey = substr($symkey, 0, 24); - $crypto = new TripleDES(); - break; - case 'DES-CBC': - $crypto = new DES(); - break; - default: - return false; - } - $crypto->setKey($symkey); - $crypto->setIV($iv); - $decoded = $crypto->decrypt($ciphertext); - } else { - $decoded = $this->_extractBER($key); - } - - if ($decoded !== false) { - $key = $decoded; - } - - $components = array(); - - if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { - return false; - } - if ($this->_decodeLength($key) != strlen($key)) { - return false; - } - - $tag = ord($this->_string_shift($key)); - /* intended for keys for which OpenSSL's asn1parse returns the following: - - 0:d=0 hl=4 l= 631 cons: SEQUENCE - 4:d=1 hl=2 l= 1 prim: INTEGER :00 - 7:d=1 hl=2 l= 13 cons: SEQUENCE - 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption - 20:d=2 hl=2 l= 0 prim: NULL - 22:d=1 hl=4 l= 609 prim: OCTET STRING - - ie. PKCS8 keys*/ - - if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") { - $this->_string_shift($key, 3); - $tag = self::ASN1_SEQUENCE; - } - - if ($tag == self::ASN1_SEQUENCE) { - $temp = $this->_string_shift($key, $this->_decodeLength($key)); - if (ord($this->_string_shift($temp)) != self::ASN1_OBJECT) { - return false; - } - $length = $this->_decodeLength($temp); - switch ($this->_string_shift($temp, $length)) { - case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption - case "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A": // rsaPSS - break; - case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC - /* - PBEParameter ::= SEQUENCE { - salt OCTET STRING (SIZE(8)), - iterationCount INTEGER } - */ - if (ord($this->_string_shift($temp)) != self::ASN1_SEQUENCE) { - return false; - } - if ($this->_decodeLength($temp) != strlen($temp)) { - return false; - } - $this->_string_shift($temp); // assume it's an octet string - $salt = $this->_string_shift($temp, $this->_decodeLength($temp)); - if (ord($this->_string_shift($temp)) != self::ASN1_INTEGER) { - return false; - } - $this->_decodeLength($temp); - list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT)); - $this->_string_shift($key); // assume it's an octet string - $length = $this->_decodeLength($key); - if (strlen($key) != $length) { - return false; - } - - $crypto = new DES(); - $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); - $key = $crypto->decrypt($key); - if ($key === false) { - return false; - } - return $this->_parseKey($key, self::PRIVATE_FORMAT_PKCS1); - default: - return false; - } - /* intended for keys for which OpenSSL's asn1parse returns the following: - - 0:d=0 hl=4 l= 290 cons: SEQUENCE - 4:d=1 hl=2 l= 13 cons: SEQUENCE - 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption - 17:d=2 hl=2 l= 0 prim: NULL - 19:d=1 hl=4 l= 271 prim: BIT STRING */ - $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag - $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length - // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of - // unused bits in the final subsequent octet. The number shall be in the range zero to seven." - // -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2) - if ($tag == self::ASN1_BITSTRING) { - $this->_string_shift($key); - } - if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { - return false; - } - if ($this->_decodeLength($key) != strlen($key)) { - return false; - } - $tag = ord($this->_string_shift($key)); - } - if ($tag != self::ASN1_INTEGER) { - return false; - } - - $length = $this->_decodeLength($key); - $temp = $this->_string_shift($key, $length); - if (strlen($temp) != 1 || ord($temp) > 2) { - $components['modulus'] = new BigInteger($temp, 256); - $this->_string_shift($key); // skip over self::ASN1_INTEGER - $length = $this->_decodeLength($key); - $components[$type == self::PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256); - - return $components; - } - if (ord($this->_string_shift($key)) != self::ASN1_INTEGER) { - return false; - } - $length = $this->_decodeLength($key); - $components['modulus'] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['publicExponent'] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['primes'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256)); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['exponents'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256)); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($key, $length), 256)); - - if (!empty($key)) { - if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { - return false; - } - $this->_decodeLength($key); - while (!empty($key)) { - if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) { - return false; - } - $this->_decodeLength($key); - $key = substr($key, 1); - $length = $this->_decodeLength($key); - $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256); - $this->_string_shift($key); - $length = $this->_decodeLength($key); - $components['coefficients'][] = new BigInteger($this->_string_shift($key, $length), 256); - } - } - - return $components; - case self::PUBLIC_FORMAT_OPENSSH: - $parts = explode(' ', $key, 3); - - $key = isset($parts[1]) ? base64_decode($parts[1]) : false; - if ($key === false) { - return false; - } - - $comment = isset($parts[2]) ? $parts[2] : false; - - $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa"; - - if (strlen($key) <= 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($key, 4))); - $publicExponent = new BigInteger($this->_string_shift($key, $length), -256); - if (strlen($key) <= 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($key, 4))); - $modulus = new BigInteger($this->_string_shift($key, $length), -256); - - if ($cleanup && strlen($key)) { - if (strlen($key) <= 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($key, 4))); - $realModulus = new BigInteger($this->_string_shift($key, $length), -256); - return strlen($key) ? false : array( - 'modulus' => $realModulus, - 'publicExponent' => $modulus, - 'comment' => $comment - ); - } else { - return strlen($key) ? false : array( - 'modulus' => $modulus, - 'publicExponent' => $publicExponent, - 'comment' => $comment - ); - } - // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue - // http://en.wikipedia.org/wiki/XML_Signature - case self::PRIVATE_FORMAT_XML: - case self::PUBLIC_FORMAT_XML: - $this->components = array(); - - $xml = xml_parser_create('UTF-8'); - xml_set_object($xml, $this); - xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler'); - xml_set_character_data_handler($xml, '_data_handler'); - // add to account for "dangling" tags like ... that are sometimes added - if (!xml_parse($xml, '' . $key . '')) { - xml_parser_free($xml); - unset($xml); - return false; - } - - xml_parser_free($xml); - unset($xml); - - return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false; - // from PuTTY's SSHPUBK.C - case self::PRIVATE_FORMAT_PUTTY: - $components = array(); - $key = preg_split('#\r\n|\r|\n#', $key); - $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0])); - if ($type != 'ssh-rsa') { - return false; - } - $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); - $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); - - $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); - $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); - $public = substr($public, 11); - extract(unpack('Nlength', $this->_string_shift($public, 4))); - $components['publicExponent'] = new BigInteger($this->_string_shift($public, $length), -256); - extract(unpack('Nlength', $this->_string_shift($public, 4))); - $components['modulus'] = new BigInteger($this->_string_shift($public, $length), -256); - - $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4])); - $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength)))); - - switch ($encryption) { - case 'aes256-cbc': - $symkey = ''; - $sequence = 0; - while (strlen($symkey) < 32) { - $temp = pack('Na*', $sequence++, $this->password); - $symkey.= pack('H*', sha1($temp)); - } - $symkey = substr($symkey, 0, 32); - $crypto = new AES(); - } - - if ($encryption != 'none') { - $crypto->setKey($symkey); - $crypto->disablePadding(); - $private = $crypto->decrypt($private); - if ($private === false) { - return false; - } - } - - extract(unpack('Nlength', $this->_string_shift($private, 4))); - if (strlen($private) < $length) { - return false; - } - $components['privateExponent'] = new BigInteger($this->_string_shift($private, $length), -256); - extract(unpack('Nlength', $this->_string_shift($private, 4))); - if (strlen($private) < $length) { - return false; - } - $components['primes'] = array(1 => new BigInteger($this->_string_shift($private, $length), -256)); - extract(unpack('Nlength', $this->_string_shift($private, 4))); - if (strlen($private) < $length) { - return false; - } - $components['primes'][] = new BigInteger($this->_string_shift($private, $length), -256); - - $temp = $components['primes'][1]->subtract($this->one); - $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp)); - $temp = $components['primes'][2]->subtract($this->one); - $components['exponents'][] = $components['publicExponent']->modInverse($temp); - - extract(unpack('Nlength', $this->_string_shift($private, 4))); - if (strlen($private) < $length) { - return false; - } - $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($private, $length), -256)); - - return $components; - case self::PRIVATE_FORMAT_OPENSSH: - $components = array(); - $decoded = $this->_extractBER($key); - $magic = $this->_string_shift($decoded, 15); - if ($magic !== "openssh-key-v1\0") { - return false; - } - $options = $this->_string_shift($decoded, 24); - // \0\0\0\4none = ciphername - // \0\0\0\4none = kdfname - // \0\0\0\0 = kdfoptions - // \0\0\0\1 = numkeys - if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") { - return false; - } - extract(unpack('Nlength', $this->_string_shift($decoded, 4))); - if (strlen($decoded) < $length) { - return false; - } - $publicKey = $this->_string_shift($decoded, $length); - extract(unpack('Nlength', $this->_string_shift($decoded, 4))); - if (strlen($decoded) < $length) { - return false; - } - $paddedKey = $this->_string_shift($decoded, $length); - - if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") { - return false; - } - - $checkint1 = $this->_string_shift($paddedKey, 4); - $checkint2 = $this->_string_shift($paddedKey, 4); - if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) { - return false; - } - - if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") { - return false; - } - - $values = array( - &$components['modulus'], - &$components['publicExponent'], - &$components['privateExponent'], - &$components['coefficients'][2], - &$components['primes'][1], - &$components['primes'][2] - ); - - foreach ($values as &$value) { - extract(unpack('Nlength', $this->_string_shift($paddedKey, 4))); - if (strlen($paddedKey) < $length) { - return false; - } - $value = new BigInteger($this->_string_shift($paddedKey, $length), -256); - } - - extract(unpack('Nlength', $this->_string_shift($paddedKey, 4))); - if (strlen($paddedKey) < $length) { - return false; - } - $components['comment'] = $this->_string_shift($decoded, $length); - - $temp = $components['primes'][1]->subtract($this->one); - $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp)); - $temp = $components['primes'][2]->subtract($this->one); - $components['exponents'][] = $components['publicExponent']->modInverse($temp); - - return $components; - } - - return false; - } - - /** - * Returns the key size - * - * More specifically, this returns the size of the modulo in bits. - * - * @access public - * @return int - */ - function getSize() - { - return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits()); - } - - /** - * Start Element Handler - * - * Called by xml_set_element_handler() - * - * @access private - * @param resource $parser - * @param string $name - * @param array $attribs - */ - function _start_element_handler($parser, $name, $attribs) - { - //$name = strtoupper($name); - switch ($name) { - case 'MODULUS': - $this->current = &$this->components['modulus']; - break; - case 'EXPONENT': - $this->current = &$this->components['publicExponent']; - break; - case 'P': - $this->current = &$this->components['primes'][1]; - break; - case 'Q': - $this->current = &$this->components['primes'][2]; - break; - case 'DP': - $this->current = &$this->components['exponents'][1]; - break; - case 'DQ': - $this->current = &$this->components['exponents'][2]; - break; - case 'INVERSEQ': - $this->current = &$this->components['coefficients'][2]; - break; - case 'D': - $this->current = &$this->components['privateExponent']; - } - $this->current = ''; - } - - /** - * Stop Element Handler - * - * Called by xml_set_element_handler() - * - * @access private - * @param resource $parser - * @param string $name - */ - function _stop_element_handler($parser, $name) - { - if (isset($this->current)) { - $this->current = new BigInteger(base64_decode($this->current), 256); - unset($this->current); - } - } - - /** - * Data Handler - * - * Called by xml_set_character_data_handler() - * - * @access private - * @param resource $parser - * @param string $data - */ - function _data_handler($parser, $data) - { - if (!isset($this->current) || is_object($this->current)) { - return; - } - $this->current.= trim($data); - } - - /** - * Loads a public or private key - * - * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed) - * - * @access public - * @param string|RSA|array $key - * @param bool|int $type optional - * @return bool - */ - function loadKey($key, $type = false) - { - if ($key instanceof RSA) { - $this->privateKeyFormat = $key->privateKeyFormat; - $this->publicKeyFormat = $key->publicKeyFormat; - $this->k = $key->k; - $this->hLen = $key->hLen; - $this->sLen = $key->sLen; - $this->mgfHLen = $key->mgfHLen; - $this->encryptionMode = $key->encryptionMode; - $this->signatureMode = $key->signatureMode; - $this->password = $key->password; - $this->configFile = $key->configFile; - $this->comment = $key->comment; - - if (is_object($key->hash)) { - $this->hash = new Hash($key->hash->getHash()); - } - if (is_object($key->mgfHash)) { - $this->mgfHash = new Hash($key->mgfHash->getHash()); - } - - if (is_object($key->modulus)) { - $this->modulus = $key->modulus->copy(); - } - if (is_object($key->exponent)) { - $this->exponent = $key->exponent->copy(); - } - if (is_object($key->publicExponent)) { - $this->publicExponent = $key->publicExponent->copy(); - } - - $this->primes = array(); - $this->exponents = array(); - $this->coefficients = array(); - - foreach ($this->primes as $prime) { - $this->primes[] = $prime->copy(); - } - foreach ($this->exponents as $exponent) { - $this->exponents[] = $exponent->copy(); - } - foreach ($this->coefficients as $coefficient) { - $this->coefficients[] = $coefficient->copy(); - } - - return true; - } - - if ($type === false) { - $types = array( - self::PUBLIC_FORMAT_RAW, - self::PRIVATE_FORMAT_PKCS1, - self::PRIVATE_FORMAT_XML, - self::PRIVATE_FORMAT_PUTTY, - self::PUBLIC_FORMAT_OPENSSH, - self::PRIVATE_FORMAT_OPENSSH - ); - foreach ($types as $type) { - $components = $this->_parseKey($key, $type); - if ($components !== false) { - break; - } - } - } else { - $components = $this->_parseKey($key, $type); - } - - if ($components === false) { - $this->comment = null; - $this->modulus = null; - $this->k = null; - $this->exponent = null; - $this->primes = null; - $this->exponents = null; - $this->coefficients = null; - $this->publicExponent = null; - - return false; - } - - if (isset($components['comment']) && $components['comment'] !== false) { - $this->comment = $components['comment']; - } - $this->modulus = $components['modulus']; - $this->k = strlen($this->modulus->toBytes()); - $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent']; - if (isset($components['primes'])) { - $this->primes = $components['primes']; - $this->exponents = $components['exponents']; - $this->coefficients = $components['coefficients']; - $this->publicExponent = $components['publicExponent']; - } else { - $this->primes = array(); - $this->exponents = array(); - $this->coefficients = array(); - $this->publicExponent = false; - } - - switch ($type) { - case self::PUBLIC_FORMAT_OPENSSH: - case self::PUBLIC_FORMAT_RAW: - $this->setPublicKey(); - break; - case self::PRIVATE_FORMAT_PKCS1: - switch (true) { - case strpos($key, '-BEGIN PUBLIC KEY-') !== false: - case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false: - $this->setPublicKey(); - } - } - - return true; - } - - /** - * Sets the password - * - * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. - * Or rather, pass in $password such that empty($password) && !is_string($password) is true. - * - * @see self::createKey() - * @see self::loadKey() - * @access public - * @param string $password - */ - function setPassword($password = false) - { - $this->password = $password; - } - - /** - * Defines the public key - * - * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when - * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a - * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys - * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public - * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used - * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being - * public. - * - * Do note that when a new key is loaded the index will be cleared. - * - * Returns true on success, false on failure - * - * @see self::getPublicKey() - * @access public - * @param string $key optional - * @param int $type optional - * @return bool - */ - function setPublicKey($key = false, $type = false) - { - // if a public key has already been loaded return false - if (!empty($this->publicExponent)) { - return false; - } - - if ($key === false && !empty($this->modulus)) { - $this->publicExponent = $this->exponent; - return true; - } - - if ($type === false) { - $types = array( - self::PUBLIC_FORMAT_RAW, - self::PUBLIC_FORMAT_PKCS1, - self::PUBLIC_FORMAT_XML, - self::PUBLIC_FORMAT_OPENSSH - ); - foreach ($types as $type) { - $components = $this->_parseKey($key, $type); - if ($components !== false) { - break; - } - } - } else { - $components = $this->_parseKey($key, $type); - } - - if ($components === false) { - return false; - } - - if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) { - $this->modulus = $components['modulus']; - $this->exponent = $this->publicExponent = $components['publicExponent']; - return true; - } - - $this->publicExponent = $components['publicExponent']; - - return true; - } - - /** - * Defines the private key - * - * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force - * phpseclib to treat the key as a private key. This function will do that. - * - * Do note that when a new key is loaded the index will be cleared. - * - * Returns true on success, false on failure - * - * @see self::getPublicKey() - * @access public - * @param string $key optional - * @param int $type optional - * @return bool - */ - function setPrivateKey($key = false, $type = false) - { - if ($key === false && !empty($this->publicExponent)) { - $this->publicExponent = false; - return true; - } - - $rsa = new RSA(); - if (!$rsa->loadKey($key, $type)) { - return false; - } - $rsa->publicExponent = false; - - // don't overwrite the old key if the new key is invalid - $this->loadKey($rsa); - return true; - } - - /** - * Returns the public key - * - * The public key is only returned under two circumstances - if the private key had the public key embedded within it - * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this - * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. - * - * @see self::getPublicKey() - * @access public - * @param int $type optional - */ - function getPublicKey($type = self::PUBLIC_FORMAT_PKCS8) - { - if (empty($this->modulus) || empty($this->publicExponent)) { - return false; - } - - $oldFormat = $this->publicKeyFormat; - $this->publicKeyFormat = $type; - $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent); - $this->publicKeyFormat = $oldFormat; - return $temp; - } - - /** - * Returns the public key's fingerprint - * - * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is - * no public key currently loaded, false is returned. - * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) - * - * @access public - * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned - * for invalid values. - * @return mixed - */ - function getPublicKeyFingerprint($algorithm = 'md5') - { - if (empty($this->modulus) || empty($this->publicExponent)) { - return false; - } - - $modulus = $this->modulus->toBytes(true); - $publicExponent = $this->publicExponent->toBytes(true); - - $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus); - - switch ($algorithm) { - case 'sha256': - $hash = new Hash('sha256'); - $base = base64_encode($hash->hash($RSAPublicKey)); - return substr($base, 0, strlen($base) - 1); - case 'md5': - return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1); - default: - return false; - } - } - - /** - * Returns the private key - * - * The private key is only returned if the currently loaded key contains the constituent prime numbers. - * - * @see self::getPublicKey() - * @access public - * @param int $type optional - * @return mixed - */ - function getPrivateKey($type = self::PUBLIC_FORMAT_PKCS1) - { - if (empty($this->primes)) { - return false; - } - - $oldFormat = $this->privateKeyFormat; - $this->privateKeyFormat = $type; - $temp = $this->_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients); - $this->privateKeyFormat = $oldFormat; - return $temp; - } - - /** - * Returns a minimalistic private key - * - * Returns the private key without the prime number constituants. Structurally identical to a public key that - * hasn't been set as the public key - * - * @see self::getPrivateKey() - * @access private - * @param int $mode optional - */ - function _getPrivatePublicKey($mode = self::PUBLIC_FORMAT_PKCS8) - { - if (empty($this->modulus) || empty($this->exponent)) { - return false; - } - - $oldFormat = $this->publicKeyFormat; - $this->publicKeyFormat = $mode; - $temp = $this->_convertPublicKey($this->modulus, $this->exponent); - $this->publicKeyFormat = $oldFormat; - return $temp; - } - - /** - * __toString() magic method - * - * @access public - * @return string - */ - function __toString() - { - $key = $this->getPrivateKey($this->privateKeyFormat); - if ($key !== false) { - return $key; - } - $key = $this->_getPrivatePublicKey($this->publicKeyFormat); - return $key !== false ? $key : ''; - } - - /** - * __clone() magic method - * - * @access public - * @return Crypt_RSA - */ - function __clone() - { - $key = new RSA(); - $key->loadKey($this); - return $key; - } - - /** - * Generates the smallest and largest numbers requiring $bits bits - * - * @access private - * @param int $bits - * @return array - */ - function _generateMinMax($bits) - { - $bytes = $bits >> 3; - $min = str_repeat(chr(0), $bytes); - $max = str_repeat(chr(0xFF), $bytes); - $msb = $bits & 7; - if ($msb) { - $min = chr(1 << ($msb - 1)) . $min; - $max = chr((1 << $msb) - 1) . $max; - } else { - $min[0] = chr(0x80); - } - - return array( - 'min' => new BigInteger($min, 256), - 'max' => new BigInteger($max, 256) - ); - } - - /** - * DER-decode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @access private - * @param string $string - * @return int - */ - function _decodeLength(&$string) - { - $length = ord($this->_string_shift($string)); - if ($length & 0x80) { // definite length, long form - $length&= 0x7F; - $temp = $this->_string_shift($string, $length); - list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); - } - return $length; - } - - /** - * DER-encode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @access private - * @param int $length - * @return string - */ - function _encodeLength($length) - { - if ($length <= 0x7F) { - return chr($length); - } - - $temp = ltrim(pack('N', $length), chr(0)); - return pack('Ca*', 0x80 | strlen($temp), $temp); - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } - - /** - * Determines the private key format - * - * @see self::createKey() - * @access public - * @param int $format - */ - function setPrivateKeyFormat($format) - { - $this->privateKeyFormat = $format; - } - - /** - * Determines the public key format - * - * @see self::createKey() - * @access public - * @param int $format - */ - function setPublicKeyFormat($format) - { - $this->publicKeyFormat = $format; - } - - /** - * Determines which hashing function should be used - * - * Used with signature production / verification and (if the encryption mode is self::ENCRYPTION_OAEP) encryption and - * decryption. If $hash isn't supported, sha1 is used. - * - * @access public - * @param string $hash - */ - function setHash($hash) - { - // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. - switch ($hash) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha256': - case 'sha384': - case 'sha512': - $this->hash = new Hash($hash); - $this->hashName = $hash; - break; - default: - $this->hash = new Hash('sha1'); - $this->hashName = 'sha1'; - } - $this->hLen = $this->hash->getLength(); - } - - /** - * Determines which hashing function should be used for the mask generation function - * - * The mask generation function is used by self::ENCRYPTION_OAEP and self::SIGNATURE_PSS and although it's - * best if Hash and MGFHash are set to the same thing this is not a requirement. - * - * @access public - * @param string $hash - */ - function setMGFHash($hash) - { - // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. - switch ($hash) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha256': - case 'sha384': - case 'sha512': - $this->mgfHash = new Hash($hash); - break; - default: - $this->mgfHash = new Hash('sha1'); - } - $this->mgfHLen = $this->mgfHash->getLength(); - } - - /** - * Determines the salt length - * - * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: - * - * Typical salt lengths in octets are hLen (the length of the output - * of the hash function Hash) and 0. - * - * @access public - * @param int $sLen - */ - function setSaltLength($sLen) - { - $this->sLen = $sLen; - } - - /** - * Integer-to-Octet-String primitive - * - * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. - * - * @access private - * @param \phpseclib\Math\BigInteger $x - * @param int $xLen - * @return string - */ - function _i2osp($x, $xLen) - { - $x = $x->toBytes(); - if (strlen($x) > $xLen) { - user_error('Integer too large'); - return false; - } - return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); - } - - /** - * Octet-String-to-Integer primitive - * - * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. - * - * @access private - * @param int|string|resource $x - * @return \phpseclib\Math\BigInteger - */ - function _os2ip($x) - { - return new BigInteger($x, 256); - } - - /** - * Exponentiate with or without Chinese Remainder Theorem - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}. - * - * @access private - * @param \phpseclib\Math\BigInteger $x - * @return \phpseclib\Math\BigInteger - */ - function _exponentiate($x) - { - switch (true) { - case empty($this->primes): - case $this->primes[1]->equals($this->zero): - case empty($this->coefficients): - case $this->coefficients[2]->equals($this->zero): - case empty($this->exponents): - case $this->exponents[1]->equals($this->zero): - return $x->modPow($this->exponent, $this->modulus); - } - - $num_primes = count($this->primes); - - if (defined('CRYPT_RSA_DISABLE_BLINDING')) { - $m_i = array( - 1 => $x->modPow($this->exponents[1], $this->primes[1]), - 2 => $x->modPow($this->exponents[2], $this->primes[2]) - ); - $h = $m_i[1]->subtract($m_i[2]); - $h = $h->multiply($this->coefficients[2]); - list(, $h) = $h->divide($this->primes[1]); - $m = $m_i[2]->add($h->multiply($this->primes[2])); - - $r = $this->primes[1]; - for ($i = 3; $i <= $num_primes; $i++) { - $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); - - $r = $r->multiply($this->primes[$i - 1]); - - $h = $m_i->subtract($m); - $h = $h->multiply($this->coefficients[$i]); - list(, $h) = $h->divide($this->primes[$i]); - - $m = $m->add($r->multiply($h)); - } - } else { - $smallest = $this->primes[1]; - for ($i = 2; $i <= $num_primes; $i++) { - if ($smallest->compare($this->primes[$i]) > 0) { - $smallest = $this->primes[$i]; - } - } - - $one = new BigInteger(1); - - $r = $one->random($one, $smallest->subtract($one)); - - $m_i = array( - 1 => $this->_blind($x, $r, 1), - 2 => $this->_blind($x, $r, 2) - ); - $h = $m_i[1]->subtract($m_i[2]); - $h = $h->multiply($this->coefficients[2]); - list(, $h) = $h->divide($this->primes[1]); - $m = $m_i[2]->add($h->multiply($this->primes[2])); - - $r = $this->primes[1]; - for ($i = 3; $i <= $num_primes; $i++) { - $m_i = $this->_blind($x, $r, $i); - - $r = $r->multiply($this->primes[$i - 1]); - - $h = $m_i->subtract($m); - $h = $h->multiply($this->coefficients[$i]); - list(, $h) = $h->divide($this->primes[$i]); - - $m = $m->add($r->multiply($h)); - } - } - - return $m; - } - - /** - * Performs RSA Blinding - * - * Protects against timing attacks by employing RSA Blinding. - * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) - * - * @access private - * @param \phpseclib\Math\BigInteger $x - * @param \phpseclib\Math\BigInteger $r - * @param int $i - * @return \phpseclib\Math\BigInteger - */ - function _blind($x, $r, $i) - { - $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); - $x = $x->modPow($this->exponents[$i], $this->primes[$i]); - - $r = $r->modInverse($this->primes[$i]); - $x = $x->multiply($r); - list(, $x) = $x->divide($this->primes[$i]); - - return $x; - } - - /** - * Performs blinded RSA equality testing - * - * Protects against a particular type of timing attack described. - * - * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)} - * - * Thanks for the heads up singpolyma! - * - * @access private - * @param string $x - * @param string $y - * @return bool - */ - function _equals($x, $y) - { - if (function_exists('hash_equals')) { - return hash_equals($x, $y); - } - - if (strlen($x) != strlen($y)) { - return false; - } - - $result = "\0"; - $x^= $y; - for ($i = 0; $i < strlen($x); $i++) { - $result|= $x[$i]; - } - - return $result === "\0"; - } - - /** - * RSAEP - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. - * - * @access private - * @param \phpseclib\Math\BigInteger $m - * @return \phpseclib\Math\BigInteger - */ - function _rsaep($m) - { - if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { - user_error('Message representative out of range'); - return false; - } - return $this->_exponentiate($m); - } - - /** - * RSADP - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. - * - * @access private - * @param \phpseclib\Math\BigInteger $c - * @return \phpseclib\Math\BigInteger - */ - function _rsadp($c) - { - if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) { - user_error('Ciphertext representative out of range'); - return false; - } - return $this->_exponentiate($c); - } - - /** - * RSASP1 - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. - * - * @access private - * @param \phpseclib\Math\BigInteger $m - * @return \phpseclib\Math\BigInteger - */ - function _rsasp1($m) - { - if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { - user_error('Message representative out of range'); - return false; - } - return $this->_exponentiate($m); - } - - /** - * RSAVP1 - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. - * - * @access private - * @param \phpseclib\Math\BigInteger $s - * @return \phpseclib\Math\BigInteger - */ - function _rsavp1($s) - { - if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) { - user_error('Signature representative out of range'); - return false; - } - return $this->_exponentiate($s); - } - - /** - * MGF1 - * - * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. - * - * @access private - * @param string $mgfSeed - * @param int $maskLen - * @return string - */ - function _mgf1($mgfSeed, $maskLen) - { - // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. - - $t = ''; - $count = ceil($maskLen / $this->mgfHLen); - for ($i = 0; $i < $count; $i++) { - $c = pack('N', $i); - $t.= $this->mgfHash->hash($mgfSeed . $c); - } - - return substr($t, 0, $maskLen); - } - - /** - * RSAES-OAEP-ENCRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and - * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. - * - * @access private - * @param string $m - * @param string $l - * @return string - */ - function _rsaes_oaep_encrypt($m, $l = '') - { - $mLen = strlen($m); - - // Length checking - - // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - if ($mLen > $this->k - 2 * $this->hLen - 2) { - user_error('Message too long'); - return false; - } - - // EME-OAEP encoding - - $lHash = $this->hash->hash($l); - $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); - $db = $lHash . $ps . chr(1) . $m; - $seed = Random::string($this->hLen); - $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1); - $maskedDB = $db ^ $dbMask; - $seedMask = $this->_mgf1($maskedDB, $this->hLen); - $maskedSeed = $seed ^ $seedMask; - $em = chr(0) . $maskedSeed . $maskedDB; - - // RSA encryption - - $m = $this->_os2ip($em); - $c = $this->_rsaep($m); - $c = $this->_i2osp($c, $this->k); - - // Output the ciphertext C - - return $c; - } - - /** - * RSAES-OAEP-DECRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error - * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: - * - * Note. Care must be taken to ensure that an opponent cannot - * distinguish the different error conditions in Step 3.g, whether by - * error message or timing, or, more generally, learn partial - * information about the encoded message EM. Otherwise an opponent may - * be able to obtain useful information about the decryption of the - * ciphertext C, leading to a chosen-ciphertext attack such as the one - * observed by Manger [36]. - * - * As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: - * - * Both the encryption and the decryption operations of RSAES-OAEP take - * the value of a label L as input. In this version of PKCS #1, L is - * the empty string; other uses of the label are outside the scope of - * this document. - * - * @access private - * @param string $c - * @param string $l - * @return string - */ - function _rsaes_oaep_decrypt($c, $l = '') - { - // Length checking - - // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { - user_error('Decryption error'); - return false; - } - - // RSA decryption - - $c = $this->_os2ip($c); - $m = $this->_rsadp($c); - if ($m === false) { - user_error('Decryption error'); - return false; - } - $em = $this->_i2osp($m, $this->k); - - // EME-OAEP decoding - - $lHash = $this->hash->hash($l); - $y = ord($em[0]); - $maskedSeed = substr($em, 1, $this->hLen); - $maskedDB = substr($em, $this->hLen + 1); - $seedMask = $this->_mgf1($maskedDB, $this->hLen); - $seed = $maskedSeed ^ $seedMask; - $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1); - $db = $maskedDB ^ $dbMask; - $lHash2 = substr($db, 0, $this->hLen); - $m = substr($db, $this->hLen); - $hashesMatch = $this->_equals($lHash, $lHash2); - $leadingZeros = 1; - $patternMatch = 0; - $offset = 0; - for ($i = 0; $i < strlen($m); $i++) { - $patternMatch|= $leadingZeros & ($m[$i] === "\1"); - $leadingZeros&= $m[$i] === "\0"; - $offset+= $patternMatch ? 0 : 1; - } - - // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation - // to protect against timing attacks - if (!$hashesMatch | !$patternMatch) { - user_error('Decryption error'); - return false; - } - - // Output the message M - - return substr($m, $offset + 1); - } - - /** - * Raw Encryption / Decryption - * - * Doesn't use padding and is not recommended. - * - * @access private - * @param string $m - * @return string - */ - function _raw_encrypt($m) - { - $temp = $this->_os2ip($m); - $temp = $this->_rsaep($temp); - return $this->_i2osp($temp, $this->k); - } - - /** - * RSAES-PKCS1-V1_5-ENCRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. - * - * @access private - * @param string $m - * @return string - */ - function _rsaes_pkcs1_v1_5_encrypt($m) - { - $mLen = strlen($m); - - // Length checking - - if ($mLen > $this->k - 11) { - user_error('Message too long'); - return false; - } - - // EME-PKCS1-v1_5 encoding - - $psLen = $this->k - $mLen - 3; - $ps = ''; - while (strlen($ps) != $psLen) { - $temp = Random::string($psLen - strlen($ps)); - $temp = str_replace("\x00", '', $temp); - $ps.= $temp; - } - $type = 2; - // see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done - if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) { - $type = 1; - // "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF" - $ps = str_repeat("\xFF", $psLen); - } - $em = chr(0) . chr($type) . $ps . chr(0) . $m; - - // RSA encryption - $m = $this->_os2ip($em); - $c = $this->_rsaep($m); - $c = $this->_i2osp($c, $this->k); - - // Output the ciphertext C - - return $c; - } - - /** - * RSAES-PKCS1-V1_5-DECRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. - * - * For compatibility purposes, this function departs slightly from the description given in RFC3447. - * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the - * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the - * public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed - * to be 2 regardless of which key is used. For compatibility purposes, we'll just check to make sure the - * second byte is 2 or less. If it is, we'll accept the decrypted string as valid. - * - * As a consequence of this, a private key encrypted ciphertext produced with \phpseclib\Crypt\RSA may not decrypt - * with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but - * not private key encrypted ciphertext's. - * - * @access private - * @param string $c - * @return string - */ - function _rsaes_pkcs1_v1_5_decrypt($c) - { - // Length checking - - if (strlen($c) != $this->k) { // or if k < 11 - user_error('Decryption error'); - return false; - } - - // RSA decryption - - $c = $this->_os2ip($c); - $m = $this->_rsadp($c); - - if ($m === false) { - user_error('Decryption error'); - return false; - } - $em = $this->_i2osp($m, $this->k); - - // EME-PKCS1-v1_5 decoding - - if (ord($em[0]) != 0 || ord($em[1]) > 2) { - user_error('Decryption error'); - return false; - } - - $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); - $m = substr($em, strlen($ps) + 3); - - if (strlen($ps) < 8) { - user_error('Decryption error'); - return false; - } - - // Output M - - return $m; - } - - /** - * EMSA-PSS-ENCODE - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. - * - * @access private - * @param string $m - * @param int $emBits - */ - function _emsa_pss_encode($m, $emBits) - { - // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) - $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; - - $mHash = $this->hash->hash($m); - if ($emLen < $this->hLen + $sLen + 2) { - user_error('Encoding error'); - return false; - } - - $salt = Random::string($sLen); - $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; - $h = $this->hash->hash($m2); - $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); - $db = $ps . chr(1) . $salt; - $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1); - $maskedDB = $db ^ $dbMask; - $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; - $em = $maskedDB . $h . chr(0xBC); - - return $em; - } - - /** - * EMSA-PSS-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. - * - * @access private - * @param string $m - * @param string $em - * @param int $emBits - * @return string - */ - function _emsa_pss_verify($m, $em, $emBits) - { - // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); - $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; - - $mHash = $this->hash->hash($m); - if ($emLen < $this->hLen + $sLen + 2) { - return false; - } - - if ($em[strlen($em) - 1] != chr(0xBC)) { - return false; - } - - $maskedDB = substr($em, 0, -$this->hLen - 1); - $h = substr($em, -$this->hLen - 1, $this->hLen); - $temp = chr(0xFF << ($emBits & 7)); - if ((~$maskedDB[0] & $temp) != $temp) { - return false; - } - $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1); - $db = $maskedDB ^ $dbMask; - $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; - $temp = $emLen - $this->hLen - $sLen - 2; - if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { - return false; - } - $salt = substr($db, $temp + 1); // should be $sLen long - $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; - $h2 = $this->hash->hash($m2); - return $this->_equals($h, $h2); - } - - /** - * RSASSA-PSS-SIGN - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. - * - * @access private - * @param string $m - * @return string - */ - function _rsassa_pss_sign($m) - { - // EMSA-PSS encoding - - $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1); - - // RSA signature - - $m = $this->_os2ip($em); - $s = $this->_rsasp1($m); - $s = $this->_i2osp($s, $this->k); - - // Output the signature S - - return $s; - } - - /** - * RSASSA-PSS-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. - * - * @access private - * @param string $m - * @param string $s - * @return string - */ - function _rsassa_pss_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - user_error('Invalid signature'); - return false; - } - - // RSA verification - - $modBits = strlen($this->modulus->toBits()); - - $s2 = $this->_os2ip($s); - $m2 = $this->_rsavp1($s2); - if ($m2 === false) { - user_error('Invalid signature'); - return false; - } - $em = $this->_i2osp($m2, $this->k); - if ($em === false) { - user_error('Invalid signature'); - return false; - } - - // EMSA-PSS verification - - return $this->_emsa_pss_verify($m, $em, $modBits - 1); - } - - /** - * EMSA-PKCS1-V1_5-ENCODE - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. - * - * @access private - * @param string $m - * @param int $emLen - * @return string - */ - function _emsa_pkcs1_v1_5_encode($m, $emLen) - { - $h = $this->hash->hash($m); - if ($h === false) { - return false; - } - - // see http://tools.ietf.org/html/rfc3447#page-43 - switch ($this->hashName) { - case 'md2': - $t = pack('H*', '3020300c06082a864886f70d020205000410'); - break; - case 'md5': - $t = pack('H*', '3020300c06082a864886f70d020505000410'); - break; - case 'sha1': - $t = pack('H*', '3021300906052b0e03021a05000414'); - break; - case 'sha256': - $t = pack('H*', '3031300d060960864801650304020105000420'); - break; - case 'sha384': - $t = pack('H*', '3041300d060960864801650304020205000430'); - break; - case 'sha512': - $t = pack('H*', '3051300d060960864801650304020305000440'); - } - $t.= $h; - $tLen = strlen($t); - - if ($emLen < $tLen + 11) { - user_error('Intended encoded message length too short'); - return false; - } - - $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); - - $em = "\0\1$ps\0$t"; - - return $em; - } - - /** - * EMSA-PKCS1-V1_5-ENCODE (without NULL) - * - * Quoting https://tools.ietf.org/html/rfc8017#page-65, - * - * "The parameters field associated with id-sha1, id-sha224, id-sha256, - * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should - * generally be omitted, but if present, it shall have a value of type - * NULL" - * - * @access private - * @param string $m - * @param int $emLen - * @return string - */ - function _emsa_pkcs1_v1_5_encode_without_null($m, $emLen) - { - $h = $this->hash->hash($m); - if ($h === false) { - return false; - } - - switch ($this->hashName) { - case 'sha1': - $t = pack('H*', '301f300706052b0e03021a0414'); - break; - case 'sha256': - $t = pack('H*', '302f300b06096086480165030402010420'); - break; - case 'sha384': - $t = pack('H*', '303f300b06096086480165030402020430'); - break; - case 'sha512': - $t = pack('H*', '304f300b06096086480165030402030440'); - break; - default: - return false; - } - $t.= $h; - $tLen = strlen($t); - - if ($emLen < $tLen + 11) { - user_error('Intended encoded message length too short'); - return false; - } - - $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); - - $em = "\0\1$ps\0$t"; - - return $em; - } - - /** - * RSASSA-PKCS1-V1_5-SIGN - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. - * - * @access private - * @param string $m - * @return string - */ - function _rsassa_pkcs1_v1_5_sign($m) - { - // EMSA-PKCS1-v1_5 encoding - - $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); - if ($em === false) { - user_error('RSA modulus too short'); - return false; - } - - // RSA signature - - $m = $this->_os2ip($em); - $s = $this->_rsasp1($m); - $s = $this->_i2osp($s, $this->k); - - // Output the signature S - - return $s; - } - - /** - * RSASSA-PKCS1-V1_5-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. - * - * @access private - * @param string $m - * @param string $s - * @return string - */ - function _rsassa_pkcs1_v1_5_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - user_error('Invalid signature'); - return false; - } - - // RSA verification - - $s = $this->_os2ip($s); - $m2 = $this->_rsavp1($s); - if ($m2 === false) { - user_error('Invalid signature'); - return false; - } - $em = $this->_i2osp($m2, $this->k); - if ($em === false) { - user_error('Invalid signature'); - return false; - } - - // EMSA-PKCS1-v1_5 encoding - - $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); - $em3 = $this->_emsa_pkcs1_v1_5_encode_without_null($m, $this->k); - - if ($em2 === false && $em3 === false) { - user_error('RSA modulus too short'); - return false; - } - - // Compare - - return ($em2 !== false && $this->_equals($em, $em2)) || - ($em3 !== false && $this->_equals($em, $em3)); - } - - /** - * Set Encryption Mode - * - * Valid values include self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1. - * - * @access public - * @param int $mode - */ - function setEncryptionMode($mode) - { - $this->encryptionMode = $mode; - } - - /** - * Set Signature Mode - * - * Valid values include self::SIGNATURE_PSS and self::SIGNATURE_PKCS1 - * - * @access public - * @param int $mode - */ - function setSignatureMode($mode) - { - $this->signatureMode = $mode; - } - - /** - * Set public key comment. - * - * @access public - * @param string $comment - */ - function setComment($comment) - { - $this->comment = $comment; - } - - /** - * Get public key comment. - * - * @access public - * @return string - */ - function getComment() - { - return $this->comment; - } - - /** - * Encryption - * - * Both self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1 both place limits on how long $plaintext can be. - * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will - * be concatenated together. - * - * @see self::decrypt() - * @access public - * @param string $plaintext - * @return string - */ - function encrypt($plaintext) - { - switch ($this->encryptionMode) { - case self::ENCRYPTION_NONE: - $plaintext = str_split($plaintext, $this->k); - $ciphertext = ''; - foreach ($plaintext as $m) { - $ciphertext.= $this->_raw_encrypt($m); - } - return $ciphertext; - case self::ENCRYPTION_PKCS1: - $length = $this->k - 11; - if ($length <= 0) { - return false; - } - - $plaintext = str_split($plaintext, $length); - $ciphertext = ''; - foreach ($plaintext as $m) { - $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m); - } - return $ciphertext; - //case self::ENCRYPTION_OAEP: - default: - $length = $this->k - 2 * $this->hLen - 2; - if ($length <= 0) { - return false; - } - - $plaintext = str_split($plaintext, $length); - $ciphertext = ''; - foreach ($plaintext as $m) { - $ciphertext.= $this->_rsaes_oaep_encrypt($m); - } - return $ciphertext; - } - } - - /** - * Decryption - * - * @see self::encrypt() - * @access public - * @param string $ciphertext - * @return string - */ - function decrypt($ciphertext) - { - if ($this->k <= 0) { - return false; - } - - $ciphertext = str_split($ciphertext, $this->k); - $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT); - - $plaintext = ''; - - switch ($this->encryptionMode) { - case self::ENCRYPTION_NONE: - $decrypt = '_raw_encrypt'; - break; - case self::ENCRYPTION_PKCS1: - $decrypt = '_rsaes_pkcs1_v1_5_decrypt'; - break; - //case self::ENCRYPTION_OAEP: - default: - $decrypt = '_rsaes_oaep_decrypt'; - } - - foreach ($ciphertext as $c) { - $temp = $this->$decrypt($c); - if ($temp === false) { - return false; - } - $plaintext.= $temp; - } - - return $plaintext; - } - - /** - * Create a signature - * - * @see self::verify() - * @access public - * @param string $message - * @return string - */ - function sign($message) - { - if (empty($this->modulus) || empty($this->exponent)) { - return false; - } - - switch ($this->signatureMode) { - case self::SIGNATURE_PKCS1: - return $this->_rsassa_pkcs1_v1_5_sign($message); - //case self::SIGNATURE_PSS: - default: - return $this->_rsassa_pss_sign($message); - } - } - - /** - * Verifies a signature - * - * @see self::sign() - * @access public - * @param string $message - * @param string $signature - * @return bool - */ - function verify($message, $signature) - { - if (empty($this->modulus) || empty($this->exponent)) { - return false; - } - - switch ($this->signatureMode) { - case self::SIGNATURE_PKCS1: - return $this->_rsassa_pkcs1_v1_5_verify($message, $signature); - //case self::SIGNATURE_PSS: - default: - return $this->_rsassa_pss_verify($message, $signature); - } - } - - /** - * Extract raw BER from Base64 encoding - * - * @access private - * @param string $str - * @return string - */ - function _extractBER($str) - { - /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them - * above and beyond the ceritificate. - * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: - * - * Bag Attributes - * localKeyID: 01 00 00 00 - * subject=/O=organization/OU=org unit/CN=common name - * issuer=/O=organization/CN=common name - */ - $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); - // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff - $temp = preg_replace('#-+[^-]+-+#', '', $temp); - // remove new lines - $temp = str_replace(array("\r", "\n", ' '), '', $temp); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; - return $temp != false ? $temp : $str; - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php deleted file mode 100644 index fc24b9145..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +++ /dev/null @@ -1,3787 +0,0 @@ -> and << cannot be used, nor can the modulo operator %, - * which only supports integers. Although this fact will slow this library down, the fact that such a high - * base is being used should more than compensate. - * - * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie. - * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1) - * - * Useful resources are as follows: - * - * - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)} - * - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)} - * - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip - * - * Here's an example of how to use this library: - * - * add($b); - * - * echo $c->toString(); // outputs 5 - * ?> - * - * - * @category Math - * @package BigInteger - * @author Jim Wigginton - * @copyright 2006 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib\Math; - -use phpseclib\Crypt\Random; - -/** - * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 - * numbers. - * - * @package BigInteger - * @author Jim Wigginton - * @access public - */ -class BigInteger -{ - /**#@+ - * Reduction constants - * - * @access private - * @see BigInteger::_reduce() - */ - /** - * @see BigInteger::_montgomery() - * @see BigInteger::_prepMontgomery() - */ - const MONTGOMERY = 0; - /** - * @see BigInteger::_barrett() - */ - const BARRETT = 1; - /** - * @see BigInteger::_mod2() - */ - const POWEROF2 = 2; - /** - * @see BigInteger::_remainder() - */ - const CLASSIC = 3; - /** - * @see BigInteger::__clone() - */ - const NONE = 4; - /**#@-*/ - - /**#@+ - * Array constants - * - * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and - * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. - * - * @access private - */ - /** - * $result[self::VALUE] contains the value. - */ - const VALUE = 0; - /** - * $result[self::SIGN] contains the sign. - */ - const SIGN = 1; - /**#@-*/ - - /**#@+ - * @access private - * @see BigInteger::_montgomery() - * @see BigInteger::_barrett() - */ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - */ - const DATA = 1; - /**#@-*/ - - /**#@+ - * Mode constants. - * - * @access private - * @see BigInteger::__construct() - */ - /** - * To use the pure-PHP implementation - */ - const MODE_INTERNAL = 1; - /** - * To use the BCMath library - * - * (if enabled; otherwise, the internal implementation will be used) - */ - const MODE_BCMATH = 2; - /** - * To use the GMP library - * - * (if present; otherwise, either the BCMath or the internal implementation will be used) - */ - const MODE_GMP = 3; - /**#@-*/ - - /** - * Karatsuba Cutoff - * - * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? - * - * @access private - */ - const KARATSUBA_CUTOFF = 25; - - /**#@+ - * Static properties used by the pure-PHP implementation. - * - * @see __construct() - */ - protected static $base; - protected static $baseFull; - protected static $maxDigit; - protected static $msb; - - /** - * $max10 in greatest $max10Len satisfying - * $max10 = 10**$max10Len <= 2**$base. - */ - protected static $max10; - - /** - * $max10Len in greatest $max10Len satisfying - * $max10 = 10**$max10Len <= 2**$base. - */ - protected static $max10Len; - protected static $maxDigit2; - /**#@-*/ - - /** - * Holds the BigInteger's value. - * - * @var array - * @access private - */ - var $value; - - /** - * Holds the BigInteger's magnitude. - * - * @var bool - * @access private - */ - var $is_negative = false; - - /** - * Precision - * - * @see self::setPrecision() - * @access private - */ - var $precision = -1; - - /** - * Precision Bitmask - * - * @see self::setPrecision() - * @access private - */ - var $bitmask = false; - - /** - * Mode independent value used for serialization. - * - * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for - * a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value, - * however, $this->hex is only calculated when $this->__sleep() is called. - * - * @see self::__sleep() - * @see self::__wakeup() - * @var string - * @access private - */ - var $hex; - - /** - * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. - * - * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using - * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. - * - * Here's an example: - * - * toString(); // outputs 50 - * ?> - * - * - * @param int|string|resource $x base-10 number or base-$base number if $base set. - * @param int $base - * @return \phpseclib\Math\BigInteger - * @access public - */ - function __construct($x = 0, $base = 10) - { - if (!defined('MATH_BIGINTEGER_MODE')) { - switch (true) { - case extension_loaded('gmp'): - define('MATH_BIGINTEGER_MODE', self::MODE_GMP); - break; - case extension_loaded('bcmath'): - define('MATH_BIGINTEGER_MODE', self::MODE_BCMATH); - break; - default: - define('MATH_BIGINTEGER_MODE', self::MODE_INTERNAL); - } - } - - if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { - // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work - $versions = array(); - - // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems) - if (strpos(ini_get('disable_functions'), 'phpinfo') === false) { - ob_start(); - @phpinfo(); - $content = ob_get_contents(); - ob_end_clean(); - - preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches); - - if (!empty($matches[1])) { - for ($i = 0; $i < count($matches[1]); $i++) { - $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i]))); - - // Remove letter part in OpenSSL version - if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) { - $versions[$matches[1][$i]] = $fullVersion; - } else { - $versions[$matches[1][$i]] = $m[0]; - } - } - } - } - - // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+ - switch (true) { - case !isset($versions['Header']): - case !isset($versions['Library']): - case $versions['Header'] == $versions['Library']: - case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0: - define('MATH_BIGINTEGER_OPENSSL_ENABLED', true); - break; - default: - define('MATH_BIGINTEGER_OPENSSL_DISABLE', true); - } - } - - if (!defined('PHP_INT_SIZE')) { - define('PHP_INT_SIZE', 4); - } - - if (empty(self::$base) && MATH_BIGINTEGER_MODE == self::MODE_INTERNAL) { - switch (PHP_INT_SIZE) { - case 8: // use 64-bit integers if int size is 8 bytes - self::$base = 31; - self::$baseFull = 0x80000000; - self::$maxDigit = 0x7FFFFFFF; - self::$msb = 0x40000000; - self::$max10 = 1000000000; - self::$max10Len = 9; - self::$maxDigit2 = pow(2, 62); - break; - //case 4: // use 64-bit floats if int size is 4 bytes - default: - self::$base = 26; - self::$baseFull = 0x4000000; - self::$maxDigit = 0x3FFFFFF; - self::$msb = 0x2000000; - self::$max10 = 10000000; - self::$max10Len = 7; - self::$maxDigit2 = pow(2, 52); // pow() prevents truncation - } - } - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - switch (true) { - case is_resource($x) && get_resource_type($x) == 'GMP integer': - // PHP 5.6 switched GMP from using resources to objects - case $x instanceof \GMP: - $this->value = $x; - return; - } - $this->value = gmp_init(0); - break; - case self::MODE_BCMATH: - $this->value = '0'; - break; - default: - $this->value = array(); - } - - // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 - // '0' is the only value like this per http://php.net/empty - if (empty($x) && (abs($base) != 256 || $x !== '0')) { - return; - } - - switch ($base) { - case -256: - if (ord($x[0]) & 0x80) { - $x = ~$x; - $this->is_negative = true; - } - case 256: - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $this->value = function_exists('gmp_import') ? - gmp_import($x) : - gmp_init('0x' . bin2hex($x)); - if ($this->is_negative) { - $this->value = gmp_neg($this->value); - } - break; - case self::MODE_BCMATH: - // round $len to the nearest 4 (thanks, DavidMJ!) - $len = (strlen($x) + 3) & 0xFFFFFFFC; - - $x = str_pad($x, $len, chr(0), STR_PAD_LEFT); - - for ($i = 0; $i < $len; $i+= 4) { - $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 - $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0); - } - - if ($this->is_negative) { - $this->value = '-' . $this->value; - } - - break; - // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb) - default: - while (strlen($x)) { - $this->value[] = $this->_bytes2int($this->_base256_rshift($x, self::$base)); - } - } - - if ($this->is_negative) { - if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) { - $this->is_negative = false; - } - $temp = $this->add(new static('-1')); - $this->value = $temp->value; - } - break; - case 16: - case -16: - if ($base > 0 && $x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x); - - $is_negative = false; - if ($base < 0 && hexdec($x[0]) >= 8) { - $this->is_negative = $is_negative = true; - $x = bin2hex(~pack('H*', $x)); - } - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = $this->is_negative ? '-0x' . $x : '0x' . $x; - $this->value = gmp_init($temp); - $this->is_negative = false; - break; - case self::MODE_BCMATH: - $x = (strlen($x) & 1) ? '0' . $x : $x; - $temp = new static(pack('H*', $x), 256); - $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; - $this->is_negative = false; - break; - default: - $x = (strlen($x) & 1) ? '0' . $x : $x; - $temp = new static(pack('H*', $x), 256); - $this->value = $temp->value; - } - - if ($is_negative) { - $temp = $this->add(new static('-1')); - $this->value = $temp->value; - } - break; - case 10: - case -10: - // (?value = gmp_init($x); - break; - case self::MODE_BCMATH: - // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different - // results then doing it on '-1' does (modInverse does $x[0]) - $this->value = $x === '-' ? '0' : (string) $x; - break; - default: - $temp = new static(); - - $multiplier = new static(); - $multiplier->value = array(self::$max10); - - if ($x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = str_pad($x, strlen($x) + ((self::$max10Len - 1) * strlen($x)) % self::$max10Len, 0, STR_PAD_LEFT); - while (strlen($x)) { - $temp = $temp->multiply($multiplier); - $temp = $temp->add(new static($this->_int2bytes(substr($x, 0, self::$max10Len)), 256)); - $x = substr($x, self::$max10Len); - } - - $this->value = $temp->value; - } - break; - case 2: // base-2 support originally implemented by Lluis Pamies - thanks! - case -2: - if ($base > 0 && $x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = preg_replace('#^([01]*).*#', '$1', $x); - $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT); - - $str = '0x'; - while (strlen($x)) { - $part = substr($x, 0, 4); - $str.= dechex(bindec($part)); - $x = substr($x, 4); - } - - if ($this->is_negative) { - $str = '-' . $str; - } - - $temp = new static($str, 8 * $base); // ie. either -16 or +16 - $this->value = $temp->value; - $this->is_negative = $temp->is_negative; - - break; - default: - // base not supported, so we'll let $this == 0 - } - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * Here's an example: - * - * toBytes(); // outputs chr(65) - * ?> - * - * - * @param bool $twos_compliment - * @return string - * @access public - * @internal Converts a base-2**26 number to base-2**8 - */ - function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - $comparison = $this->compare(new static()); - if ($comparison == 0) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy(); - $bytes = $temp->toBytes(); - - if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 - $bytes = chr(0); - } - - if ($this->precision <= 0 && (ord($bytes[0]) & 0x80)) { - $bytes = chr(0) . $bytes; - } - - return $comparison < 0 ? ~$bytes : $bytes; - } - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - if (gmp_cmp($this->value, gmp_init(0)) == 0) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - if (function_exists('gmp_export')) { - $temp = gmp_export($this->value); - } else { - $temp = gmp_strval(gmp_abs($this->value), 16); - $temp = (strlen($temp) & 1) ? '0' . $temp : $temp; - $temp = pack('H*', $temp); - } - - return $this->precision > 0 ? - substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : - ltrim($temp, chr(0)); - case self::MODE_BCMATH: - if ($this->value === '0') { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $value = ''; - $current = $this->value; - - if ($current[0] == '-') { - $current = substr($current, 1); - } - - while (bccomp($current, '0', 0) > 0) { - $temp = bcmod($current, '16777216'); - $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; - $current = bcdiv($current, '16777216', 0); - } - - return $this->precision > 0 ? - substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : - ltrim($value, chr(0)); - } - - if (!count($this->value)) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - $result = $this->_int2bytes($this->value[count($this->value) - 1]); - - $temp = $this->copy(); - - for ($i = count($temp->value) - 2; $i >= 0; --$i) { - $temp->_base256_lshift($result, self::$base); - $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT); - } - - return $this->precision > 0 ? - str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) : - $result; - } - - /** - * Converts a BigInteger to a hex string (eg. base-16)). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * Here's an example: - * - * toHex(); // outputs '41' - * ?> - * - * - * @param bool $twos_compliment - * @return string - * @access public - * @internal Converts a base-2**26 number to base-2**8 - */ - function toHex($twos_compliment = false) - { - return bin2hex($this->toBytes($twos_compliment)); - } - - /** - * Converts a BigInteger to a bit string (eg. base-2). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * Here's an example: - * - * toBits(); // outputs '1000001' - * ?> - * - * - * @param bool $twos_compliment - * @return string - * @access public - * @internal Converts a base-2**26 number to base-2**2 - */ - function toBits($twos_compliment = false) - { - $hex = $this->toHex($twos_compliment); - $bits = ''; - for ($i = strlen($hex) - 6, $start = strlen($hex) % 6; $i >= $start; $i-=6) { - $bits = str_pad(decbin(hexdec(substr($hex, $i, 6))), 24, '0', STR_PAD_LEFT) . $bits; - } - if ($start) { // hexdec('') == 0 - $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8 * $start, '0', STR_PAD_LEFT) . $bits; - } - $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); - - if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { - return '0' . $result; - } - - return $result; - } - - /** - * Converts a BigInteger to a base-10 number. - * - * Here's an example: - * - * toString(); // outputs 50 - * ?> - * - * - * @return string - * @access public - * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10) - */ - function toString() - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - return gmp_strval($this->value); - case self::MODE_BCMATH: - if ($this->value === '0') { - return '0'; - } - - return ltrim($this->value, '0'); - } - - if (!count($this->value)) { - return '0'; - } - - $temp = $this->copy(); - $temp->bitmask = false; - $temp->is_negative = false; - - $divisor = new static(); - $divisor->value = array(self::$max10); - $result = ''; - while (count($temp->value)) { - list($temp, $mod) = $temp->divide($divisor); - $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', self::$max10Len, '0', STR_PAD_LEFT) . $result; - } - $result = ltrim($result, '0'); - if (empty($result)) { - $result = '0'; - } - - if ($this->is_negative) { - $result = '-' . $result; - } - - return $result; - } - - /** - * Copy an object - * - * PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee - * that all objects are passed by value, when appropriate. More information can be found here: - * - * {@link http://php.net/language.oop5.basic#51624} - * - * @access public - * @see self::__clone() - * @return \phpseclib\Math\BigInteger - */ - function copy() - { - $temp = new static(); - $temp->value = $this->value; - $temp->is_negative = $this->is_negative; - $temp->precision = $this->precision; - $temp->bitmask = $this->bitmask; - return $temp; - } - - /** - * __toString() magic method - * - * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call - * toString(). - * - * @access public - * @internal Implemented per a suggestion by Techie-Michael - thanks! - */ - function __toString() - { - return $this->toString(); - } - - /** - * __clone() magic method - * - * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly - * in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5 - * only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and - * PHP5, call BigInteger::copy(), instead. - * - * @access public - * @see self::copy() - * @return \phpseclib\Math\BigInteger - */ - function __clone() - { - return $this->copy(); - } - - /** - * __sleep() magic method - * - * Will be called, automatically, when serialize() is called on a BigInteger object. - * - * @see self::__wakeup() - * @access public - */ - function __sleep() - { - $this->hex = $this->toHex(true); - $vars = array('hex'); - if ($this->precision > 0) { - $vars[] = 'precision'; - } - return $vars; - } - - /** - * __wakeup() magic method - * - * Will be called, automatically, when unserialize() is called on a BigInteger object. - * - * @see self::__sleep() - * @access public - */ - function __wakeup() - { - $temp = new static($this->hex, -16); - $this->value = $temp->value; - $this->is_negative = $temp->is_negative; - if ($this->precision > 0) { - // recalculate $this->bitmask - $this->setPrecision($this->precision); - } - } - - /** - * __debugInfo() magic method - * - * Will be called, automatically, when print_r() or var_dump() are called - * - * @access public - */ - function __debugInfo() - { - $opts = array(); - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $engine = 'gmp'; - break; - case self::MODE_BCMATH: - $engine = 'bcmath'; - break; - case self::MODE_INTERNAL: - $engine = 'internal'; - $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit'; - } - if (MATH_BIGINTEGER_MODE != self::MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { - $opts[] = 'OpenSSL'; - } - if (!empty($opts)) { - $engine.= ' (' . implode('.', $opts) . ')'; - } - return array( - 'value' => '0x' . $this->toHex(true), - 'engine' => $engine - ); - } - - /** - * Adds two BigIntegers. - * - * Here's an example: - * - * add($b); - * - * echo $c->toString(); // outputs 30 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $y - * @return \phpseclib\Math\BigInteger - * @access public - * @internal Performs base-2**52 addition - */ - function add($y) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_add($this->value, $y->value); - - return $this->_normalize($temp); - case self::MODE_BCMATH: - $temp = new static(); - $temp->value = bcadd($this->value, $y->value, 0); - - return $this->_normalize($temp); - } - - $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative); - - $result = new static(); - $result->value = $temp[self::VALUE]; - $result->is_negative = $temp[self::SIGN]; - - return $this->_normalize($result); - } - - /** - * Performs addition. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - * @access private - */ - function _add($x_value, $x_negative, $y_value, $y_negative) - { - $x_size = count($x_value); - $y_size = count($y_value); - - if ($x_size == 0) { - return array( - self::VALUE => $y_value, - self::SIGN => $y_negative - ); - } elseif ($y_size == 0) { - return array( - self::VALUE => $x_value, - self::SIGN => $x_negative - ); - } - - // subtract, if appropriate - if ($x_negative != $y_negative) { - if ($x_value == $y_value) { - return array( - self::VALUE => array(), - self::SIGN => false - ); - } - - $temp = $this->_subtract($x_value, false, $y_value, false); - $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ? - $x_negative : $y_negative; - - return $temp; - } - - if ($x_size < $y_size) { - $size = $x_size; - $value = $y_value; - } else { - $size = $y_size; - $value = $x_value; - } - - $value[count($value)] = 0; // just in case the carry adds an extra digit - - $carry = 0; - for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) { - $sum = $x_value[$j] * self::$baseFull + $x_value[$i] + $y_value[$j] * self::$baseFull + $y_value[$i] + $carry; - $carry = $sum >= self::$maxDigit2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 - $sum = $carry ? $sum - self::$maxDigit2 : $sum; - - $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31); - - $value[$i] = (int) ($sum - self::$baseFull * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) - $value[$j] = $temp; - } - - if ($j == $size) { // ie. if $y_size is odd - $sum = $x_value[$i] + $y_value[$i] + $carry; - $carry = $sum >= self::$baseFull; - $value[$i] = $carry ? $sum - self::$baseFull : $sum; - ++$i; // ie. let $i = $j since we've just done $value[$i] - } - - if ($carry) { - for (; $value[$i] == self::$maxDigit; ++$i) { - $value[$i] = 0; - } - ++$value[$i]; - } - - return array( - self::VALUE => $this->_trim($value), - self::SIGN => $x_negative - ); - } - - /** - * Subtracts two BigIntegers. - * - * Here's an example: - * - * subtract($b); - * - * echo $c->toString(); // outputs -10 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $y - * @return \phpseclib\Math\BigInteger - * @access public - * @internal Performs base-2**52 subtraction - */ - function subtract($y) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_sub($this->value, $y->value); - - return $this->_normalize($temp); - case self::MODE_BCMATH: - $temp = new static(); - $temp->value = bcsub($this->value, $y->value, 0); - - return $this->_normalize($temp); - } - - $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative); - - $result = new static(); - $result->value = $temp[self::VALUE]; - $result->is_negative = $temp[self::SIGN]; - - return $this->_normalize($result); - } - - /** - * Performs subtraction. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - * @access private - */ - function _subtract($x_value, $x_negative, $y_value, $y_negative) - { - $x_size = count($x_value); - $y_size = count($y_value); - - if ($x_size == 0) { - return array( - self::VALUE => $y_value, - self::SIGN => !$y_negative - ); - } elseif ($y_size == 0) { - return array( - self::VALUE => $x_value, - self::SIGN => $x_negative - ); - } - - // add, if appropriate (ie. -$x - +$y or +$x - -$y) - if ($x_negative != $y_negative) { - $temp = $this->_add($x_value, false, $y_value, false); - $temp[self::SIGN] = $x_negative; - - return $temp; - } - - $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative); - - if (!$diff) { - return array( - self::VALUE => array(), - self::SIGN => false - ); - } - - // switch $x and $y around, if appropriate. - if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_negative = !$x_negative; - - $x_size = count($x_value); - $y_size = count($y_value); - } - - // at this point, $x_value should be at least as big as - if not bigger than - $y_value - - $carry = 0; - for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) { - $sum = $x_value[$j] * self::$baseFull + $x_value[$i] - $y_value[$j] * self::$baseFull - $y_value[$i] - $carry; - $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 - $sum = $carry ? $sum + self::$maxDigit2 : $sum; - - $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31); - - $x_value[$i] = (int) ($sum - self::$baseFull * $temp); - $x_value[$j] = $temp; - } - - if ($j == $y_size) { // ie. if $y_size is odd - $sum = $x_value[$i] - $y_value[$i] - $carry; - $carry = $sum < 0; - $x_value[$i] = $carry ? $sum + self::$baseFull : $sum; - ++$i; - } - - if ($carry) { - for (; !$x_value[$i]; ++$i) { - $x_value[$i] = self::$maxDigit; - } - --$x_value[$i]; - } - - return array( - self::VALUE => $this->_trim($x_value), - self::SIGN => $x_negative - ); - } - - /** - * Multiplies two BigIntegers - * - * Here's an example: - * - * multiply($b); - * - * echo $c->toString(); // outputs 200 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $x - * @return \phpseclib\Math\BigInteger - * @access public - */ - function multiply($x) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_mul($this->value, $x->value); - - return $this->_normalize($temp); - case self::MODE_BCMATH: - $temp = new static(); - $temp->value = bcmul($this->value, $x->value, 0); - - return $this->_normalize($temp); - } - - $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative); - - $product = new static(); - $product->value = $temp[self::VALUE]; - $product->is_negative = $temp[self::SIGN]; - - return $this->_normalize($product); - } - - /** - * Performs multiplication. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - * @access private - */ - function _multiply($x_value, $x_negative, $y_value, $y_negative) - { - //if ( $x_value == $y_value ) { - // return array( - // self::VALUE => $this->_square($x_value), - // self::SIGN => $x_sign != $y_value - // ); - //} - - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return array( - self::VALUE => array(), - self::SIGN => false - ); - } - - return array( - self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? - $this->_trim($this->_regularMultiply($x_value, $y_value)) : - $this->_trim($this->_karatsuba($x_value, $y_value)), - self::SIGN => $x_negative != $y_negative - ); - } - - /** - * Performs long multiplication on two BigIntegers - * - * Modeled after 'multiply' in MutableBigInteger.java. - * - * @param array $x_value - * @param array $y_value - * @return array - * @access private - */ - function _regularMultiply($x_value, $y_value) - { - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return array(); - } - - if ($x_length < $y_length) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_length = count($x_value); - $y_length = count($y_value); - } - - $product_value = $this->_array_repeat(0, $x_length + $y_length); - - // the following for loop could be removed if the for loop following it - // (the one with nested for loops) initially set $i to 0, but - // doing so would also make the result in one set of unnecessary adds, - // since on the outermost loops first pass, $product->value[$k] is going - // to always be 0 - - $carry = 0; - - for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 - $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$j] = (int) ($temp - self::$baseFull * $carry); - } - - $product_value[$j] = $carry; - - // the above for loop is what the previous comment was talking about. the - // following for loop is the "one with nested for loops" - for ($i = 1; $i < $y_length; ++$i) { - $carry = 0; - - for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { - $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$k] = (int) ($temp - self::$baseFull * $carry); - } - - $product_value[$k] = $carry; - } - - return $product_value; - } - - /** - * Performs Karatsuba multiplication on two BigIntegers - * - * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. - * - * @param array $x_value - * @param array $y_value - * @return array - * @access private - */ - function _karatsuba($x_value, $y_value) - { - $m = min(count($x_value) >> 1, count($y_value) >> 1); - - if ($m < self::KARATSUBA_CUTOFF) { - return $this->_regularMultiply($x_value, $y_value); - } - - $x1 = array_slice($x_value, $m); - $x0 = array_slice($x_value, 0, $m); - $y1 = array_slice($y_value, $m); - $y0 = array_slice($y_value, 0, $m); - - $z2 = $this->_karatsuba($x1, $y1); - $z0 = $this->_karatsuba($x0, $y0); - - $z1 = $this->_add($x1, false, $x0, false); - $temp = $this->_add($y1, false, $y0, false); - $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]); - $temp = $this->_add($z2, false, $z0, false); - $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false); - - $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); - $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - - $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false); - - return $xy[self::VALUE]; - } - - /** - * Performs squaring - * - * @param array $x - * @return array - * @access private - */ - function _square($x = false) - { - return count($x) < 2 * self::KARATSUBA_CUTOFF ? - $this->_trim($this->_baseSquare($x)) : - $this->_trim($this->_karatsubaSquare($x)); - } - - /** - * Performs traditional squaring on two BigIntegers - * - * Squaring can be done faster than multiplying a number by itself can be. See - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. - * - * @param array $value - * @return array - * @access private - */ - function _baseSquare($value) - { - if (empty($value)) { - return array(); - } - $square_value = $this->_array_repeat(0, 2 * count($value)); - - for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { - $i2 = $i << 1; - - $temp = $square_value[$i2] + $value[$i] * $value[$i]; - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $square_value[$i2] = (int) ($temp - self::$baseFull * $carry); - - // note how we start from $i+1 instead of 0 as we do in multiplication. - for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { - $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $square_value[$k] = (int) ($temp - self::$baseFull * $carry); - } - - // the following line can yield values larger 2**15. at this point, PHP should switch - // over to floats. - $square_value[$i + $max_index + 1] = $carry; - } - - return $square_value; - } - - /** - * Performs Karatsuba "squaring" on two BigIntegers - * - * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. - * - * @param array $value - * @return array - * @access private - */ - function _karatsubaSquare($value) - { - $m = count($value) >> 1; - - if ($m < self::KARATSUBA_CUTOFF) { - return $this->_baseSquare($value); - } - - $x1 = array_slice($value, $m); - $x0 = array_slice($value, 0, $m); - - $z2 = $this->_karatsubaSquare($x1); - $z0 = $this->_karatsubaSquare($x0); - - $z1 = $this->_add($x1, false, $x0, false); - $z1 = $this->_karatsubaSquare($z1[self::VALUE]); - $temp = $this->_add($z2, false, $z0, false); - $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false); - - $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); - $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - - $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false); - - return $xx[self::VALUE]; - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * Here's an example: - * - * divide($b); - * - * echo $quotient->toString(); // outputs 0 - * echo "\r\n"; - * echo $remainder->toString(); // outputs 10 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $y - * @return array - * @access public - * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. - */ - function divide($y) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $quotient = new static(); - $remainder = new static(); - - list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); - - if (gmp_sign($remainder->value) < 0) { - $remainder->value = gmp_add($remainder->value, gmp_abs($y->value)); - } - - return array($this->_normalize($quotient), $this->_normalize($remainder)); - case self::MODE_BCMATH: - $quotient = new static(); - $remainder = new static(); - - $quotient->value = bcdiv($this->value, $y->value, 0); - $remainder->value = bcmod($this->value, $y->value); - - if ($remainder->value[0] == '-') { - $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); - } - - return array($this->_normalize($quotient), $this->_normalize($remainder)); - } - - if (count($y->value) == 1) { - list($q, $r) = $this->_divide_digit($this->value, $y->value[0]); - $quotient = new static(); - $remainder = new static(); - $quotient->value = $q; - $remainder->value = array($r); - $quotient->is_negative = $this->is_negative != $y->is_negative; - return array($this->_normalize($quotient), $this->_normalize($remainder)); - } - - static $zero; - if (!isset($zero)) { - $zero = new static(); - } - - $x = $this->copy(); - $y = $y->copy(); - - $x_sign = $x->is_negative; - $y_sign = $y->is_negative; - - $x->is_negative = $y->is_negative = false; - - $diff = $x->compare($y); - - if (!$diff) { - $temp = new static(); - $temp->value = array(1); - $temp->is_negative = $x_sign != $y_sign; - return array($this->_normalize($temp), $this->_normalize(new static())); - } - - if ($diff < 0) { - // if $x is negative, "add" $y. - if ($x_sign) { - $x = $y->subtract($x); - } - return array($this->_normalize(new static()), $this->_normalize($x)); - } - - // normalize $x and $y as described in HAC 14.23 / 14.24 - $msb = $y->value[count($y->value) - 1]; - for ($shift = 0; !($msb & self::$msb); ++$shift) { - $msb <<= 1; - } - $x->_lshift($shift); - $y->_lshift($shift); - $y_value = &$y->value; - - $x_max = count($x->value) - 1; - $y_max = count($y->value) - 1; - - $quotient = new static(); - $quotient_value = &$quotient->value; - $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1); - - static $temp, $lhs, $rhs; - if (!isset($temp)) { - $temp = new static(); - $lhs = new static(); - $rhs = new static(); - } - $temp_value = &$temp->value; - $rhs_value = &$rhs->value; - - // $temp = $y << ($x_max - $y_max-1) in base 2**26 - $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value); - - while ($x->compare($temp) >= 0) { - // calculate the "common residue" - ++$quotient_value[$x_max - $y_max]; - $x = $x->subtract($temp); - $x_max = count($x->value) - 1; - } - - for ($i = $x_max; $i >= $y_max + 1; --$i) { - $x_value = &$x->value; - $x_window = array( - isset($x_value[$i]) ? $x_value[$i] : 0, - isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, - isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 - ); - $y_window = array( - $y_value[$y_max], - ($y_max > 0) ? $y_value[$y_max - 1] : 0 - ); - - $q_index = $i - $y_max - 1; - if ($x_window[0] == $y_window[0]) { - $quotient_value[$q_index] = self::$maxDigit; - } else { - $quotient_value[$q_index] = $this->_safe_divide( - $x_window[0] * self::$baseFull + $x_window[1], - $y_window[0] - ); - } - - $temp_value = array($y_window[1], $y_window[0]); - - $lhs->value = array($quotient_value[$q_index]); - $lhs = $lhs->multiply($temp); - - $rhs_value = array($x_window[2], $x_window[1], $x_window[0]); - - while ($lhs->compare($rhs) > 0) { - --$quotient_value[$q_index]; - - $lhs->value = array($quotient_value[$q_index]); - $lhs = $lhs->multiply($temp); - } - - $adjust = $this->_array_repeat(0, $q_index); - $temp_value = array($quotient_value[$q_index]); - $temp = $temp->multiply($y); - $temp_value = &$temp->value; - if (count($temp_value)) { - $temp_value = array_merge($adjust, $temp_value); - } - - $x = $x->subtract($temp); - - if ($x->compare($zero) < 0) { - $temp_value = array_merge($adjust, $y_value); - $x = $x->add($temp); - - --$quotient_value[$q_index]; - } - - $x_max = count($x_value) - 1; - } - - // unnormalize the remainder - $x->_rshift($shift); - - $quotient->is_negative = $x_sign != $y_sign; - - // calculate the "common residue", if appropriate - if ($x_sign) { - $y->_rshift($shift); - $x = $y->subtract($x); - } - - return array($this->_normalize($quotient), $this->_normalize($x)); - } - - /** - * Divides a BigInteger by a regular integer - * - * abc / x = a00 / x + b0 / x + c / x - * - * @param array $dividend - * @param array $divisor - * @return array - * @access private - */ - function _divide_digit($dividend, $divisor) - { - $carry = 0; - $result = array(); - - for ($i = count($dividend) - 1; $i >= 0; --$i) { - $temp = self::$baseFull * $carry + $dividend[$i]; - $result[$i] = $this->_safe_divide($temp, $divisor); - $carry = (int) ($temp - $divisor * $result[$i]); - } - - return array($result, $carry); - } - - /** - * Performs modular exponentiation. - * - * Here's an example: - * - * modPow($b, $c); - * - * echo $c->toString(); // outputs 10 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $e - * @param \phpseclib\Math\BigInteger $n - * @return \phpseclib\Math\BigInteger - * @access public - * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and - * and although the approach involving repeated squaring does vastly better, it, too, is impractical - * for our purposes. The reason being that division - by far the most complicated and time-consuming - * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. - * - * Modular reductions resolve this issue. Although an individual modular reduction takes more time - * then an individual division, when performed in succession (with the same modulo), they're a lot faster. - * - * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, - * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the - * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because - * the product of two odd numbers is odd), but what about when RSA isn't used? - * - * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a - * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the - * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, - * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and - * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. - * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. - */ - function modPow($e, $n) - { - $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); - - if ($e->compare(new static()) < 0) { - $e = $e->abs(); - - $temp = $this->modInverse($n); - if ($temp === false) { - return false; - } - - return $this->_normalize($temp->modPow($e, $n)); - } - - if (MATH_BIGINTEGER_MODE == self::MODE_GMP) { - $temp = new static(); - $temp->value = gmp_powm($this->value, $e->value, $n->value); - - return $this->_normalize($temp); - } - - if ($this->compare(new static()) < 0 || $this->compare($n) > 0) { - list(, $temp) = $this->divide($n); - return $temp->modPow($e, $n); - } - - if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { - $components = array( - 'modulus' => $n->toBytes(true), - 'publicExponent' => $e->toBytes(true) - ); - - $components = array( - 'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']), - 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent']) - ); - - $RSAPublicKey = pack( - 'Ca*a*a*', - 48, - $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])), - $components['modulus'], - $components['publicExponent'] - ); - - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA - $RSAPublicKey = chr(0) . $RSAPublicKey; - $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey; - - $encapsulated = pack( - 'Ca*a*', - 48, - $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), - $rsaOID . $RSAPublicKey - ); - - $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($encapsulated)) . - '-----END PUBLIC KEY-----'; - - $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT); - - if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) { - return new static($result, 256); - } - } - - if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { - $temp = new static(); - $temp->value = bcpowmod($this->value, $e->value, $n->value, 0); - - return $this->_normalize($temp); - } - - if (empty($e->value)) { - $temp = new static(); - $temp->value = array(1); - return $this->_normalize($temp); - } - - if ($e->value == array(1)) { - list(, $temp) = $this->divide($n); - return $this->_normalize($temp); - } - - if ($e->value == array(2)) { - $temp = new static(); - $temp->value = $this->_square($this->value); - list(, $temp) = $temp->divide($n); - return $this->_normalize($temp); - } - - return $this->_normalize($this->_slidingWindow($e, $n, self::BARRETT)); - - // the following code, although not callable, can be run independently of the above code - // although the above code performed better in my benchmarks the following could might - // perform better under different circumstances. in lieu of deleting it it's just been - // made uncallable - - // is the modulo odd? - if ($n->value[0] & 1) { - return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY)); - } - // if it's not, it's even - - // find the lowest set bit (eg. the max pow of 2 that divides $n) - for ($i = 0; $i < count($n->value); ++$i) { - if ($n->value[$i]) { - $temp = decbin($n->value[$i]); - $j = strlen($temp) - strrpos($temp, '1') - 1; - $j+= 26 * $i; - break; - } - } - // at this point, 2^$j * $n/(2^$j) == $n - - $mod1 = $n->copy(); - $mod1->_rshift($j); - $mod2 = new static(); - $mod2->value = array(1); - $mod2->_lshift($j); - - $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, self::MONTGOMERY) : new static(); - $part2 = $this->_slidingWindow($e, $mod2, self::POWEROF2); - - $y1 = $mod2->modInverse($mod1); - $y2 = $mod1->modInverse($mod2); - - $result = $part1->multiply($mod2); - $result = $result->multiply($y1); - - $temp = $part2->multiply($mod1); - $temp = $temp->multiply($y2); - - $result = $result->add($temp); - list(, $result) = $result->divide($n); - - return $this->_normalize($result); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param \phpseclib\Math\BigInteger $e - * @param \phpseclib\Math\BigInteger $n - * @return \phpseclib\Math\BigInteger - * @access public - */ - function powMod($e, $n) - { - return $this->modPow($e, $n); - } - - /** - * Sliding Window k-ary Modular Exponentiation - * - * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, - * however, this function performs a modular reduction after every multiplication and squaring operation. - * As such, this function has the same preconditions that the reductions being used do. - * - * @param \phpseclib\Math\BigInteger $e - * @param \phpseclib\Math\BigInteger $n - * @param int $mode - * @return \phpseclib\Math\BigInteger - * @access private - */ - function _slidingWindow($e, $n, $mode) - { - static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function - //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1 - - $e_value = $e->value; - $e_length = count($e_value) - 1; - $e_bits = decbin($e_value[$e_length]); - for ($i = $e_length - 1; $i >= 0; --$i) { - $e_bits.= str_pad(decbin($e_value[$i]), self::$base, '0', STR_PAD_LEFT); - } - - $e_length = strlen($e_bits); - - // calculate the appropriate window size. - // $window_size == 3 if $window_ranges is between 25 and 81, for example. - for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { - } - - $n_value = $n->value; - - // precompute $this^0 through $this^$window_size - $powers = array(); - $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode); - $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode); - - // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end - // in a 1. ie. it's supposed to be odd. - $temp = 1 << ($window_size - 1); - for ($i = 1; $i < $temp; ++$i) { - $i2 = $i << 1; - $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode); - } - - $result = array(1); - $result = $this->_prepareReduce($result, $n_value, $mode); - - for ($i = 0; $i < $e_length;) { - if (!$e_bits[$i]) { - $result = $this->_squareReduce($result, $n_value, $mode); - ++$i; - } else { - for ($j = $window_size - 1; $j > 0; --$j) { - if (!empty($e_bits[$i + $j])) { - break; - } - } - - // eg. the length of substr($e_bits, $i, $j + 1) - for ($k = 0; $k <= $j; ++$k) { - $result = $this->_squareReduce($result, $n_value, $mode); - } - - $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode); - - $i += $j + 1; - } - } - - $temp = new static(); - $temp->value = $this->_reduce($result, $n_value, $mode); - - return $temp; - } - - /** - * Modular reduction - * - * For most $modes this will return the remainder. - * - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $n - * @param int $mode - * @return array - */ - function _reduce($x, $n, $mode) - { - switch ($mode) { - case self::MONTGOMERY: - return $this->_montgomery($x, $n); - case self::BARRETT: - return $this->_barrett($x, $n); - case self::POWEROF2: - $lhs = new static(); - $lhs->value = $x; - $rhs = new static(); - $rhs->value = $n; - return $x->_mod2($n); - case self::CLASSIC: - $lhs = new static(); - $lhs->value = $x; - $rhs = new static(); - $rhs->value = $n; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - case self::NONE: - return $x; - default: - // an invalid $mode was provided - } - } - - /** - * Modular reduction preperation - * - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $n - * @param int $mode - * @return array - */ - function _prepareReduce($x, $n, $mode) - { - if ($mode == self::MONTGOMERY) { - return $this->_prepMontgomery($x, $n); - } - return $this->_reduce($x, $n, $mode); - } - - /** - * Modular multiply - * - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $y - * @param array $n - * @param int $mode - * @return array - */ - function _multiplyReduce($x, $y, $n, $mode) - { - if ($mode == self::MONTGOMERY) { - return $this->_montgomeryMultiply($x, $y, $n); - } - $temp = $this->_multiply($x, false, $y, false); - return $this->_reduce($temp[self::VALUE], $n, $mode); - } - - /** - * Modular square - * - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $n - * @param int $mode - * @return array - */ - function _squareReduce($x, $n, $mode) - { - if ($mode == self::MONTGOMERY) { - return $this->_montgomeryMultiply($x, $x, $n); - } - return $this->_reduce($this->_square($x), $n, $mode); - } - - /** - * Modulos for Powers of Two - * - * Calculates $x%$n, where $n = 2**$e, for some $e. Since this is basically the same as doing $x & ($n-1), - * we'll just use this function as a wrapper for doing that. - * - * @see self::_slidingWindow() - * @access private - * @param \phpseclib\Math\BigInteger $n - * @return \phpseclib\Math\BigInteger - */ - function _mod2($n) - { - $temp = new static(); - $temp->value = array(1); - return $this->bitwise_and($n->subtract($temp)); - } - - /** - * Barrett Modular Reduction - * - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, - * so as not to require negative numbers (initially, this script didn't support negative numbers). - * - * Employs "folding", as described at - * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from - * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." - * - * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that - * usable on account of (1) its not using reasonable radix points as discussed in - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable - * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that - * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line - * comments for details. - * - * @see self::_slidingWindow() - * @access private - * @param array $n - * @param array $m - * @return array - */ - function _barrett($n, $m) - { - static $cache = array( - self::VARIABLE => array(), - self::DATA => array() - ); - - $m_length = count($m); - - // if ($this->_compare($n, $this->_square($m)) >= 0) { - if (count($n) > 2 * $m_length) { - $lhs = new static(); - $rhs = new static(); - $lhs->value = $n; - $rhs->value = $m; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced - if ($m_length < 5) { - return $this->_regularBarrett($n, $m); - } - - // n = 2 * m.length - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - - $lhs = new static(); - $lhs_value = &$lhs->value; - $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1)); - $lhs_value[] = 1; - $rhs = new static(); - $rhs->value = $m; - - list($u, $m1) = $lhs->divide($rhs); - $u = $u->value; - $m1 = $m1->value; - - $cache[self::DATA][] = array( - 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) - 'm1'=> $m1 // m.length - ); - } else { - extract($cache[self::DATA][$key]); - } - - $cutoff = $m_length + ($m_length >> 1); - $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) - $msd = array_slice($n, $cutoff); // m.length >> 1 - $lsd = $this->_trim($lsd); - $temp = $this->_multiply($msd, false, $m1, false); - $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 - - if ($m_length & 1) { - return $this->_regularBarrett($n[self::VALUE], $m); - } - - // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 - $temp = array_slice($n[self::VALUE], $m_length - 1); - // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 - // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 - $temp = $this->_multiply($temp, false, $u, false); - // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 - // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) - $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); - // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 - // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) - $temp = $this->_multiply($temp, false, $m, false); - - // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit - // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop - // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). - - $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false); - - while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { - $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false); - } - - return $result[self::VALUE]; - } - - /** - * (Regular) Barrett Modular Reduction - * - * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this - * is that this function does not fold the denominator into a smaller form. - * - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $n - * @return array - */ - function _regularBarrett($x, $n) - { - static $cache = array( - self::VARIABLE => array(), - self::DATA => array() - ); - - $n_length = count($n); - - if (count($x) > 2 * $n_length) { - $lhs = new static(); - $rhs = new static(); - $lhs->value = $x; - $rhs->value = $n; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $n; - $lhs = new static(); - $lhs_value = &$lhs->value; - $lhs_value = $this->_array_repeat(0, 2 * $n_length); - $lhs_value[] = 1; - $rhs = new static(); - $rhs->value = $n; - list($temp, ) = $lhs->divide($rhs); // m.length - $cache[self::DATA][] = $temp->value; - } - - // 2 * m.length - (m.length - 1) = m.length + 1 - $temp = array_slice($x, $n_length - 1); - // (m.length + 1) + m.length = 2 * m.length + 1 - $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false); - // (2 * m.length + 1) - (m.length - 1) = m.length + 2 - $temp = array_slice($temp[self::VALUE], $n_length + 1); - - // m.length + 1 - $result = array_slice($x, 0, $n_length + 1); - // m.length + 1 - $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1); - // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1) - - if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { - $corrector_value = $this->_array_repeat(0, $n_length + 1); - $corrector_value[count($corrector_value)] = 1; - $result = $this->_add($result, false, $corrector_value, false); - $result = $result[self::VALUE]; - } - - // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits - $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]); - while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { - $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false); - } - - return $result[self::VALUE]; - } - - /** - * Performs long multiplication up to $stop digits - * - * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. - * - * @see self::_regularBarrett() - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @param int $stop - * @return array - * @access private - */ - function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop) - { - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return array( - self::VALUE => array(), - self::SIGN => false - ); - } - - if ($x_length < $y_length) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_length = count($x_value); - $y_length = count($y_value); - } - - $product_value = $this->_array_repeat(0, $x_length + $y_length); - - // the following for loop could be removed if the for loop following it - // (the one with nested for loops) initially set $i to 0, but - // doing so would also make the result in one set of unnecessary adds, - // since on the outermost loops first pass, $product->value[$k] is going - // to always be 0 - - $carry = 0; - - for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i - $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$j] = (int) ($temp - self::$baseFull * $carry); - } - - if ($j < $stop) { - $product_value[$j] = $carry; - } - - // the above for loop is what the previous comment was talking about. the - // following for loop is the "one with nested for loops" - - for ($i = 1; $i < $y_length; ++$i) { - $carry = 0; - - for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { - $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$k] = (int) ($temp - self::$baseFull * $carry); - } - - if ($k < $stop) { - $product_value[$k] = $carry; - } - } - - return array( - self::VALUE => $this->_trim($product_value), - self::SIGN => $x_negative != $y_negative - ); - } - - /** - * Montgomery Modular Reduction - * - * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n. - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be - * improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function - * to work correctly. - * - * @see self::_prepMontgomery() - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $n - * @return array - */ - function _montgomery($x, $n) - { - static $cache = array( - self::VARIABLE => array(), - self::DATA => array() - ); - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $x; - $cache[self::DATA][] = $this->_modInverse67108864($n); - } - - $k = count($n); - - $result = array(self::VALUE => $x); - - for ($i = 0; $i < $k; ++$i) { - $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; - $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $this->_regularMultiply(array($temp), $n); - $temp = array_merge($this->_array_repeat(0, $i), $temp); - $result = $this->_add($result[self::VALUE], false, $temp, false); - } - - $result[self::VALUE] = array_slice($result[self::VALUE], $k); - - if ($this->_compare($result, false, $n, false) >= 0) { - $result = $this->_subtract($result[self::VALUE], false, $n, false); - } - - return $result[self::VALUE]; - } - - /** - * Montgomery Multiply - * - * Interleaves the montgomery reduction and long multiplication algorithms together as described in - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} - * - * @see self::_prepMontgomery() - * @see self::_montgomery() - * @access private - * @param array $x - * @param array $y - * @param array $m - * @return array - */ - function _montgomeryMultiply($x, $y, $m) - { - $temp = $this->_multiply($x, false, $y, false); - return $this->_montgomery($temp[self::VALUE], $m); - - // the following code, although not callable, can be run independently of the above code - // although the above code performed better in my benchmarks the following could might - // perform better under different circumstances. in lieu of deleting it it's just been - // made uncallable - - static $cache = array( - self::VARIABLE => array(), - self::DATA => array() - ); - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - $cache[self::DATA][] = $this->_modInverse67108864($m); - } - - $n = max(count($x), count($y), count($m)); - $x = array_pad($x, $n, 0); - $y = array_pad($y, $n, 0); - $m = array_pad($m, $n, 0); - $a = array(self::VALUE => $this->_array_repeat(0, $n + 1)); - for ($i = 0; $i < $n; ++$i) { - $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; - $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $temp * $cache[self::DATA][$key]; - $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false); - $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false); - $a[self::VALUE] = array_slice($a[self::VALUE], 1); - } - if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) { - $a = $this->_subtract($a[self::VALUE], false, $m, false); - } - return $a[self::VALUE]; - } - - /** - * Prepare a number for use in Montgomery Modular Reductions - * - * @see self::_montgomery() - * @see self::_slidingWindow() - * @access private - * @param array $x - * @param array $n - * @return array - */ - function _prepMontgomery($x, $n) - { - $lhs = new static(); - $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x); - $rhs = new static(); - $rhs->value = $n; - - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - /** - * Modular Inverse of a number mod 2**26 (eg. 67108864) - * - * Based off of the bnpInvDigit function implemented and justified in the following URL: - * - * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} - * - * The following URL provides more info: - * - * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} - * - * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For - * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields - * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't - * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that - * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the - * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to - * 40 bits, which only 64-bit floating points will support. - * - * Thanks to Pedro Gimeno Fortea for input! - * - * @see self::_montgomery() - * @access private - * @param array $x - * @return int - */ - function _modInverse67108864($x) // 2**26 == 67,108,864 - { - $x = -$x[0]; - $result = $x & 0x3; // x**-1 mod 2**2 - $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 - $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 - $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 - $result = fmod($result * (2 - fmod($x * $result, self::$baseFull)), self::$baseFull); // x**-1 mod 2**26 - return $result & self::$maxDigit; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * Here's an example: - * - * modInverse($b); - * echo $c->toString(); // outputs 4 - * - * echo "\r\n"; - * - * $d = $a->multiply($c); - * list(, $d) = $d->divide($b); - * echo $d; // outputs 1 (as per the definition of modular inverse) - * ?> - * - * - * @param \phpseclib\Math\BigInteger $n - * @return \phpseclib\Math\BigInteger|false - * @access public - * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information. - */ - function modInverse($n) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_invert($this->value, $n->value); - - return ($temp->value === false) ? false : $this->_normalize($temp); - } - - static $zero, $one; - if (!isset($zero)) { - $zero = new static(); - $one = new static(1); - } - - // $x mod -$n == $x mod $n. - $n = $n->abs(); - - if ($this->compare($zero) < 0) { - $temp = $this->abs(); - $temp = $temp->modInverse($n); - return $this->_normalize($n->subtract($temp)); - } - - extract($this->extendedGCD($n)); - - if (!$gcd->equals($one)) { - return false; - } - - $x = $x->compare($zero) < 0 ? $x->add($n) : $x; - - return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x); - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that - * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which - * combination is returned is dependent upon which mode is in use. See - * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. - * - * Here's an example: - * - * extendedGCD($b)); - * - * echo $gcd->toString() . "\r\n"; // outputs 21 - * echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $n - * @return \phpseclib\Math\BigInteger - * @access public - * @internal Calculates the GCD using the binary xGCD algorithim described in - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes, - * the more traditional algorithim requires "relatively costly multiple-precision divisions". - */ - function extendedGCD($n) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - extract(gmp_gcdext($this->value, $n->value)); - - return array( - 'gcd' => $this->_normalize(new static($g)), - 'x' => $this->_normalize(new static($s)), - 'y' => $this->_normalize(new static($t)) - ); - case self::MODE_BCMATH: - // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works - // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, - // the basic extended euclidean algorithim is what we're using. - - $u = $this->value; - $v = $n->value; - - $a = '1'; - $b = '0'; - $c = '0'; - $d = '1'; - - while (bccomp($v, '0', 0) != 0) { - $q = bcdiv($u, $v, 0); - - $temp = $u; - $u = $v; - $v = bcsub($temp, bcmul($v, $q, 0), 0); - - $temp = $a; - $a = $c; - $c = bcsub($temp, bcmul($a, $q, 0), 0); - - $temp = $b; - $b = $d; - $d = bcsub($temp, bcmul($b, $q, 0), 0); - } - - return array( - 'gcd' => $this->_normalize(new static($u)), - 'x' => $this->_normalize(new static($a)), - 'y' => $this->_normalize(new static($b)) - ); - } - - $y = $n->copy(); - $x = $this->copy(); - $g = new static(); - $g->value = array(1); - - while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) { - $x->_rshift(1); - $y->_rshift(1); - $g->_lshift(1); - } - - $u = $x->copy(); - $v = $y->copy(); - - $a = new static(); - $b = new static(); - $c = new static(); - $d = new static(); - - $a->value = $d->value = $g->value = array(1); - $b->value = $c->value = array(); - - while (!empty($u->value)) { - while (!($u->value[0] & 1)) { - $u->_rshift(1); - if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) { - $a = $a->add($y); - $b = $b->subtract($x); - } - $a->_rshift(1); - $b->_rshift(1); - } - - while (!($v->value[0] & 1)) { - $v->_rshift(1); - if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) { - $c = $c->add($y); - $d = $d->subtract($x); - } - $c->_rshift(1); - $d->_rshift(1); - } - - if ($u->compare($v) >= 0) { - $u = $u->subtract($v); - $a = $a->subtract($c); - $b = $b->subtract($d); - } else { - $v = $v->subtract($u); - $c = $c->subtract($a); - $d = $d->subtract($b); - } - } - - return array( - 'gcd' => $this->_normalize($g->multiply($v)), - 'x' => $this->_normalize($c), - 'y' => $this->_normalize($d) - ); - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * Here's an example: - * - * extendedGCD($b); - * - * echo $gcd->toString() . "\r\n"; // outputs 21 - * ?> - * - * - * @param \phpseclib\Math\BigInteger $n - * @return \phpseclib\Math\BigInteger - * @access public - */ - function gcd($n) - { - extract($this->extendedGCD($n)); - return $gcd; - } - - /** - * Absolute value. - * - * @return \phpseclib\Math\BigInteger - * @access public - */ - function abs() - { - $temp = new static(); - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp->value = gmp_abs($this->value); - break; - case self::MODE_BCMATH: - $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value; - break; - default: - $temp->value = $this->value; - } - - return $temp; - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * @param \phpseclib\Math\BigInteger $y - * @return int that is < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @access public - * @see self::equals() - * @internal Could return $this->subtract($x), but that's not as fast as what we do do. - */ - function compare($y) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $r = gmp_cmp($this->value, $y->value); - if ($r < -1) { - $r = -1; - } - if ($r > 1) { - $r = 1; - } - return $r; - case self::MODE_BCMATH: - return bccomp($this->value, $y->value, 0); - } - - return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative); - } - - /** - * Compares two numbers. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return int - * @see self::compare() - * @access private - */ - function _compare($x_value, $x_negative, $y_value, $y_negative) - { - if ($x_negative != $y_negative) { - return (!$x_negative && $y_negative) ? 1 : -1; - } - - $result = $x_negative ? -1 : 1; - - if (count($x_value) != count($y_value)) { - return (count($x_value) > count($y_value)) ? $result : -$result; - } - $size = max(count($x_value), count($y_value)); - - $x_value = array_pad($x_value, $size, 0); - $y_value = array_pad($y_value, $size, 0); - - for ($i = count($x_value) - 1; $i >= 0; --$i) { - if ($x_value[$i] != $y_value[$i]) { - return ($x_value[$i] > $y_value[$i]) ? $result : -$result; - } - } - - return 0; - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param \phpseclib\Math\BigInteger $x - * @return bool - * @access public - * @see self::compare() - */ - function equals($x) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - return gmp_cmp($this->value, $x->value) == 0; - default: - return $this->value === $x->value && $this->is_negative == $x->is_negative; - } - } - - /** - * Set Precision - * - * Some bitwise operations give different results depending on the precision being used. Examples include left - * shift, not, and rotates. - * - * @param int $bits - * @access public - */ - function setPrecision($bits) - { - $this->precision = $bits; - if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) { - $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); - } else { - $this->bitmask = new static(bcpow('2', $bits, 0)); - } - - $temp = $this->_normalize($this); - $this->value = $temp->value; - } - - /** - * Logical And - * - * @param \phpseclib\Math\BigInteger $x - * @access public - * @internal Implemented per a request by Lluis Pamies i Juarez - * @return \phpseclib\Math\BigInteger - */ - function bitwise_and($x) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_and($this->value, $x->value); - - return $this->_normalize($temp); - case self::MODE_BCMATH: - $left = $this->toBytes(); - $right = $x->toBytes(); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->_normalize(new static($left & $right, 256)); - } - - $result = $this->copy(); - - $length = min(count($x->value), count($this->value)); - - $result->value = array_slice($result->value, 0, $length); - - for ($i = 0; $i < $length; ++$i) { - $result->value[$i]&= $x->value[$i]; - } - - return $this->_normalize($result); - } - - /** - * Logical Or - * - * @param \phpseclib\Math\BigInteger $x - * @access public - * @internal Implemented per a request by Lluis Pamies i Juarez - * @return \phpseclib\Math\BigInteger - */ - function bitwise_or($x) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_or($this->value, $x->value); - - return $this->_normalize($temp); - case self::MODE_BCMATH: - $left = $this->toBytes(); - $right = $x->toBytes(); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->_normalize(new static($left | $right, 256)); - } - - $length = max(count($this->value), count($x->value)); - $result = $this->copy(); - $result->value = array_pad($result->value, $length, 0); - $x->value = array_pad($x->value, $length, 0); - - for ($i = 0; $i < $length; ++$i) { - $result->value[$i]|= $x->value[$i]; - } - - return $this->_normalize($result); - } - - /** - * Logical Exclusive-Or - * - * @param \phpseclib\Math\BigInteger $x - * @access public - * @internal Implemented per a request by Lluis Pamies i Juarez - * @return \phpseclib\Math\BigInteger - */ - function bitwise_xor($x) - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - $temp = new static(); - $temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value)); - return $this->_normalize($temp); - case self::MODE_BCMATH: - $left = $this->toBytes(); - $right = $x->toBytes(); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->_normalize(new static($left ^ $right, 256)); - } - - $length = max(count($this->value), count($x->value)); - $result = $this->copy(); - $result->is_negative = false; - $result->value = array_pad($result->value, $length, 0); - $x->value = array_pad($x->value, $length, 0); - - for ($i = 0; $i < $length; ++$i) { - $result->value[$i]^= $x->value[$i]; - } - - return $this->_normalize($result); - } - - /** - * Logical Not - * - * @access public - * @internal Implemented per a request by Lluis Pamies i Juarez - * @return \phpseclib\Math\BigInteger - */ - function bitwise_not() - { - // calculuate "not" without regard to $this->precision - // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) - $temp = $this->toBytes(); - if ($temp == '') { - return $this->_normalize(new static()); - } - $pre_msb = decbin(ord($temp[0])); - $temp = ~$temp; - $msb = decbin(ord($temp[0])); - if (strlen($msb) == 8) { - $msb = substr($msb, strpos($msb, '0')); - } - $temp[0] = chr(bindec($msb)); - - // see if we need to add extra leading 1's - $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; - $new_bits = $this->precision - $current_bits; - if ($new_bits <= 0) { - return $this->_normalize(new static($temp, 256)); - } - - // generate as many leading 1's as we need to. - $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); - $this->_base256_lshift($leading_ones, $current_bits); - - $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); - - return $this->_normalize(new static($leading_ones | $temp, 256)); - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return \phpseclib\Math\BigInteger - * @access public - * @internal The only version that yields any speed increases is the internal version. - */ - function bitwise_rightShift($shift) - { - $temp = new static(); - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - static $two; - - if (!isset($two)) { - $two = gmp_init('2'); - } - - $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift)); - - break; - case self::MODE_BCMATH: - $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); - - break; - default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten - // and I don't want to do that... - $temp->value = $this->value; - $temp->_rshift($shift); - } - - return $this->_normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return \phpseclib\Math\BigInteger - * @access public - * @internal The only version that yields any speed increases is the internal version. - */ - function bitwise_leftShift($shift) - { - $temp = new static(); - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - static $two; - - if (!isset($two)) { - $two = gmp_init('2'); - } - - $temp->value = gmp_mul($this->value, gmp_pow($two, $shift)); - - break; - case self::MODE_BCMATH: - $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); - - break; - default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten - // and I don't want to do that... - $temp->value = $this->value; - $temp->_lshift($shift); - } - - return $this->_normalize($temp); - } - - /** - * Logical Left Rotate - * - * Instead of the top x bits being dropped they're appended to the shifted bit string. - * - * @param int $shift - * @return \phpseclib\Math\BigInteger - * @access public - */ - function bitwise_leftRotate($shift) - { - $bits = $this->toBytes(); - - if ($this->precision > 0) { - $precision = $this->precision; - if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { - $mask = $this->bitmask->subtract(new static(1)); - $mask = $mask->toBytes(); - } else { - $mask = $this->bitmask->toBytes(); - } - } else { - $temp = ord($bits[0]); - for ($i = 0; $temp >> $i; ++$i) { - } - $precision = 8 * strlen($bits) - 8 + $i; - $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); - } - - if ($shift < 0) { - $shift+= $precision; - } - $shift%= $precision; - - if (!$shift) { - return $this->copy(); - } - - $left = $this->bitwise_leftShift($shift); - $left = $left->bitwise_and(new static($mask, 256)); - $right = $this->bitwise_rightShift($precision - $shift); - $result = MATH_BIGINTEGER_MODE != self::MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right); - return $this->_normalize($result); - } - - /** - * Logical Right Rotate - * - * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. - * - * @param int $shift - * @return \phpseclib\Math\BigInteger - * @access public - */ - function bitwise_rightRotate($shift) - { - return $this->bitwise_leftRotate(-$shift); - } - - /** - * Generates a random BigInteger - * - * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not. - * - * @param int $size - * @return \phpseclib\Math\BigInteger - * @access private - */ - function _random_number_helper($size) - { - if (class_exists('\phpseclib\Crypt\Random')) { - $random = Random::string($size); - } else { - $random = ''; - - if ($size & 1) { - $random.= chr(mt_rand(0, 255)); - } - - $blocks = $size >> 1; - for ($i = 0; $i < $blocks; ++$i) { - // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems - $random.= pack('n', mt_rand(0, 0xFFFF)); - } - } - - return new static($random, 256); - } - - /** - * Generate a random number - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * $min->random($max) - * $max->random($min) - * - * @param \phpseclib\Math\BigInteger $arg1 - * @param \phpseclib\Math\BigInteger $arg2 - * @return \phpseclib\Math\BigInteger - * @access public - * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object. - * That method is still supported for BC purposes. - */ - function random($arg1, $arg2 = false) - { - if ($arg1 === false) { - return false; - } - - if ($arg2 === false) { - $max = $arg1; - $min = $this; - } else { - $min = $arg1; - $max = $arg2; - } - - $compare = $max->compare($min); - - if (!$compare) { - return $this->_normalize($min); - } elseif ($compare < 0) { - // if $min is bigger then $max, swap $min and $max - $temp = $max; - $max = $min; - $min = $temp; - } - - static $one; - if (!isset($one)) { - $one = new static(1); - } - - $max = $max->subtract($min->subtract($one)); - $size = strlen(ltrim($max->toBytes(), chr(0))); - - /* - doing $random % $max doesn't work because some numbers will be more likely to occur than others. - eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 - would produce 5 whereas the only value of random that could produce 139 would be 139. ie. - not all numbers would be equally likely. some would be more likely than others. - - creating a whole new random number until you find one that is within the range doesn't work - because, for sufficiently small ranges, the likelihood that you'd get a number within that range - would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability - would be pretty high that $random would be greater than $max. - - phpseclib works around this using the technique described here: - - http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string - */ - $random_max = new static(chr(1) . str_repeat("\0", $size), 256); - $random = $this->_random_number_helper($size); - - list($max_multiple) = $random_max->divide($max); - $max_multiple = $max_multiple->multiply($max); - - while ($random->compare($max_multiple) >= 0) { - $random = $random->subtract($max_multiple); - $random_max = $random_max->subtract($max_multiple); - $random = $random->bitwise_leftShift(8); - $random = $random->add($this->_random_number_helper(1)); - $random_max = $random_max->bitwise_leftShift(8); - list($max_multiple) = $random_max->divide($max); - $max_multiple = $max_multiple->multiply($max); - } - list(, $random) = $random->divide($max); - - return $this->_normalize($random->add($min)); - } - - /** - * Generate a random prime number. - * - * If there's not a prime within the given range, false will be returned. - * If more than $timeout seconds have elapsed, give up and return false. - * - * @param \phpseclib\Math\BigInteger $arg1 - * @param \phpseclib\Math\BigInteger $arg2 - * @param int $timeout - * @return Math_BigInteger|false - * @access public - * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}. - */ - function randomPrime($arg1, $arg2 = false, $timeout = false) - { - if ($arg1 === false) { - return false; - } - - if ($arg2 === false) { - $max = $arg1; - $min = $this; - } else { - $min = $arg1; - $max = $arg2; - } - - $compare = $max->compare($min); - - if (!$compare) { - return $min->isPrime() ? $min : false; - } elseif ($compare < 0) { - // if $min is bigger then $max, swap $min and $max - $temp = $max; - $max = $min; - $min = $temp; - } - - static $one, $two; - if (!isset($one)) { - $one = new static(1); - $two = new static(2); - } - - $start = time(); - - $x = $this->random($min, $max); - - // gmp_nextprime() requires PHP 5 >= 5.2.0 per . - if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) { - $p = new static(); - $p->value = gmp_nextprime($x->value); - - if ($p->compare($max) <= 0) { - return $p; - } - - if (!$min->equals($x)) { - $x = $x->subtract($one); - } - - return $x->randomPrime($min, $x); - } - - if ($x->equals($two)) { - return $x; - } - - $x->_make_odd(); - if ($x->compare($max) > 0) { - // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range - if ($min->equals($max)) { - return false; - } - $x = $min->copy(); - $x->_make_odd(); - } - - $initial_x = $x->copy(); - - while (true) { - if ($timeout !== false && time() - $start > $timeout) { - return false; - } - - if ($x->isPrime()) { - return $x; - } - - $x = $x->add($two); - - if ($x->compare($max) > 0) { - $x = $min->copy(); - if ($x->equals($two)) { - return $x; - } - $x->_make_odd(); - } - - if ($x->equals($initial_x)) { - return false; - } - } - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - * @access private - */ - function _make_odd() - { - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - gmp_setbit($this->value, 0); - break; - case self::MODE_BCMATH: - if ($this->value[strlen($this->value) - 1] % 2 == 0) { - $this->value = bcadd($this->value, '1'); - } - break; - default: - $this->value[0] |= 1; - } - } - - /** - * Checks a numer to see if it's prime - * - * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the - * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads - * on a website instead of just one. - * - * @param \phpseclib\Math\BigInteger $t - * @return bool - * @access public - * @internal Uses the - * {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. See - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}. - */ - function isPrime($t = false) - { - $length = strlen($this->toBytes()); - - if (!$t) { - // see HAC 4.49 "Note (controlling the error probability)" - // @codingStandardsIgnoreStart - if ($length >= 163) { $t = 2; } // floor(1300 / 8) - else if ($length >= 106) { $t = 3; } // floor( 850 / 8) - else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) - else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) - else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) - else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) - else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) - else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) - else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) - else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) - else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) - else { $t = 27; } - // @codingStandardsIgnoreEnd - } - - // ie. gmp_testbit($this, 0) - // ie. isEven() or !isOdd() - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - return gmp_prob_prime($this->value, $t) != 0; - case self::MODE_BCMATH: - if ($this->value === '2') { - return true; - } - if ($this->value[strlen($this->value) - 1] % 2 == 0) { - return false; - } - break; - default: - if ($this->value == array(2)) { - return true; - } - if (~$this->value[0] & 1) { - return false; - } - } - - static $primes, $zero, $one, $two; - - if (!isset($primes)) { - $primes = array( - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997 - ); - - if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) { - for ($i = 0; $i < count($primes); ++$i) { - $primes[$i] = new static($primes[$i]); - } - } - - $zero = new static(); - $one = new static(1); - $two = new static(2); - } - - if ($this->equals($one)) { - return false; - } - - // see HAC 4.4.1 "Random search for probable primes" - if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) { - foreach ($primes as $prime) { - list(, $r) = $this->divide($prime); - if ($r->equals($zero)) { - return $this->equals($prime); - } - } - } else { - $value = $this->value; - foreach ($primes as $prime) { - list(, $r) = $this->_divide_digit($value, $prime); - if (!$r) { - return count($value) == 1 && $value[0] == $prime; - } - } - } - - $n = $this->copy(); - $n_1 = $n->subtract($one); - $n_2 = $n->subtract($two); - - $r = $n_1->copy(); - $r_value = $r->value; - // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { - $s = 0; - // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier - while ($r->value[strlen($r->value) - 1] % 2 == 0) { - $r->value = bcdiv($r->value, '2', 0); - ++$s; - } - } else { - for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { - $temp = ~$r_value[$i] & 0xFFFFFF; - for ($j = 1; ($temp >> $j) & 1; ++$j) { - } - if ($j != 25) { - break; - } - } - $s = 26 * $i + $j; - $r->_rshift($s); - } - - for ($i = 0; $i < $t; ++$i) { - $a = $this->random($two, $n_2); - $y = $a->modPow($r, $n); - - if (!$y->equals($one) && !$y->equals($n_1)) { - for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { - $y = $y->modPow($two, $n); - if ($y->equals($one)) { - return false; - } - } - - if (!$y->equals($n_1)) { - return false; - } - } - } - return true; - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits. - * - * @param int $shift - * @access private - */ - function _lshift($shift) - { - if ($shift == 0) { - return; - } - - $num_digits = (int) ($shift / self::$base); - $shift %= self::$base; - $shift = 1 << $shift; - - $carry = 0; - - for ($i = 0; $i < count($this->value); ++$i) { - $temp = $this->value[$i] * $shift + $carry; - $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $this->value[$i] = (int) ($temp - $carry * self::$baseFull); - } - - if ($carry) { - $this->value[count($this->value)] = $carry; - } - - while ($num_digits--) { - array_unshift($this->value, 0); - } - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits. - * - * @param int $shift - * @access private - */ - function _rshift($shift) - { - if ($shift == 0) { - return; - } - - $num_digits = (int) ($shift / self::$base); - $shift %= self::$base; - $carry_shift = self::$base - $shift; - $carry_mask = (1 << $shift) - 1; - - if ($num_digits) { - $this->value = array_slice($this->value, $num_digits); - } - - $carry = 0; - - for ($i = count($this->value) - 1; $i >= 0; --$i) { - $temp = $this->value[$i] >> $shift | $carry; - $carry = ($this->value[$i] & $carry_mask) << $carry_shift; - $this->value[$i] = $temp; - } - - $this->value = $this->_trim($this->value); - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param \phpseclib\Math\BigInteger $result - * @return \phpseclib\Math\BigInteger - * @see self::_trim() - * @access private - */ - function _normalize($result) - { - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - switch (MATH_BIGINTEGER_MODE) { - case self::MODE_GMP: - if ($this->bitmask !== false) { - $flip = gmp_cmp($result->value, gmp_init(0)) < 0; - if ($flip) { - $result->value = gmp_neg($result->value); - } - $result->value = gmp_and($result->value, $result->bitmask->value); - if ($flip) { - $result->value = gmp_neg($result->value); - } - } - - return $result; - case self::MODE_BCMATH: - if (!empty($result->bitmask->value)) { - $result->value = bcmod($result->value, $result->bitmask->value); - } - - return $result; - } - - $value = &$result->value; - - if (!count($value)) { - $result->is_negative = false; - return $result; - } - - $value = $this->_trim($value); - - if (!empty($result->bitmask->value)) { - $length = min(count($value), count($this->bitmask->value)); - $value = array_slice($value, 0, $length); - - for ($i = 0; $i < $length; ++$i) { - $value[$i] = $value[$i] & $this->bitmask->value[$i]; - } - } - - return $result; - } - - /** - * Trim - * - * Removes leading zeros - * - * @param array $value - * @return \phpseclib\Math\BigInteger - * @access private - */ - function _trim($value) - { - for ($i = count($value) - 1; $i >= 0; --$i) { - if ($value[$i]) { - break; - } - unset($value[$i]); - } - - return $value; - } - - /** - * Array Repeat - * - * @param array $input - * @param mixed $multiplier - * @return array - * @access private - */ - function _array_repeat($input, $multiplier) - { - return ($multiplier) ? array_fill(0, $multiplier, $input) : array(); - } - - /** - * Logical Left Shift - * - * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. - * - * @param string $x (by reference) - * @param int $shift - * @return string - * @access private - */ - function _base256_lshift(&$x, $shift) - { - if ($shift == 0) { - return; - } - - $num_bytes = $shift >> 3; // eg. floor($shift/8) - $shift &= 7; // eg. $shift % 8 - - $carry = 0; - for ($i = strlen($x) - 1; $i >= 0; --$i) { - $temp = ord($x[$i]) << $shift | $carry; - $x[$i] = chr($temp); - $carry = $temp >> 8; - } - $carry = ($carry != 0) ? chr($carry) : ''; - $x = $carry . $x . str_repeat(chr(0), $num_bytes); - } - - /** - * Logical Right Shift - * - * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder. - * - * @param string $x (by referenc) - * @param int $shift - * @return string - * @access private - */ - function _base256_rshift(&$x, $shift) - { - if ($shift == 0) { - $x = ltrim($x, chr(0)); - return ''; - } - - $num_bytes = $shift >> 3; // eg. floor($shift/8) - $shift &= 7; // eg. $shift % 8 - - $remainder = ''; - if ($num_bytes) { - $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes; - $remainder = substr($x, $start); - $x = substr($x, 0, -$num_bytes); - } - - $carry = 0; - $carry_shift = 8 - $shift; - for ($i = 0; $i < strlen($x); ++$i) { - $temp = (ord($x[$i]) >> $shift) | $carry; - $carry = (ord($x[$i]) << $carry_shift) & 0xFF; - $x[$i] = chr($temp); - } - $x = ltrim($x, chr(0)); - - $remainder = chr($carry >> $carry_shift) . $remainder; - - return ltrim($remainder, chr(0)); - } - - // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long - // at 32-bits, while java's longs are 64-bits. - - /** - * Converts 32-bit integers to bytes. - * - * @param int $x - * @return string - * @access private - */ - function _int2bytes($x) - { - return ltrim(pack('N', $x), chr(0)); - } - - /** - * Converts bytes to 32-bit integers - * - * @param string $x - * @return int - * @access private - */ - function _bytes2int($x) - { - $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT)); - return $temp['int']; - } - - /** - * DER-encode an integer - * - * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL - * - * @see self::modPow() - * @access private - * @param int $length - * @return string - */ - function _encodeASN1Length($length) - { - if ($length <= 0x7F) { - return chr($length); - } - - $temp = ltrim(pack('N', $length), chr(0)); - return pack('Ca*', 0x80 | strlen($temp), $temp); - } - - /** - * Single digit division - * - * Even if int64 is being used the division operator will return a float64 value - * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't - * have the precision of int64 this is a problem so, when int64 is being used, - * we'll guarantee that the dividend is divisible by first subtracting the remainder. - * - * @access private - * @param int $x - * @param int $y - * @return int - */ - function _safe_divide($x, $y) - { - if (self::$base === 26) { - return (int) ($x / $y); - } - - // self::$base === 31 - return ($x - ($x % $y)) / $y; - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php deleted file mode 100644 index cf13496cd..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php +++ /dev/null @@ -1,342 +0,0 @@ - - * login('username', 'password')) { - * exit('bad login'); - * } - * $scp = new \phpseclib\Net\SCP($ssh); - * - * $scp->put('abcd', str_repeat('x', 1024*1024)); - * ?> - * - * - * @category Net - * @package SCP - * @author Jim Wigginton - * @copyright 2010 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Net; - -/** - * Pure-PHP implementations of SCP. - * - * @package SCP - * @author Jim Wigginton - * @access public - */ -class SCP -{ - /**#@+ - * @access public - * @see \phpseclib\Net\SCP::put() - */ - /** - * Reads data from a local file. - */ - const SOURCE_LOCAL_FILE = 1; - /** - * Reads data from a string. - */ - const SOURCE_STRING = 2; - /**#@-*/ - - /**#@+ - * @access private - * @see \phpseclib\Net\SCP::_send() - * @see \phpseclib\Net\SCP::_receive() - */ - /** - * SSH1 is being used. - */ - const MODE_SSH1 = 1; - /** - * SSH2 is being used. - */ - const MODE_SSH2 = 2; - /**#@-*/ - - /** - * SSH Object - * - * @var object - * @access private - */ - var $ssh; - - /** - * Packet Size - * - * @var int - * @access private - */ - var $packet_size; - - /** - * Mode - * - * @var int - * @access private - */ - var $mode; - - /** - * Default Constructor. - * - * Connects to an SSH server - * - * @param \phpseclib\Net\SSH1|\phpseclib\Net\SSH2 $ssh - * @return \phpseclib\Net\SCP - * @access public - */ - function __construct($ssh) - { - if ($ssh instanceof SSH2) { - $this->mode = self::MODE_SSH2; - } elseif ($ssh instanceof SSH1) { - $this->packet_size = 50000; - $this->mode = self::MODE_SSH1; - } else { - return; - } - - $this->ssh = $ssh; - } - - /** - * Uploads a file to the SCP server. - * - * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. - * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes - * long, containing 'filename.ext' as its contents. - * - * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will - * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how - * large $remote_file will be, as well. - * - * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take - * care of that, yourself. - * - * @param string $remote_file - * @param string $data - * @param int $mode - * @param callable $callback - * @return bool - * @access public - */ - function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null) - { - if (!isset($this->ssh)) { - return false; - } - - if (empty($remote_file)) { - user_error('remote_file cannot be blank', E_USER_NOTICE); - return false; - } - - if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to - return false; - } - - $temp = $this->_receive(); - if ($temp !== chr(0)) { - return false; - } - - if ($this->mode == self::MODE_SSH2) { - $this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4; - } - - $remote_file = basename($remote_file); - - if ($mode == self::SOURCE_STRING) { - $size = strlen($data); - } else { - if (!is_file($data)) { - user_error("$data is not a valid file", E_USER_NOTICE); - return false; - } - - $fp = @fopen($data, 'rb'); - if (!$fp) { - return false; - } - $size = filesize($data); - } - - $this->_send('C0644 ' . $size . ' ' . $remote_file . "\n"); - - $temp = $this->_receive(); - if ($temp !== chr(0)) { - return false; - } - - $sent = 0; - while ($sent < $size) { - $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size); - $this->_send($temp); - $sent+= strlen($temp); - - if (is_callable($callback)) { - call_user_func($callback, $sent); - } - } - $this->_close(); - - if ($mode != self::SOURCE_STRING) { - fclose($fp); - } - - return true; - } - - /** - * Downloads a file from the SCP server. - * - * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if - * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the - * operation - * - * @param string $remote_file - * @param string $local_file - * @return mixed - * @access public - */ - function get($remote_file, $local_file = false) - { - if (!isset($this->ssh)) { - return false; - } - - if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from - return false; - } - - $this->_send("\0"); - - if (!preg_match('#(?[^ ]+) (?\d+) (?.+)#', rtrim($this->_receive()), $info)) { - return false; - } - - $this->_send("\0"); - - $size = 0; - - if ($local_file !== false) { - $fp = @fopen($local_file, 'wb'); - if (!$fp) { - return false; - } - } - - $content = ''; - while ($size < $info['size']) { - $data = $this->_receive(); - // SCP usually seems to split stuff out into 16k chunks - $size+= strlen($data); - - if ($local_file === false) { - $content.= $data; - } else { - fputs($fp, $data); - } - } - - $this->_close(); - - if ($local_file !== false) { - fclose($fp); - return true; - } - - return $content; - } - - /** - * Sends a packet to an SSH server - * - * @param string $data - * @access private - */ - function _send($data) - { - switch ($this->mode) { - case self::MODE_SSH2: - $this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data); - break; - case self::MODE_SSH1: - $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data); - $this->ssh->_send_binary_packet($data); - } - } - - /** - * Receives a packet from an SSH server - * - * @return string - * @access private - */ - function _receive() - { - switch ($this->mode) { - case self::MODE_SSH2: - return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true); - case self::MODE_SSH1: - if (!$this->ssh->bitmap) { - return false; - } - while (true) { - $response = $this->ssh->_get_binary_packet(); - switch ($response[SSH1::RESPONSE_TYPE]) { - case NET_SSH1_SMSG_STDOUT_DATA: - if (strlen($response[SSH1::RESPONSE_DATA]) < 4) { - return false; - } - extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA])); - return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length); - case NET_SSH1_SMSG_STDERR_DATA: - break; - case NET_SSH1_SMSG_EXITSTATUS: - $this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION)); - fclose($this->ssh->fsock); - $this->ssh->bitmap = 0; - return false; - default: - user_error('Unknown packet received', E_USER_NOTICE); - return false; - } - } - } - } - - /** - * Closes the connection to an SSH server - * - * @access private - */ - function _close() - { - switch ($this->mode) { - case self::MODE_SSH2: - $this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true); - break; - case self::MODE_SSH1: - $this->ssh->disconnect(); - } - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php deleted file mode 100644 index e372b8b92..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php +++ /dev/null @@ -1,1646 +0,0 @@ - - * login('username', 'password')) { - * exit('Login Failed'); - * } - * - * echo $ssh->exec('ls -la'); - * ?> - * - * - * Here's another short example: - * - * login('username', 'password')) { - * exit('Login Failed'); - * } - * - * echo $ssh->read('username@username:~$'); - * $ssh->write("ls -la\n"); - * echo $ssh->read('username@username:~$'); - * ?> - * - * - * More information on the SSHv1 specification can be found by reading - * {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}. - * - * @category Net - * @package SSH1 - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Net; - -use phpseclib\Crypt\DES; -use phpseclib\Crypt\Random; -use phpseclib\Crypt\TripleDES; -use phpseclib\Math\BigInteger; - -/** - * Pure-PHP implementation of SSHv1. - * - * @package SSH1 - * @author Jim Wigginton - * @access public - */ -class SSH1 -{ - /**#@+ - * Encryption Methods - * - * @see \phpseclib\Net\SSH1::getSupportedCiphers() - * @access public - */ - /** - * No encryption - * - * Not supported. - */ - const CIPHER_NONE = 0; - /** - * IDEA in CFB mode - * - * Not supported. - */ - const CIPHER_IDEA = 1; - /** - * DES in CBC mode - */ - const CIPHER_DES = 2; - /** - * Triple-DES in CBC mode - * - * All implementations are required to support this - */ - const CIPHER_3DES = 3; - /** - * TRI's Simple Stream encryption CBC - * - * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h), - * although it doesn't use it (see cipher.c) - */ - const CIPHER_BROKEN_TSS = 4; - /** - * RC4 - * - * Not supported. - * - * @internal According to the SSH1 specs: - * - * "The first 16 bytes of the session key are used as the key for - * the server to client direction. The remaining 16 bytes are used - * as the key for the client to server direction. This gives - * independent 128-bit keys for each direction." - * - * This library currently only supports encryption when the same key is being used for both directions. This is - * because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps). - */ - const CIPHER_RC4 = 5; - /** - * Blowfish - * - * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and - * uses it (see cipher.c) - */ - const CIPHER_BLOWFISH = 6; - /**#@-*/ - - /**#@+ - * Authentication Methods - * - * @see \phpseclib\Net\SSH1::getSupportedAuthentications() - * @access public - */ - /** - * .rhosts or /etc/hosts.equiv - */ - const AUTH_RHOSTS = 1; - /** - * pure RSA authentication - */ - const AUTH_RSA = 2; - /** - * password authentication - * - * This is the only method that is supported by this library. - */ - const AUTH_PASSWORD = 3; - /** - * .rhosts with RSA host authentication - */ - const AUTH_RHOSTS_RSA = 4; - /**#@-*/ - - /**#@+ - * Terminal Modes - * - * @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html - * @access private - */ - const TTY_OP_END = 0; - /**#@-*/ - - /** - * The Response Type - * - * @see \phpseclib\Net\SSH1::_get_binary_packet() - * @access private - */ - const RESPONSE_TYPE = 1; - - /** - * The Response Data - * - * @see \phpseclib\Net\SSH1::_get_binary_packet() - * @access private - */ - const RESPONSE_DATA = 2; - - /**#@+ - * Execution Bitmap Masks - * - * @see \phpseclib\Net\SSH1::bitmap - * @access private - */ - const MASK_CONSTRUCTOR = 0x00000001; - const MASK_CONNECTED = 0x00000002; - const MASK_LOGIN = 0x00000004; - const MASK_SHELL = 0x00000008; - /**#@-*/ - - /**#@+ - * @access public - * @see \phpseclib\Net\SSH1::getLog() - */ - /** - * Returns the message numbers - */ - const LOG_SIMPLE = 1; - /** - * Returns the message content - */ - const LOG_COMPLEX = 2; - /** - * Outputs the content real-time - */ - const LOG_REALTIME = 3; - /** - * Dumps the content real-time to a file - */ - const LOG_REALTIME_FILE = 4; - /**#@-*/ - - /**#@+ - * @access public - * @see \phpseclib\Net\SSH1::read() - */ - /** - * Returns when a string matching $expect exactly is found - */ - const READ_SIMPLE = 1; - /** - * Returns when a string matching the regular expression $expect is found - */ - const READ_REGEX = 2; - /**#@-*/ - - /** - * The SSH identifier - * - * @var string - * @access private - */ - var $identifier = 'SSH-1.5-phpseclib'; - - /** - * The Socket Object - * - * @var object - * @access private - */ - var $fsock; - - /** - * The cryptography object - * - * @var object - * @access private - */ - var $crypto = false; - - /** - * Execution Bitmap - * - * The bits that are set represent functions that have been called already. This is used to determine - * if a requisite function has been successfully executed. If not, an error should be thrown. - * - * @var int - * @access private - */ - var $bitmap = 0; - - /** - * The Server Key Public Exponent - * - * Logged for debug purposes - * - * @see self::getServerKeyPublicExponent() - * @var string - * @access private - */ - var $server_key_public_exponent; - - /** - * The Server Key Public Modulus - * - * Logged for debug purposes - * - * @see self::getServerKeyPublicModulus() - * @var string - * @access private - */ - var $server_key_public_modulus; - - /** - * The Host Key Public Exponent - * - * Logged for debug purposes - * - * @see self::getHostKeyPublicExponent() - * @var string - * @access private - */ - var $host_key_public_exponent; - - /** - * The Host Key Public Modulus - * - * Logged for debug purposes - * - * @see self::getHostKeyPublicModulus() - * @var string - * @access private - */ - var $host_key_public_modulus; - - /** - * Supported Ciphers - * - * Logged for debug purposes - * - * @see self::getSupportedCiphers() - * @var array - * @access private - */ - var $supported_ciphers = array( - self::CIPHER_NONE => 'No encryption', - self::CIPHER_IDEA => 'IDEA in CFB mode', - self::CIPHER_DES => 'DES in CBC mode', - self::CIPHER_3DES => 'Triple-DES in CBC mode', - self::CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC', - self::CIPHER_RC4 => 'RC4', - self::CIPHER_BLOWFISH => 'Blowfish' - ); - - /** - * Supported Authentications - * - * Logged for debug purposes - * - * @see self::getSupportedAuthentications() - * @var array - * @access private - */ - var $supported_authentications = array( - self::AUTH_RHOSTS => '.rhosts or /etc/hosts.equiv', - self::AUTH_RSA => 'pure RSA authentication', - self::AUTH_PASSWORD => 'password authentication', - self::AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication' - ); - - /** - * Server Identification - * - * @see self::getServerIdentification() - * @var string - * @access private - */ - var $server_identification = ''; - - /** - * Protocol Flags - * - * @see self::__construct() - * @var array - * @access private - */ - var $protocol_flags = array(); - - /** - * Protocol Flag Log - * - * @see self::getLog() - * @var array - * @access private - */ - var $protocol_flag_log = array(); - - /** - * Message Log - * - * @see self::getLog() - * @var array - * @access private - */ - var $message_log = array(); - - /** - * Real-time log file pointer - * - * @see self::_append_log() - * @var resource - * @access private - */ - var $realtime_log_file; - - /** - * Real-time log file size - * - * @see self::_append_log() - * @var int - * @access private - */ - var $realtime_log_size; - - /** - * Real-time log file wrap boolean - * - * @see self::_append_log() - * @var bool - * @access private - */ - var $realtime_log_wrap; - - /** - * Interactive Buffer - * - * @see self::read() - * @var array - * @access private - */ - var $interactiveBuffer = ''; - - /** - * Timeout - * - * @see self::setTimeout() - * @access private - */ - var $timeout; - - /** - * Current Timeout - * - * @see self::_get_channel_packet() - * @access private - */ - var $curTimeout; - - /** - * Log Boundary - * - * @see self::_format_log() - * @access private - */ - var $log_boundary = ':'; - - /** - * Log Long Width - * - * @see self::_format_log() - * @access private - */ - var $log_long_width = 65; - - /** - * Log Short Width - * - * @see self::_format_log() - * @access private - */ - var $log_short_width = 16; - - /** - * Hostname - * - * @see self::__construct() - * @see self::_connect() - * @var string - * @access private - */ - var $host; - - /** - * Port Number - * - * @see self::__construct() - * @see self::_connect() - * @var int - * @access private - */ - var $port; - - /** - * Timeout for initial connection - * - * Set by the constructor call. Calling setTimeout() is optional. If it's not called functions like - * exec() won't timeout unless some PHP setting forces it too. The timeout specified in the constructor, - * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be - * 10 seconds. It is used by fsockopen() in that function. - * - * @see self::__construct() - * @see self::_connect() - * @var int - * @access private - */ - var $connectionTimeout; - - /** - * Default cipher - * - * @see self::__construct() - * @see self::_connect() - * @var int - * @access private - */ - var $cipher; - - /** - * Default Constructor. - * - * Connects to an SSHv1 server - * - * @param string $host - * @param int $port - * @param int $timeout - * @param int $cipher - * @return \phpseclib\Net\SSH1 - * @access public - */ - function __construct($host, $port = 22, $timeout = 10, $cipher = self::CIPHER_3DES) - { - $this->protocol_flags = array( - 1 => 'NET_SSH1_MSG_DISCONNECT', - 2 => 'NET_SSH1_SMSG_PUBLIC_KEY', - 3 => 'NET_SSH1_CMSG_SESSION_KEY', - 4 => 'NET_SSH1_CMSG_USER', - 9 => 'NET_SSH1_CMSG_AUTH_PASSWORD', - 10 => 'NET_SSH1_CMSG_REQUEST_PTY', - 12 => 'NET_SSH1_CMSG_EXEC_SHELL', - 13 => 'NET_SSH1_CMSG_EXEC_CMD', - 14 => 'NET_SSH1_SMSG_SUCCESS', - 15 => 'NET_SSH1_SMSG_FAILURE', - 16 => 'NET_SSH1_CMSG_STDIN_DATA', - 17 => 'NET_SSH1_SMSG_STDOUT_DATA', - 18 => 'NET_SSH1_SMSG_STDERR_DATA', - 19 => 'NET_SSH1_CMSG_EOF', - 20 => 'NET_SSH1_SMSG_EXITSTATUS', - 33 => 'NET_SSH1_CMSG_EXIT_CONFIRMATION' - ); - - $this->_define_array($this->protocol_flags); - - $this->host = $host; - $this->port = $port; - $this->connectionTimeout = $timeout; - $this->cipher = $cipher; - } - - /** - * Connect to an SSHv1 server - * - * @return bool - * @access private - */ - function _connect() - { - $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout); - if (!$this->fsock) { - user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr")); - return false; - } - - $this->server_identification = $init_line = fgets($this->fsock, 255); - - if (defined('NET_SSH1_LOGGING')) { - $this->_append_log('<-', $this->server_identification); - $this->_append_log('->', $this->identifier . "\r\n"); - } - - if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) { - user_error('Can only connect to SSH servers'); - return false; - } - if ($parts[1][0] != 1) { - user_error("Cannot connect to SSH $parts[1] servers"); - return false; - } - - fputs($this->fsock, $this->identifier."\r\n"); - - $response = $this->_get_binary_packet(); - if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) { - user_error('Expected SSH_SMSG_PUBLIC_KEY'); - return false; - } - - $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8); - - $this->_string_shift($response[self::RESPONSE_DATA], 4); - - if (strlen($response[self::RESPONSE_DATA]) < 2) { - return false; - } - $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); - $server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); - $this->server_key_public_exponent = $server_key_public_exponent; - - if (strlen($response[self::RESPONSE_DATA]) < 2) { - return false; - } - $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); - $server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); - - $this->server_key_public_modulus = $server_key_public_modulus; - - $this->_string_shift($response[self::RESPONSE_DATA], 4); - - if (strlen($response[self::RESPONSE_DATA]) < 2) { - return false; - } - $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); - $host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); - $this->host_key_public_exponent = $host_key_public_exponent; - - if (strlen($response[self::RESPONSE_DATA]) < 2) { - return false; - } - $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2)); - $host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256); - - $this->host_key_public_modulus = $host_key_public_modulus; - - $this->_string_shift($response[self::RESPONSE_DATA], 4); - - // get a list of the supported ciphers - if (strlen($response[self::RESPONSE_DATA]) < 4) { - return false; - } - extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4))); - - foreach ($this->supported_ciphers as $mask => $name) { - if (($supported_ciphers_mask & (1 << $mask)) == 0) { - unset($this->supported_ciphers[$mask]); - } - } - - // get a list of the supported authentications - if (strlen($response[self::RESPONSE_DATA]) < 4) { - return false; - } - extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4))); - foreach ($this->supported_authentications as $mask => $name) { - if (($supported_authentications_mask & (1 << $mask)) == 0) { - unset($this->supported_authentications[$mask]); - } - } - - $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie)); - - $session_key = Random::string(32); - $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0)); - - if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) { - $double_encrypted_session_key = $this->_rsa_crypt( - $double_encrypted_session_key, - array( - $server_key_public_exponent, - $server_key_public_modulus - ) - ); - $double_encrypted_session_key = $this->_rsa_crypt( - $double_encrypted_session_key, - array( - $host_key_public_exponent, - $host_key_public_modulus - ) - ); - } else { - $double_encrypted_session_key = $this->_rsa_crypt( - $double_encrypted_session_key, - array( - $host_key_public_exponent, - $host_key_public_modulus - ) - ); - $double_encrypted_session_key = $this->_rsa_crypt( - $double_encrypted_session_key, - array( - $server_key_public_exponent, - $server_key_public_modulus - ) - ); - } - - $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES; - $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_SESSION_KEY'); - return false; - } - - switch ($cipher) { - //case self::CIPHER_NONE: - // $this->crypto = new \phpseclib\Crypt\Null(); - // break; - case self::CIPHER_DES: - $this->crypto = new DES(); - $this->crypto->disablePadding(); - $this->crypto->enableContinuousBuffer(); - $this->crypto->setKey(substr($session_key, 0, 8)); - break; - case self::CIPHER_3DES: - $this->crypto = new TripleDES(TripleDES::MODE_3CBC); - $this->crypto->disablePadding(); - $this->crypto->enableContinuousBuffer(); - $this->crypto->setKey(substr($session_key, 0, 24)); - break; - //case self::CIPHER_RC4: - // $this->crypto = new RC4(); - // $this->crypto->enableContinuousBuffer(); - // $this->crypto->setKey(substr($session_key, 0, 16)); - // break; - } - - $response = $this->_get_binary_packet(); - - if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { - user_error('Expected SSH_SMSG_SUCCESS'); - return false; - } - - $this->bitmap = self::MASK_CONNECTED; - - return true; - } - - /** - * Login - * - * @param string $username - * @param string $password - * @return bool - * @access public - */ - function login($username, $password = '') - { - if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - $this->bitmap |= self::MASK_CONSTRUCTOR; - if (!$this->_connect()) { - return false; - } - } - - if (!($this->bitmap & self::MASK_CONNECTED)) { - return false; - } - - $data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_USER'); - return false; - } - - $response = $this->_get_binary_packet(); - - if ($response === true) { - return false; - } - if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) { - $this->bitmap |= self::MASK_LOGIN; - return true; - } elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) { - user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); - return false; - } - - $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_AUTH_PASSWORD'); - return false; - } - - // remove the username and password from the last logged packet - if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == self::LOG_COMPLEX) { - $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password'); - $this->message_log[count($this->message_log) - 1] = $data; - } - - $response = $this->_get_binary_packet(); - - if ($response === true) { - return false; - } - if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) { - $this->bitmap |= self::MASK_LOGIN; - return true; - } elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) { - return false; - } else { - user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); - return false; - } - } - - /** - * Set Timeout - * - * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. - * Setting $timeout to false or 0 will mean there is no timeout. - * - * @param mixed $timeout - */ - function setTimeout($timeout) - { - $this->timeout = $this->curTimeout = $timeout; - } - - /** - * Executes a command on a non-interactive shell, returns the output, and quits. - * - * An SSH1 server will close the connection after a command has been executed on a non-interactive shell. SSH2 - * servers don't, however, this isn't an SSH2 client. The way this works, on the server, is by initiating a - * shell with the -s option, as discussed in the following links: - * - * {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html} - * {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html} - * - * To execute further commands, a new \phpseclib\Net\SSH1 object will need to be created. - * - * Returns false on failure and the output, otherwise. - * - * @see self::interactiveRead() - * @see self::interactiveWrite() - * @param string $cmd - * @param bool $block - * @return mixed - * @access public - */ - function exec($cmd, $block = true) - { - if (!($this->bitmap & self::MASK_LOGIN)) { - user_error('Operation disallowed prior to login()'); - return false; - } - - $data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_EXEC_CMD'); - return false; - } - - if (!$block) { - return true; - } - - $output = ''; - $response = $this->_get_binary_packet(); - - if ($response !== false) { - do { - $output.= substr($response[self::RESPONSE_DATA], 4); - $response = $this->_get_binary_packet(); - } while (is_array($response) && $response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS); - } - - $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION); - - // i don't think it's really all that important if this packet gets sent or not. - $this->_send_binary_packet($data); - - fclose($this->fsock); - - // reset the execution bitmap - a new \phpseclib\Net\SSH1 object needs to be created. - $this->bitmap = 0; - - return $output; - } - - /** - * Creates an interactive shell - * - * @see self::interactiveRead() - * @see self::interactiveWrite() - * @return bool - * @access private - */ - function _initShell() - { - // connect using the sample parameters in protocol-1.5.txt. - // according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text - // terminal is a command line interpreter or shell". thus, opening a terminal session to run the shell. - $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_REQUEST_PTY'); - return false; - } - - $response = $this->_get_binary_packet(); - - if ($response === true) { - return false; - } - if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { - user_error('Expected SSH_SMSG_SUCCESS'); - return false; - } - - $data = pack('C', NET_SSH1_CMSG_EXEC_SHELL); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_EXEC_SHELL'); - return false; - } - - $this->bitmap |= self::MASK_SHELL; - - //stream_set_blocking($this->fsock, 0); - - return true; - } - - /** - * Inputs a command into an interactive shell. - * - * @see self::interactiveWrite() - * @param string $cmd - * @return bool - * @access public - */ - function write($cmd) - { - return $this->interactiveWrite($cmd); - } - - /** - * Returns the output of an interactive shell when there's a match for $expect - * - * $expect can take the form of a string literal or, if $mode == self::READ_REGEX, - * a regular expression. - * - * @see self::write() - * @param string $expect - * @param int $mode - * @return bool - * @access public - */ - function read($expect, $mode = self::READ_SIMPLE) - { - if (!($this->bitmap & self::MASK_LOGIN)) { - user_error('Operation disallowed prior to login()'); - return false; - } - - if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; - } - - $match = $expect; - while (true) { - if ($mode == self::READ_REGEX) { - preg_match($expect, $this->interactiveBuffer, $matches); - $match = isset($matches[0]) ? $matches[0] : ''; - } - $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; - if ($pos !== false) { - return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match)); - } - $response = $this->_get_binary_packet(); - - if ($response === true) { - return $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); - } - $this->interactiveBuffer.= substr($response[self::RESPONSE_DATA], 4); - } - } - - /** - * Inputs a command into an interactive shell. - * - * @see self::interactiveRead() - * @param string $cmd - * @return bool - * @access public - */ - function interactiveWrite($cmd) - { - if (!($this->bitmap & self::MASK_LOGIN)) { - user_error('Operation disallowed prior to login()'); - return false; - } - - if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; - } - - $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd); - - if (!$this->_send_binary_packet($data)) { - user_error('Error sending SSH_CMSG_STDIN'); - return false; - } - - return true; - } - - /** - * Returns the output of an interactive shell when no more output is available. - * - * Requires PHP 4.3.0 or later due to the use of the stream_select() function. If you see stuff like - * "^[[00m", you're seeing ANSI escape codes. According to - * {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT - * does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user, - * there's not going to be much recourse. - * - * @see self::interactiveRead() - * @return string - * @access public - */ - function interactiveRead() - { - if (!($this->bitmap & self::MASK_LOGIN)) { - user_error('Operation disallowed prior to login()'); - return false; - } - - if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; - } - - $read = array($this->fsock); - $write = $except = null; - if (stream_select($read, $write, $except, 0)) { - $response = $this->_get_binary_packet(); - return substr($response[self::RESPONSE_DATA], 4); - } else { - return ''; - } - } - - /** - * Disconnect - * - * @access public - */ - function disconnect() - { - $this->_disconnect(); - } - - /** - * Destructor. - * - * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call - * disconnect(). - * - * @access public - */ - function __destruct() - { - $this->_disconnect(); - } - - /** - * Disconnect - * - * @param string $msg - * @access private - */ - function _disconnect($msg = 'Client Quit') - { - if ($this->bitmap) { - $data = pack('C', NET_SSH1_CMSG_EOF); - $this->_send_binary_packet($data); - /* - $response = $this->_get_binary_packet(); - if ($response === true) { - $response = array(self::RESPONSE_TYPE => -1); - } - switch ($response[self::RESPONSE_TYPE]) { - case NET_SSH1_SMSG_EXITSTATUS: - $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION); - break; - default: - $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg); - } - */ - $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg); - - $this->_send_binary_packet($data); - fclose($this->fsock); - $this->bitmap = 0; - } - } - - /** - * Gets Binary Packets - * - * See 'The Binary Packet Protocol' of protocol-1.5.txt for more info. - * - * Also, this function could be improved upon by adding detection for the following exploit: - * http://www.securiteam.com/securitynews/5LP042K3FY.html - * - * @see self::_send_binary_packet() - * @return array - * @access private - */ - function _get_binary_packet() - { - if (feof($this->fsock)) { - //user_error('connection closed prematurely'); - return false; - } - - if ($this->curTimeout) { - $read = array($this->fsock); - $write = $except = null; - - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 - $sec = floor($this->curTimeout); - $usec = 1000000 * ($this->curTimeout - $sec); - // on windows this returns a "Warning: Invalid CRT parameters detected" error - if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { - //$this->_disconnect('Timeout'); - return true; - } - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; - $this->curTimeout-= $elapsed; - } - - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 - $data = fread($this->fsock, 4); - if (strlen($data) < 4) { - return false; - } - $temp = unpack('Nlength', $data); - - $padding_length = 8 - ($temp['length'] & 7); - $length = $temp['length'] + $padding_length; - $raw = ''; - - while ($length > 0) { - $temp = fread($this->fsock, $length); - if (strlen($temp) != $length) { - return false; - } - $raw.= $temp; - $length-= strlen($temp); - } - $stop = strtok(microtime(), ' ') + strtok(''); - - if (strlen($raw) && $this->crypto !== false) { - $raw = $this->crypto->decrypt($raw); - } - - $padding = substr($raw, 0, $padding_length); - $type = $raw[$padding_length]; - $data = substr($raw, $padding_length + 1, -4); - - if (strlen($raw) < 4) { - return false; - } - $temp = unpack('Ncrc', substr($raw, -4)); - - //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) { - // user_error('Bad CRC in packet from server'); - // return false; - //} - - $type = ord($type); - - if (defined('NET_SSH1_LOGGING')) { - $temp = isset($this->protocol_flags[$type]) ? $this->protocol_flags[$type] : 'UNKNOWN'; - $temp = '<- ' . $temp . - ' (' . round($stop - $start, 4) . 's)'; - $this->_append_log($temp, $data); - } - - return array( - self::RESPONSE_TYPE => $type, - self::RESPONSE_DATA => $data - ); - } - - /** - * Sends Binary Packets - * - * Returns true on success, false on failure. - * - * @see self::_get_binary_packet() - * @param string $data - * @return bool - * @access private - */ - function _send_binary_packet($data) - { - if (feof($this->fsock)) { - //user_error('connection closed prematurely'); - return false; - } - - $length = strlen($data) + 4; - - $padding = Random::string(8 - ($length & 7)); - - $orig = $data; - $data = $padding . $data; - $data.= pack('N', $this->_crc($data)); - - if ($this->crypto !== false) { - $data = $this->crypto->encrypt($data); - } - - $packet = pack('Na*', $length, $data); - - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 - $result = strlen($packet) == fputs($this->fsock, $packet); - $stop = strtok(microtime(), ' ') + strtok(''); - - if (defined('NET_SSH1_LOGGING')) { - $temp = isset($this->protocol_flags[ord($orig[0])]) ? $this->protocol_flags[ord($orig[0])] : 'UNKNOWN'; - $temp = '-> ' . $temp . - ' (' . round($stop - $start, 4) . 's)'; - $this->_append_log($temp, $orig); - } - - return $result; - } - - /** - * Cyclic Redundancy Check (CRC) - * - * PHP's crc32 function is implemented slightly differently than the one that SSH v1 uses, so - * we've reimplemented it. A more detailed discussion of the differences can be found after - * $crc_lookup_table's initialization. - * - * @see self::_get_binary_packet() - * @see self::_send_binary_packet() - * @param string $data - * @return int - * @access private - */ - function _crc($data) - { - static $crc_lookup_table = array( - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D - ); - - // For this function to yield the same output as PHP's crc32 function, $crc would have to be - // set to 0xFFFFFFFF, initially - not 0x00000000 as it currently is. - $crc = 0x00000000; - $length = strlen($data); - - for ($i=0; $i<$length; $i++) { - // We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all - // be zero. PHP, unfortunately, doesn't always do this. 0x80000000 >> 8, as an example, - // yields 0xFF800000 - not 0x00800000. The following link elaborates: - // http://www.php.net/manual/en/language.operators.bitwise.php#57281 - $crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc_lookup_table[($crc & 0xFF) ^ ord($data[$i])]; - } - - // In addition to having to set $crc to 0xFFFFFFFF, initially, the return value must be XOR'd with - // 0xFFFFFFFF for this function to return the same thing that PHP's crc32 function would. - return $crc; - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } - - /** - * RSA Encrypt - * - * Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e - * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that - * calls this call modexp, instead, but I think this makes things clearer, maybe... - * - * @see self::__construct() - * @param BigInteger $m - * @param array $key - * @return BigInteger - * @access private - */ - function _rsa_crypt($m, $key) - { - /* - $rsa = new RSA(); - $rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW); - $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); - return $rsa->encrypt($m); - */ - - // To quote from protocol-1.5.txt: - // The most significant byte (which is only partial as the value must be - // less than the public modulus, which is never a power of two) is zero. - // - // The next byte contains the value 2 (which stands for public-key - // encrypted data in the PKCS standard [PKCS#1]). Then, there are non- - // zero random bytes to fill any unused space, a zero byte, and the data - // to be encrypted in the least significant bytes, the last byte of the - // data in the least significant byte. - - // Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation", - // under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL: - // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf - $modulus = $key[1]->toBytes(); - $length = strlen($modulus) - strlen($m) - 3; - $random = ''; - while (strlen($random) != $length) { - $block = Random::string($length - strlen($random)); - $block = str_replace("\x00", '', $block); - $random.= $block; - } - $temp = chr(0) . chr(2) . $random . chr(0) . $m; - - $m = new BigInteger($temp, 256); - $m = $m->modPow($key[0], $key[1]); - - return $m->toBytes(); - } - - /** - * Define Array - * - * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of - * named constants from it, using the value as the name of the constant and the index as the value of the constant. - * If any of the constants that would be defined already exists, none of the constants will be defined. - * - * @access private - */ - function _define_array() - { - $args = func_get_args(); - foreach ($args as $arg) { - foreach ($arg as $key => $value) { - if (!defined($value)) { - define($value, $key); - } else { - break 2; - } - } - } - } - - /** - * Returns a log of the packets that have been sent and received. - * - * Returns a string if NET_SSH1_LOGGING == self::LOG_COMPLEX, an array if NET_SSH1_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING') - * - * @access public - * @return array|false|string - */ - function getLog() - { - if (!defined('NET_SSH1_LOGGING')) { - return false; - } - - switch (NET_SSH1_LOGGING) { - case self::LOG_SIMPLE: - return $this->message_number_log; - break; - case self::LOG_COMPLEX: - return $this->_format_log($this->message_log, $this->protocol_flags_log); - break; - default: - return false; - } - } - - /** - * Formats a log for printing - * - * @param array $message_log - * @param array $message_number_log - * @access private - * @return string - */ - function _format_log($message_log, $message_number_log) - { - $output = ''; - for ($i = 0; $i < count($message_log); $i++) { - $output.= $message_number_log[$i] . "\r\n"; - $current_log = $message_log[$i]; - $j = 0; - do { - if (strlen($current_log)) { - $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; - } - $fragment = $this->_string_shift($current_log, $this->log_short_width); - $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary)); - // replace non ASCII printable characters with dots - // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters - // also replace < with a . since < messes up the output on web browsers - $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); - $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; - $j++; - } while (strlen($current_log)); - $output.= "\r\n"; - } - - return $output; - } - - /** - * Helper function for _format_log - * - * For use with preg_replace_callback() - * - * @param array $matches - * @access private - * @return string - */ - function _format_log_helper($matches) - { - return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); - } - - /** - * Return the server key public exponent - * - * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, - * the raw bytes. This behavior is similar to PHP's md5() function. - * - * @param bool $raw_output - * @return string - * @access public - */ - function getServerKeyPublicExponent($raw_output = false) - { - return $raw_output ? $this->server_key_public_exponent->toBytes() : $this->server_key_public_exponent->toString(); - } - - /** - * Return the server key public modulus - * - * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, - * the raw bytes. This behavior is similar to PHP's md5() function. - * - * @param bool $raw_output - * @return string - * @access public - */ - function getServerKeyPublicModulus($raw_output = false) - { - return $raw_output ? $this->server_key_public_modulus->toBytes() : $this->server_key_public_modulus->toString(); - } - - /** - * Return the host key public exponent - * - * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, - * the raw bytes. This behavior is similar to PHP's md5() function. - * - * @param bool $raw_output - * @return string - * @access public - */ - function getHostKeyPublicExponent($raw_output = false) - { - return $raw_output ? $this->host_key_public_exponent->toBytes() : $this->host_key_public_exponent->toString(); - } - - /** - * Return the host key public modulus - * - * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead, - * the raw bytes. This behavior is similar to PHP's md5() function. - * - * @param bool $raw_output - * @return string - * @access public - */ - function getHostKeyPublicModulus($raw_output = false) - { - return $raw_output ? $this->host_key_public_modulus->toBytes() : $this->host_key_public_modulus->toString(); - } - - /** - * Return a list of ciphers supported by SSH1 server. - * - * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output - * is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll - * get array(self::CIPHER_3DES). - * - * @param bool $raw_output - * @return array - * @access public - */ - function getSupportedCiphers($raw_output = false) - { - return $raw_output ? array_keys($this->supported_ciphers) : array_values($this->supported_ciphers); - } - - /** - * Return a list of authentications supported by SSH1 server. - * - * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output - * is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll - * get array(self::AUTH_PASSWORD). - * - * @param bool $raw_output - * @return array - * @access public - */ - function getSupportedAuthentications($raw_output = false) - { - return $raw_output ? array_keys($this->supported_authentications) : array_values($this->supported_authentications); - } - - /** - * Return the server identification. - * - * @return string - * @access public - */ - function getServerIdentification() - { - return rtrim($this->server_identification); - } - - /** - * Logs data packets - * - * Makes sure that only the last 1MB worth of packets will be logged - * - * @param int $protocol_flags - * @param string $message - * @access private - */ - function _append_log($protocol_flags, $message) - { - switch (NET_SSH1_LOGGING) { - // useful for benchmarks - case self::LOG_SIMPLE: - $this->protocol_flags_log[] = $protocol_flags; - break; - // the most useful log for SSH1 - case self::LOG_COMPLEX: - $this->protocol_flags_log[] = $protocol_flags; - $this->_string_shift($message); - $this->log_size+= strlen($message); - $this->message_log[] = $message; - while ($this->log_size > self::LOG_MAX_SIZE) { - $this->log_size-= strlen(array_shift($this->message_log)); - array_shift($this->protocol_flags_log); - } - break; - // dump the output out realtime; packets may be interspersed with non packets, - // passwords won't be filtered out and select other packets may not be correctly - // identified - case self::LOG_REALTIME: - echo "
\r\n" . $this->_format_log(array($message), array($protocol_flags)) . "\r\n
\r\n"; - @flush(); - @ob_flush(); - break; - // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE - // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. - // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily - // at the beginning of the file - case self::LOG_REALTIME_FILE: - if (!isset($this->realtime_log_file)) { - // PHP doesn't seem to like using constants in fopen() - $filename = self::LOG_REALTIME_FILE; - $fp = fopen($filename, 'w'); - $this->realtime_log_file = $fp; - } - if (!is_resource($this->realtime_log_file)) { - break; - } - $entry = $this->_format_log(array($message), array($protocol_flags)); - if ($this->realtime_log_wrap) { - $temp = "<<< START >>>\r\n"; - $entry.= $temp; - fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp)); - } - $this->realtime_log_size+= strlen($entry); - if ($this->realtime_log_size > self::LOG_MAX_SIZE) { - fseek($this->realtime_log_file, 0); - $this->realtime_log_size = strlen($entry); - $this->realtime_log_wrap = true; - } - fputs($this->realtime_log_file, $entry); - } - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php deleted file mode 100644 index 3065dd423..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +++ /dev/null @@ -1,5387 +0,0 @@ - - * login('username', 'password')) { - * exit('Login Failed'); - * } - * - * echo $ssh->exec('pwd'); - * echo $ssh->exec('ls -la'); - * ?> - * - * - * - * setPassword('whatever'); - * $key->loadKey(file_get_contents('privatekey')); - * - * $ssh = new \phpseclib\Net\SSH2('www.domain.tld'); - * if (!$ssh->login('username', $key)) { - * exit('Login Failed'); - * } - * - * echo $ssh->read('username@username:~$'); - * $ssh->write("ls -la\n"); - * echo $ssh->read('username@username:~$'); - * ?> - * - * - * @category Net - * @package SSH2 - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Net; - -use phpseclib\Crypt\Base; -use phpseclib\Crypt\Blowfish; -use phpseclib\Crypt\Hash; -use phpseclib\Crypt\Random; -use phpseclib\Crypt\RC4; -use phpseclib\Crypt\Rijndael; -use phpseclib\Crypt\RSA; -use phpseclib\Crypt\TripleDES; -use phpseclib\Crypt\Twofish; -use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. -use phpseclib\System\SSH\Agent; - -/**#@+ - * @access private - */ -/** - * No compression - */ -define('NET_SSH2_COMPRESSION_NONE', 1); -/** - * zlib compression - */ -define('NET_SSH2_COMPRESSION_ZLIB', 2); -/** - * zlib@openssh.com - */ -define('NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH', 3); -/**#@-*/ - -/** - * Pure-PHP implementation of SSHv2. - * - * @package SSH2 - * @author Jim Wigginton - * @access public - */ -class SSH2 -{ - /**#@+ - * Execution Bitmap Masks - * - * @see \phpseclib\Net\SSH2::bitmap - * @access private - */ - const MASK_CONSTRUCTOR = 0x00000001; - const MASK_CONNECTED = 0x00000002; - const MASK_LOGIN_REQ = 0x00000004; - const MASK_LOGIN = 0x00000008; - const MASK_SHELL = 0x00000010; - const MASK_WINDOW_ADJUST = 0x00000020; - /**#@-*/ - - /**#@+ - * Channel constants - * - * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer - * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with - * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a - * recepient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel - * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snipet: - * The 'recipient channel' is the channel number given in the original - * open request, and 'sender channel' is the channel number allocated by - * the other side. - * - * @see \phpseclib\Net\SSH2::_send_channel_packet() - * @see \phpseclib\Net\SSH2::_get_channel_packet() - * @access private - */ - const CHANNEL_EXEC = 1; // PuTTy uses 0x100 - const CHANNEL_SHELL = 2; - const CHANNEL_SUBSYSTEM = 3; - const CHANNEL_AGENT_FORWARD = 4; - const CHANNEL_KEEP_ALIVE = 5; - /**#@-*/ - - /**#@+ - * @access public - * @see \phpseclib\Net\SSH2::getLog() - */ - /** - * Returns the message numbers - */ - const LOG_SIMPLE = 1; - /** - * Returns the message content - */ - const LOG_COMPLEX = 2; - /** - * Outputs the content real-time - */ - const LOG_REALTIME = 3; - /** - * Dumps the content real-time to a file - */ - const LOG_REALTIME_FILE = 4; - /** - * Make sure that the log never gets larger than this - */ - const LOG_MAX_SIZE = 1048576; // 1024 * 1024 - /**#@-*/ - - /**#@+ - * @access public - * @see \phpseclib\Net\SSH2::read() - */ - /** - * Returns when a string matching $expect exactly is found - */ - const READ_SIMPLE = 1; - /** - * Returns when a string matching the regular expression $expect is found - */ - const READ_REGEX = 2; - /** - * Returns whenever a data packet is received. - * - * Some data packets may only contain a single character so it may be necessary - * to call read() multiple times when using this option - */ - const READ_NEXT = 3; - /**#@-*/ - - /** - * The SSH identifier - * - * @var string - * @access private - */ - var $identifier; - - /** - * The Socket Object - * - * @var object - * @access private - */ - var $fsock; - - /** - * Execution Bitmap - * - * The bits that are set represent functions that have been called already. This is used to determine - * if a requisite function has been successfully executed. If not, an error should be thrown. - * - * @var int - * @access private - */ - var $bitmap = 0; - - /** - * Error information - * - * @see self::getErrors() - * @see self::getLastError() - * @var string - * @access private - */ - var $errors = array(); - - /** - * Server Identifier - * - * @see self::getServerIdentification() - * @var array|false - * @access private - */ - var $server_identifier = false; - - /** - * Key Exchange Algorithms - * - * @see self::getKexAlgorithims() - * @var array|false - * @access private - */ - var $kex_algorithms = false; - - /** - * Key Exchange Algorithm - * - * @see self::getMethodsNegotiated() - * @var string|false - * @access private - */ - var $kex_algorithm = false; - - /** - * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods - * - * @see self::_key_exchange() - * @var int - * @access private - */ - var $kex_dh_group_size_min = 1536; - - /** - * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods - * - * @see self::_key_exchange() - * @var int - * @access private - */ - var $kex_dh_group_size_preferred = 2048; - - /** - * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods - * - * @see self::_key_exchange() - * @var int - * @access private - */ - var $kex_dh_group_size_max = 4096; - - /** - * Server Host Key Algorithms - * - * @see self::getServerHostKeyAlgorithms() - * @var array|false - * @access private - */ - var $server_host_key_algorithms = false; - - /** - * Encryption Algorithms: Client to Server - * - * @see self::getEncryptionAlgorithmsClient2Server() - * @var array|false - * @access private - */ - var $encryption_algorithms_client_to_server = false; - - /** - * Encryption Algorithms: Server to Client - * - * @see self::getEncryptionAlgorithmsServer2Client() - * @var array|false - * @access private - */ - var $encryption_algorithms_server_to_client = false; - - /** - * MAC Algorithms: Client to Server - * - * @see self::getMACAlgorithmsClient2Server() - * @var array|false - * @access private - */ - var $mac_algorithms_client_to_server = false; - - /** - * MAC Algorithms: Server to Client - * - * @see self::getMACAlgorithmsServer2Client() - * @var array|false - * @access private - */ - var $mac_algorithms_server_to_client = false; - - /** - * Compression Algorithms: Client to Server - * - * @see self::getCompressionAlgorithmsClient2Server() - * @var array|false - * @access private - */ - var $compression_algorithms_client_to_server = false; - - /** - * Compression Algorithms: Server to Client - * - * @see self::getCompressionAlgorithmsServer2Client() - * @var array|false - * @access private - */ - var $compression_algorithms_server_to_client = false; - - /** - * Languages: Server to Client - * - * @see self::getLanguagesServer2Client() - * @var array|false - * @access private - */ - var $languages_server_to_client = false; - - /** - * Languages: Client to Server - * - * @see self::getLanguagesClient2Server() - * @var array|false - * @access private - */ - var $languages_client_to_server = false; - - /** - * Preferred Algorithms - * - * @see self::setPreferredAlgorithms() - * @var array - * @access private - */ - var $preferred = array(); - - /** - * Block Size for Server to Client Encryption - * - * "Note that the length of the concatenation of 'packet_length', - * 'padding_length', 'payload', and 'random padding' MUST be a multiple - * of the cipher block size or 8, whichever is larger. This constraint - * MUST be enforced, even when using stream ciphers." - * - * -- http://tools.ietf.org/html/rfc4253#section-6 - * - * @see self::__construct() - * @see self::_send_binary_packet() - * @var int - * @access private - */ - var $encrypt_block_size = 8; - - /** - * Block Size for Client to Server Encryption - * - * @see self::__construct() - * @see self::_get_binary_packet() - * @var int - * @access private - */ - var $decrypt_block_size = 8; - - /** - * Server to Client Encryption Object - * - * @see self::_get_binary_packet() - * @var object - * @access private - */ - var $decrypt = false; - - /** - * Client to Server Encryption Object - * - * @see self::_send_binary_packet() - * @var object - * @access private - */ - var $encrypt = false; - - /** - * Client to Server HMAC Object - * - * @see self::_send_binary_packet() - * @var object - * @access private - */ - var $hmac_create = false; - - /** - * Server to Client HMAC Object - * - * @see self::_get_binary_packet() - * @var object - * @access private - */ - var $hmac_check = false; - - /** - * Size of server to client HMAC - * - * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read. - * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is - * append it. - * - * @see self::_get_binary_packet() - * @var int - * @access private - */ - var $hmac_size = false; - - /** - * Server Public Host Key - * - * @see self::getServerPublicHostKey() - * @var string - * @access private - */ - var $server_public_host_key; - - /** - * Session identifier - * - * "The exchange hash H from the first key exchange is additionally - * used as the session identifier, which is a unique identifier for - * this connection." - * - * -- http://tools.ietf.org/html/rfc4253#section-7.2 - * - * @see self::_key_exchange() - * @var string - * @access private - */ - var $session_id = false; - - /** - * Exchange hash - * - * The current exchange hash - * - * @see self::_key_exchange() - * @var string - * @access private - */ - var $exchange_hash = false; - - /** - * Message Numbers - * - * @see self::__construct() - * @var array - * @access private - */ - var $message_numbers = array(); - - /** - * Disconnection Message 'reason codes' defined in RFC4253 - * - * @see self::__construct() - * @var array - * @access private - */ - var $disconnect_reasons = array(); - - /** - * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 - * - * @see self::__construct() - * @var array - * @access private - */ - var $channel_open_failure_reasons = array(); - - /** - * Terminal Modes - * - * @link http://tools.ietf.org/html/rfc4254#section-8 - * @see self::__construct() - * @var array - * @access private - */ - var $terminal_modes = array(); - - /** - * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes - * - * @link http://tools.ietf.org/html/rfc4254#section-5.2 - * @see self::__construct() - * @var array - * @access private - */ - var $channel_extended_data_type_codes = array(); - - /** - * Send Sequence Number - * - * See 'Section 6.4. Data Integrity' of rfc4253 for more info. - * - * @see self::_send_binary_packet() - * @var int - * @access private - */ - var $send_seq_no = 0; - - /** - * Get Sequence Number - * - * See 'Section 6.4. Data Integrity' of rfc4253 for more info. - * - * @see self::_get_binary_packet() - * @var int - * @access private - */ - var $get_seq_no = 0; - - /** - * Server Channels - * - * Maps client channels to server channels - * - * @see self::_get_channel_packet() - * @see self::exec() - * @var array - * @access private - */ - var $server_channels = array(); - - /** - * Channel Buffers - * - * If a client requests a packet from one channel but receives two packets from another those packets should - * be placed in a buffer - * - * @see self::_get_channel_packet() - * @see self::exec() - * @var array - * @access private - */ - var $channel_buffers = array(); - - /** - * Channel Status - * - * Contains the type of the last sent message - * - * @see self::_get_channel_packet() - * @var array - * @access private - */ - var $channel_status = array(); - - /** - * Packet Size - * - * Maximum packet size indexed by channel - * - * @see self::_send_channel_packet() - * @var array - * @access private - */ - var $packet_size_client_to_server = array(); - - /** - * Message Number Log - * - * @see self::getLog() - * @var array - * @access private - */ - var $message_number_log = array(); - - /** - * Message Log - * - * @see self::getLog() - * @var array - * @access private - */ - var $message_log = array(); - - /** - * The Window Size - * - * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) - * - * @var int - * @see self::_send_channel_packet() - * @see self::exec() - * @access private - */ - var $window_size = 0x7FFFFFFF; - - /** - * What we resize the window to - * - * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes. - * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so - * we'll just do what PuTTY does - * - * @var int - * @see self::_send_channel_packet() - * @see self::exec() - * @access private - */ - var $window_resize = 0x40000000; - - /** - * Window size, server to client - * - * Window size indexed by channel - * - * @see self::_send_channel_packet() - * @var array - * @access private - */ - var $window_size_server_to_client = array(); - - /** - * Window size, client to server - * - * Window size indexed by channel - * - * @see self::_get_channel_packet() - * @var array - * @access private - */ - var $window_size_client_to_server = array(); - - /** - * Server signature - * - * Verified against $this->session_id - * - * @see self::getServerPublicHostKey() - * @var string - * @access private - */ - var $signature = ''; - - /** - * Server signature format - * - * ssh-rsa or ssh-dss. - * - * @see self::getServerPublicHostKey() - * @var string - * @access private - */ - var $signature_format = ''; - - /** - * Interactive Buffer - * - * @see self::read() - * @var array - * @access private - */ - var $interactiveBuffer = ''; - - /** - * Current log size - * - * Should never exceed self::LOG_MAX_SIZE - * - * @see self::_send_binary_packet() - * @see self::_get_binary_packet() - * @var int - * @access private - */ - var $log_size; - - /** - * Timeout - * - * @see self::setTimeout() - * @access private - */ - var $timeout; - - /** - * Current Timeout - * - * @see self::_get_channel_packet() - * @access private - */ - var $curTimeout; - - /** - * Keep Alive Interval - * - * @see self::setKeepAlive() - * @access private - */ - var $keepAlive; - - /** - * Real-time log file pointer - * - * @see self::_append_log() - * @var resource - * @access private - */ - var $realtime_log_file; - - /** - * Real-time log file size - * - * @see self::_append_log() - * @var int - * @access private - */ - var $realtime_log_size; - - /** - * Has the signature been validated? - * - * @see self::getServerPublicHostKey() - * @var bool - * @access private - */ - var $signature_validated = false; - - /** - * Real-time log file wrap boolean - * - * @see self::_append_log() - * @access private - */ - var $realtime_log_wrap; - - /** - * Flag to suppress stderr from output - * - * @see self::enableQuietMode() - * @access private - */ - var $quiet_mode = false; - - /** - * Time of first network activity - * - * @var int - * @access private - */ - var $last_packet; - - /** - * Exit status returned from ssh if any - * - * @var int - * @access private - */ - var $exit_status; - - /** - * Flag to request a PTY when using exec() - * - * @var bool - * @see self::enablePTY() - * @access private - */ - var $request_pty = false; - - /** - * Flag set while exec() is running when using enablePTY() - * - * @var bool - * @access private - */ - var $in_request_pty_exec = false; - - /** - * Flag set after startSubsystem() is called - * - * @var bool - * @access private - */ - var $in_subsystem; - - /** - * Contents of stdError - * - * @var string - * @access private - */ - var $stdErrorLog; - - /** - * The Last Interactive Response - * - * @see self::_keyboard_interactive_process() - * @var string - * @access private - */ - var $last_interactive_response = ''; - - /** - * Keyboard Interactive Request / Responses - * - * @see self::_keyboard_interactive_process() - * @var array - * @access private - */ - var $keyboard_requests_responses = array(); - - /** - * Banner Message - * - * Quoting from the RFC, "in some jurisdictions, sending a warning message before - * authentication may be relevant for getting legal protection." - * - * @see self::_filter() - * @see self::getBannerMessage() - * @var string - * @access private - */ - var $banner_message = ''; - - /** - * Did read() timeout or return normally? - * - * @see self::isTimeout() - * @var bool - * @access private - */ - var $is_timeout = false; - - /** - * Log Boundary - * - * @see self::_format_log() - * @var string - * @access private - */ - var $log_boundary = ':'; - - /** - * Log Long Width - * - * @see self::_format_log() - * @var int - * @access private - */ - var $log_long_width = 65; - - /** - * Log Short Width - * - * @see self::_format_log() - * @var int - * @access private - */ - var $log_short_width = 16; - - /** - * Hostname - * - * @see self::__construct() - * @see self::_connect() - * @var string - * @access private - */ - var $host; - - /** - * Port Number - * - * @see self::__construct() - * @see self::_connect() - * @var int - * @access private - */ - var $port; - - /** - * Number of columns for terminal window size - * - * @see self::getWindowColumns() - * @see self::setWindowColumns() - * @see self::setWindowSize() - * @var int - * @access private - */ - var $windowColumns = 80; - - /** - * Number of columns for terminal window size - * - * @see self::getWindowRows() - * @see self::setWindowRows() - * @see self::setWindowSize() - * @var int - * @access private - */ - var $windowRows = 24; - - /** - * Crypto Engine - * - * @see self::setCryptoEngine() - * @see self::_key_exchange() - * @var int - * @access private - */ - var $crypto_engine = false; - - /** - * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario - * - * @var System_SSH_Agent - * @access private - */ - var $agent; - - /** - * Send the identification string first? - * - * @var bool - * @access private - */ - var $send_id_string_first = true; - - /** - * Send the key exchange initiation packet first? - * - * @var bool - * @access private - */ - var $send_kex_first = true; - - /** - * Some versions of OpenSSH incorrectly calculate the key size - * - * @var bool - * @access private - */ - var $bad_key_size_fix = false; - - /** - * Should we try to re-connect to re-establish keys? - * - * @var bool - * @access private - */ - var $retry_connect = false; - - /** - * Binary Packet Buffer - * - * @var string|false - * @access private - */ - var $binary_packet_buffer = false; - - /** - * Preferred Signature Format - * - * @var string|false - * @access private - */ - var $preferred_signature_format = false; - - /** - * Authentication Credentials - * - * @var array - * @access private - */ - var $auth = array(); - - /** - * The authentication methods that may productively continue authentication. - * - * @see https://tools.ietf.org/html/rfc4252#section-5.1 - * @var array|null - * @access private - */ - var $auth_methods_to_continue = null; - - /** - * Compression method - * - * @var int - * @access private - */ - var $compress = NET_SSH2_COMPRESSION_NONE; - - /** - * Decompression method - * - * @var resource|object - * @access private - */ - var $decompress = NET_SSH2_COMPRESSION_NONE; - - /** - * Compression context - * - * @var int - * @access private - */ - var $compress_context; - - /** - * Decompression context - * - * @var resource|object - * @access private - */ - var $decompress_context; - - /** - * Regenerate Compression Context - * - * @var bool - * @access private - */ - var $regenerate_compression_context = false; - - /** - * Regenerate Decompression Context - * - * @var bool - * @access private - */ - var $regenerate_decompression_context = false; - - /** - * Smart multi-factor authentication flag - * - * @var bool - * @access private - */ - var $smartMFA = true; - - /** - * Default Constructor. - * - * $host can either be a string, representing the host, or a stream resource. - * - * @param mixed $host - * @param int $port - * @param int $timeout - * @see self::login() - * @return \phpseclib\Net\SSH2 - * @access public - */ - function __construct($host, $port = 22, $timeout = 10) - { - $this->message_numbers = array( - 1 => 'NET_SSH2_MSG_DISCONNECT', - 2 => 'NET_SSH2_MSG_IGNORE', - 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', - 4 => 'NET_SSH2_MSG_DEBUG', - 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', - 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', - 20 => 'NET_SSH2_MSG_KEXINIT', - 21 => 'NET_SSH2_MSG_NEWKEYS', - 30 => 'NET_SSH2_MSG_KEXDH_INIT', - 31 => 'NET_SSH2_MSG_KEXDH_REPLY', - 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', - 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', - 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', - 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', - - 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', - 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', - 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', - 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', - 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', - 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', - 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', - 94 => 'NET_SSH2_MSG_CHANNEL_DATA', - 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', - 96 => 'NET_SSH2_MSG_CHANNEL_EOF', - 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', - 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', - 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', - 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' - ); - $this->disconnect_reasons = array( - 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', - 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', - 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', - 4 => 'NET_SSH2_DISCONNECT_RESERVED', - 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', - 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', - 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', - 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', - 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', - 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', - 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', - 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', - 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', - 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', - 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' - ); - $this->channel_open_failure_reasons = array( - 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' - ); - $this->terminal_modes = array( - 0 => 'NET_SSH2_TTY_OP_END' - ); - $this->channel_extended_data_type_codes = array( - 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' - ); - - $this->_define_array( - $this->message_numbers, - $this->disconnect_reasons, - $this->channel_open_failure_reasons, - $this->terminal_modes, - $this->channel_extended_data_type_codes, - array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'), - array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'), - array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', - 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'), - // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} - array(30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', - 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', - 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', - 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', - 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'), - // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) - array(30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', - 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY') - ); - - if (is_resource($host)) { - $this->fsock = $host; - return; - } - - if (is_string($host)) { - $this->host = $host; - $this->port = $port; - $this->timeout = $timeout; - } - } - - /** - * Set Crypto Engine Mode - * - * Possible $engine values: - * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT - * - * @param int $engine - * @access public - */ - function setCryptoEngine($engine) - { - $this->crypto_engine = $engine; - } - - /** - * Send Identification String First - * - * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, - * both sides MUST send an identification string". It does not say which side sends it first. In - * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - * @access public - */ - function sendIdentificationStringFirst() - { - $this->send_id_string_first = true; - } - - /** - * Send Identification String Last - * - * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, - * both sides MUST send an identification string". It does not say which side sends it first. In - * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - * @access public - */ - function sendIdentificationStringLast() - { - $this->send_id_string_first = false; - } - - /** - * Send SSH_MSG_KEXINIT First - * - * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending - * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory - * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - * @access public - */ - function sendKEXINITFirst() - { - $this->send_kex_first = true; - } - - /** - * Send SSH_MSG_KEXINIT Last - * - * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending - * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory - * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - * @access public - */ - function sendKEXINITLast() - { - $this->send_kex_first = false; - } - - /** - * Connect to an SSHv2 server - * - * @return bool - * @access private - */ - function _connect() - { - if ($this->bitmap & self::MASK_CONSTRUCTOR) { - return false; - } - - $this->bitmap |= self::MASK_CONSTRUCTOR; - - $this->curTimeout = $this->timeout; - - $this->last_packet = microtime(true); - - if (!is_resource($this->fsock)) { - $start = microtime(true); - // with stream_select a timeout of 0 means that no timeout takes place; - // with fsockopen a timeout of 0 means that you instantly timeout - // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0 - $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); - if (!$this->fsock) { - $host = $this->host . ':' . $this->port; - user_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); - return false; - } - $elapsed = microtime(true) - $start; - - if ($this->curTimeout) { - $this->curTimeout-= $elapsed; - if ($this->curTimeout < 0) { - $this->is_timeout = true; - return false; - } - } - } - - $this->identifier = $this->_generate_identifier(); - - if ($this->send_id_string_first) { - fputs($this->fsock, $this->identifier . "\r\n"); - } - - /* According to the SSH2 specs, - - "The server MAY send other lines of data before sending the version - string. Each line SHOULD be terminated by a Carriage Return and Line - Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded - in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients - MUST be able to process such lines." */ - $data = ''; - while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) { - $line = ''; - while (true) { - if ($this->curTimeout) { - if ($this->curTimeout < 0) { - $this->is_timeout = true; - return false; - } - $read = array($this->fsock); - $write = $except = null; - $start = microtime(true); - $sec = floor($this->curTimeout); - $usec = 1000000 * ($this->curTimeout - $sec); - // on windows this returns a "Warning: Invalid CRT parameters detected" error - // the !count() is done as a workaround for - if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { - $this->is_timeout = true; - return false; - } - $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; - } - - $temp = stream_get_line($this->fsock, 255, "\n"); - if (strlen($temp) == 255) { - continue; - } - if ($temp === false) { - return false; - } - - $line.= "$temp\n"; - - // quoting RFC4253, "Implementers who wish to maintain - // compatibility with older, undocumented versions of this protocol may - // want to process the identification string without expecting the - // presence of the carriage return character for reasons described in - // Section 5 of this document." - - //if (substr($line, -2) == "\r\n") { - // break; - //} - - break; - } - - $data.= $line; - } - - if (feof($this->fsock)) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - $extra = $matches[1]; - - if (defined('NET_SSH2_LOGGING')) { - $this->_append_log('<-', $matches[0]); - $this->_append_log('->', $this->identifier . "\r\n"); - } - - $this->server_identifier = trim($temp, "\r\n"); - if (strlen($extra)) { - $this->errors[] = $data; - } - - if (version_compare($matches[3], '1.99', '<')) { - user_error("Cannot connect to SSH $matches[3] servers"); - return false; - } - - if (!$this->send_id_string_first) { - fputs($this->fsock, $this->identifier . "\r\n"); - } - - if (!$this->send_kex_first) { - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) { - user_error('Expected SSH_MSG_KEXINIT'); - return false; - } - - if (!$this->_key_exchange($response)) { - return false; - } - } - - if ($this->send_kex_first && !$this->_key_exchange()) { - return false; - } - - $this->bitmap|= self::MASK_CONNECTED; - - return true; - } - - /** - * Generates the SSH identifier - * - * You should overwrite this method in your own class if you want to use another identifier - * - * @access protected - * @return string - */ - function _generate_identifier() - { - $identifier = 'SSH-2.0-phpseclib_2.0'; - - $ext = array(); - if (function_exists('sodium_crypto_box_publickey_from_secretkey')) { - $ext[] = 'libsodium'; - } - - if (extension_loaded('openssl')) { - $ext[] = 'openssl'; - } elseif (extension_loaded('mcrypt')) { - $ext[] = 'mcrypt'; - } - - if (extension_loaded('gmp')) { - $ext[] = 'gmp'; - } elseif (extension_loaded('bcmath')) { - $ext[] = 'bcmath'; - } - - if (!empty($ext)) { - $identifier .= ' (' . implode(', ', $ext) . ')'; - } - - return $identifier; - } - - /** - * Key Exchange - * - * @param string $kexinit_payload_server optional - * @access private - */ - function _key_exchange($kexinit_payload_server = false) - { - $preferred = $this->preferred; - $send_kex = true; - - $kex_algorithms = isset($preferred['kex']) ? - $preferred['kex'] : - $this->getSupportedKEXAlgorithms(); - $server_host_key_algorithms = isset($preferred['hostkey']) ? - $preferred['hostkey'] : - $this->getSupportedHostKeyAlgorithms(); - $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? - $preferred['server_to_client']['crypt'] : - $this->getSupportedEncryptionAlgorithms(); - $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? - $preferred['client_to_server']['crypt'] : - $this->getSupportedEncryptionAlgorithms(); - $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? - $preferred['server_to_client']['mac'] : - $this->getSupportedMACAlgorithms(); - $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? - $preferred['client_to_server']['mac'] : - $this->getSupportedMACAlgorithms(); - $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? - $preferred['server_to_client']['comp'] : - $this->getSupportedCompressionAlgorithms(); - $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? - $preferred['client_to_server']['comp'] : - $this->getSupportedCompressionAlgorithms(); - - // some SSH servers have buggy implementations of some of the above algorithms - switch (true) { - case $this->server_identifier == 'SSH-2.0-SSHD': - case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK': - if (!isset($preferred['server_to_client']['mac'])) { - $s2c_mac_algorithms = array_values(array_diff( - $s2c_mac_algorithms, - array('hmac-sha1-96', 'hmac-md5-96') - )); - } - if (!isset($preferred['client_to_server']['mac'])) { - $c2s_mac_algorithms = array_values(array_diff( - $c2s_mac_algorithms, - array('hmac-sha1-96', 'hmac-md5-96') - )); - } - } - - $str_kex_algorithms = implode(',', $kex_algorithms); - $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms); - $encryption_algorithms_server_to_client = implode(',', $s2c_encryption_algorithms); - $encryption_algorithms_client_to_server = implode(',', $c2s_encryption_algorithms); - $mac_algorithms_server_to_client = implode(',', $s2c_mac_algorithms); - $mac_algorithms_client_to_server = implode(',', $c2s_mac_algorithms); - $compression_algorithms_server_to_client = implode(',', $s2c_compression_algorithms); - $compression_algorithms_client_to_server = implode(',', $c2s_compression_algorithms); - - $client_cookie = Random::string(16); - - $kexinit_payload_client = pack( - 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN', - NET_SSH2_MSG_KEXINIT, - $client_cookie, - strlen($str_kex_algorithms), - $str_kex_algorithms, - strlen($str_server_host_key_algorithms), - $str_server_host_key_algorithms, - strlen($encryption_algorithms_client_to_server), - $encryption_algorithms_client_to_server, - strlen($encryption_algorithms_server_to_client), - $encryption_algorithms_server_to_client, - strlen($mac_algorithms_client_to_server), - $mac_algorithms_client_to_server, - strlen($mac_algorithms_server_to_client), - $mac_algorithms_server_to_client, - strlen($compression_algorithms_client_to_server), - $compression_algorithms_client_to_server, - strlen($compression_algorithms_server_to_client), - $compression_algorithms_server_to_client, - 0, - '', - 0, - '', - 0, - 0 - ); - - if ($kexinit_payload_server === false) { - if (!$this->_send_binary_packet($kexinit_payload_client)) { - return false; - } - - $kexinit_payload_server = $this->_get_binary_packet(); - if ($kexinit_payload_server === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) { - user_error('Expected SSH_MSG_KEXINIT'); - return false; - } - - $send_kex = false; - } - - $response = $kexinit_payload_server; - $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) - $server_cookie = $this->_string_shift($response, 16); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length'])); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length'])); - - if (!strlen($response)) { - return false; - } - extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1))); - $first_kex_packet_follows = $first_kex_packet_follows != 0; - - if ($send_kex && !$this->_send_binary_packet($kexinit_payload_client)) { - return false; - } - - // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange - // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the - // diffie-hellman key exchange as fast as possible - $decrypt = $this->_array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); - $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt); - if ($decryptKeyLength === null) { - user_error('No compatible server to client encryption algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $encrypt = $this->_array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); - $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt); - if ($encryptKeyLength === null) { - user_error('No compatible client to server encryption algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - // through diffie-hellman key exchange a symmetric key is obtained - $this->kex_algorithm = $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms); - if ($kex_algorithm === false) { - user_error('No compatible key exchange algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); - if ($server_host_key_algorithm === false) { - user_error('No compatible server host key algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $mac_algorithm_in = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); - if ($mac_algorithm_in === false) { - user_error('No compatible server to client message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $compression_map = array( - 'none' => NET_SSH2_COMPRESSION_NONE, - 'zlib' => NET_SSH2_COMPRESSION_ZLIB, - 'zlib@openssh.com' => NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH - ); - - $compression_algorithm_out = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm_out === false) { - user_error('No compatible client to server compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - $this->compress = $compression_map[$compression_algorithm_out]; - - $compression_algorithm_in = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); - if ($compression_algorithm_in === false) { - user_error('No compatible server to client compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - $this->decompress = $compression_map[$compression_algorithm_in]; - - // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. - $exchange_hash_rfc4419 = ''; - - if ($kex_algorithm === 'curve25519-sha256@libssh.org') { - $x = Random::string(32); - $eBytes = sodium_crypto_box_publickey_from_secretkey($x); - $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; - $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; - $kexHash = new Hash('sha256'); - } else { - if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) { - $dh_group_sizes_packed = pack( - 'NNN', - $this->kex_dh_group_size_min, - $this->kex_dh_group_size_preferred, - $this->kex_dh_group_size_max - ); - $packet = pack( - 'Ca*', - NET_SSH2_MSG_KEXDH_GEX_REQUEST, - $dh_group_sizes_packed - ); - if (!$this->_send_binary_packet($packet)) { - return false; - } - $this->_updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); - - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { - user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP'); - return false; - } - $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); - - if (strlen($response) < 4) { - return false; - } - extract(unpack('NprimeLength', $this->_string_shift($response, 4))); - $primeBytes = $this->_string_shift($response, $primeLength); - $prime = new BigInteger($primeBytes, -256); - - if (strlen($response) < 4) { - return false; - } - extract(unpack('NgLength', $this->_string_shift($response, 4))); - $gBytes = $this->_string_shift($response, $gLength); - $g = new BigInteger($gBytes, -256); - - $exchange_hash_rfc4419 = pack( - 'a*Na*Na*', - $dh_group_sizes_packed, - $primeLength, - $primeBytes, - $gLength, - $gBytes - ); - - $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; - $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; - } else { - switch ($kex_algorithm) { - // see http://tools.ietf.org/html/rfc2409#section-6.2 and - // http://tools.ietf.org/html/rfc2412, appendex E - case 'diffie-hellman-group1-sha1': - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; - break; - // see http://tools.ietf.org/html/rfc3526#section-3 - case 'diffie-hellman-group14-sha1': - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; - break; - } - // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1 - // the generator field element is 2 (decimal) and the hash function is sha1. - $g = new BigInteger(2); - $prime = new BigInteger($prime, 16); - $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; - $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; - } - - switch ($kex_algorithm) { - case 'diffie-hellman-group-exchange-sha256': - $kexHash = new Hash('sha256'); - break; - default: - $kexHash = new Hash('sha1'); - } - - /* To increase the speed of the key exchange, both client and server may - reduce the size of their private exponents. It should be at least - twice as long as the key material that is generated from the shared - secret. For more details, see the paper by van Oorschot and Wiener - [VAN-OORSCHOT]. - - -- http://tools.ietf.org/html/rfc4419#section-6.2 */ - $one = new BigInteger(1); - $keyLength = min($kexHash->getLength(), max($encryptKeyLength, $decryptKeyLength)); - $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength - $max = $max->subtract($one); - - $x = $one->random($one, $max); - $e = $g->modPow($x, $prime); - - $eBytes = $e->toBytes(true); - } - $data = pack('CNa*', constant($clientKexInitMessage), strlen($eBytes), $eBytes); - - if (!$this->_send_binary_packet($data)) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - switch ($clientKexInitMessage) { - case 'NET_SSH2_MSG_KEX_ECDH_INIT': - $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); - break; - case 'NET_SSH2_MSG_KEXDH_GEX_INIT': - $this->_updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); - } - - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - if ($type != constant($serverKexReplyMessage)) { - user_error("Expected $serverKexReplyMessage"); - return false; - } - switch ($serverKexReplyMessage) { - case 'NET_SSH2_MSG_KEX_ECDH_REPLY': - $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); - break; - case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': - $this->_updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); - } - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']); - - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $fBytes = $this->_string_shift($response, $temp['length']); - - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($response, 4)); - $this->signature = $this->_string_shift($response, $temp['length']); - - if (strlen($this->signature) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($this->signature, 4)); - $this->signature_format = $this->_string_shift($this->signature, $temp['length']); - - if ($kex_algorithm === 'curve25519-sha256@libssh.org') { - if (strlen($fBytes) !== 32) { - user_error('Received curve25519 public key of invalid length.'); - return false; - } - $key = new BigInteger(sodium_crypto_scalarmult($x, $fBytes), 256); - // sodium_compat doesn't emulate sodium_memzero - // also, with v1 of libsodium API the extension identifies itself as - // libsodium whereas v2 of the libsodium API (what PHP 7.2+ includes) - // identifies itself as sodium. sodium_compat uses the v1 API to - // emulate the v2 API if it's the v1 API that's available - if (extension_loaded('sodium') || extension_loaded('libsodium')) { - sodium_memzero($x); - } - } else { - $f = new BigInteger($fBytes, -256); - $key = $f->modPow($x, $prime); - } - $keyBytes = $key->toBytes(true); - - $this->exchange_hash = pack( - 'Na*Na*Na*Na*Na*a*Na*Na*Na*', - strlen($this->identifier), - $this->identifier, - strlen($this->server_identifier), - $this->server_identifier, - strlen($kexinit_payload_client), - $kexinit_payload_client, - strlen($kexinit_payload_server), - $kexinit_payload_server, - strlen($this->server_public_host_key), - $this->server_public_host_key, - $exchange_hash_rfc4419, - strlen($eBytes), - $eBytes, - strlen($fBytes), - $fBytes, - strlen($keyBytes), - $keyBytes - ); - - $this->exchange_hash = $kexHash->hash($this->exchange_hash); - - if ($this->session_id === false) { - $this->session_id = $this->exchange_hash; - } - - switch ($server_host_key_algorithm) { - case 'ssh-dss': - $expected_key_format = 'ssh-dss'; - break; - //case 'rsa-sha2-256': - //case 'rsa-sha2-512': - //case 'ssh-rsa': - default: - $expected_key_format = 'ssh-rsa'; - } - - if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { - switch (true) { - case $this->signature_format == $server_host_key_algorithm: - case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': - case $this->signature_format != 'ssh-rsa': - user_error('Server Host Key Algorithm Mismatch'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - } - - $packet = pack( - 'C', - NET_SSH2_MSG_NEWKEYS - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $response = $this->_get_binary_packet(); - - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - if ($type != NET_SSH2_MSG_NEWKEYS) { - user_error('Expected SSH_MSG_NEWKEYS'); - return false; - } - - $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); - - $this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt); - if ($this->encrypt) { - if ($this->crypto_engine) { - $this->encrypt->setPreferredEngine($this->crypto_engine); - } - if ($this->encrypt->block_size) { - $this->encrypt_block_size = $this->encrypt->block_size; - } - $this->encrypt->enableContinuousBuffer(); - $this->encrypt->disablePadding(); - - if ($this->encrypt->getBlockLength()) { - $this->encrypt_block_size = $this->encrypt->getBlockLength() >> 3; - } - - $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); - while ($this->encrypt_block_size > strlen($iv)) { - $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); - } - $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); - - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); - while ($encryptKeyLength > strlen($key)) { - $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); - - $this->encrypt->name = $decrypt; - } - - $this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt); - if ($this->decrypt) { - if ($this->crypto_engine) { - $this->decrypt->setPreferredEngine($this->crypto_engine); - } - if ($this->decrypt->block_size) { - $this->decrypt_block_size = $this->decrypt->block_size; - } - $this->decrypt->enableContinuousBuffer(); - $this->decrypt->disablePadding(); - - if ($this->decrypt->getBlockLength()) { - $this->decrypt_block_size = $this->decrypt->getBlockLength() >> 3; - } - - $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); - while ($this->decrypt_block_size > strlen($iv)) { - $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); - } - $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); - - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); - while ($decryptKeyLength > strlen($key)) { - $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); - - $this->decrypt->name = $decrypt; - } - - /* The "arcfour128" algorithm is the RC4 cipher, as described in - [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream - generated by the cipher MUST be discarded, and the first byte of the - first encrypted packet MUST be encrypted using the 1537th byte of - keystream. - - -- http://tools.ietf.org/html/rfc4345#section-4 */ - if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') { - $this->encrypt->encrypt(str_repeat("\0", 1536)); - } - if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') { - $this->decrypt->decrypt(str_repeat("\0", 1536)); - } - - $mac_algorithm_out = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); - if ($mac_algorithm_out === false) { - user_error('No compatible client to server message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $createKeyLength = 0; // ie. $mac_algorithm == 'none' - switch ($mac_algorithm_out) { - case 'hmac-sha2-256': - $this->hmac_create = new Hash('sha256'); - $createKeyLength = 32; - break; - case 'hmac-sha1': - $this->hmac_create = new Hash('sha1'); - $createKeyLength = 20; - break; - case 'hmac-sha1-96': - $this->hmac_create = new Hash('sha1-96'); - $createKeyLength = 20; - break; - case 'hmac-md5': - $this->hmac_create = new Hash('md5'); - $createKeyLength = 16; - break; - case 'hmac-md5-96': - $this->hmac_create = new Hash('md5-96'); - $createKeyLength = 16; - } - $this->hmac_create->name = $mac_algorithm_out; - - $checkKeyLength = 0; - $this->hmac_size = 0; - switch ($mac_algorithm_in) { - case 'hmac-sha2-256': - $this->hmac_check = new Hash('sha256'); - $checkKeyLength = 32; - $this->hmac_size = 32; - break; - case 'hmac-sha1': - $this->hmac_check = new Hash('sha1'); - $checkKeyLength = 20; - $this->hmac_size = 20; - break; - case 'hmac-sha1-96': - $this->hmac_check = new Hash('sha1-96'); - $checkKeyLength = 20; - $this->hmac_size = 12; - break; - case 'hmac-md5': - $this->hmac_check = new Hash('md5'); - $checkKeyLength = 16; - $this->hmac_size = 16; - break; - case 'hmac-md5-96': - $this->hmac_check = new Hash('md5-96'); - $checkKeyLength = 16; - $this->hmac_size = 12; - } - $this->hmac_check->name = $mac_algorithm_in; - - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); - while ($createKeyLength > strlen($key)) { - $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); - - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); - while ($checkKeyLength > strlen($key)) { - $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); - - $this->regenerate_compression_context = $this->regenerate_decompression_context = true; - - return true; - } - - /** - * Maps an encryption algorithm name to the number of key bytes. - * - * @param string $algorithm Name of the encryption algorithm - * @return int|null Number of bytes as an integer or null for unknown - * @access private - */ - function _encryption_algorithm_to_key_size($algorithm) - { - if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) { - return 16; - } - - switch ($algorithm) { - case 'none': - return 0; - case 'aes128-cbc': - case 'aes128-ctr': - case 'arcfour': - case 'arcfour128': - case 'blowfish-cbc': - case 'blowfish-ctr': - case 'twofish128-cbc': - case 'twofish128-ctr': - return 16; - case '3des-cbc': - case '3des-ctr': - case 'aes192-cbc': - case 'aes192-ctr': - case 'twofish192-cbc': - case 'twofish192-ctr': - return 24; - case 'aes256-cbc': - case 'aes256-ctr': - case 'arcfour256': - case 'twofish-cbc': - case 'twofish256-cbc': - case 'twofish256-ctr': - return 32; - } - return null; - } - - /** - * Maps an encryption algorithm name to an instance of a subclass of - * \phpseclib\Crypt\Base. - * - * @param string $algorithm Name of the encryption algorithm - * @return mixed Instance of \phpseclib\Crypt\Base or null for unknown - * @access private - */ - function _encryption_algorithm_to_crypt_instance($algorithm) - { - switch ($algorithm) { - case '3des-cbc': - return new TripleDES(); - case '3des-ctr': - return new TripleDES(Base::MODE_CTR); - case 'aes256-cbc': - case 'aes192-cbc': - case 'aes128-cbc': - return new Rijndael(); - case 'aes256-ctr': - case 'aes192-ctr': - case 'aes128-ctr': - return new Rijndael(Base::MODE_CTR); - case 'blowfish-cbc': - return new Blowfish(); - case 'blowfish-ctr': - return new Blowfish(Base::MODE_CTR); - case 'twofish128-cbc': - case 'twofish192-cbc': - case 'twofish256-cbc': - case 'twofish-cbc': - return new Twofish(); - case 'twofish128-ctr': - case 'twofish192-ctr': - case 'twofish256-ctr': - return new Twofish(Base::MODE_CTR); - case 'arcfour': - case 'arcfour128': - case 'arcfour256': - return new RC4(); - } - return null; - } - - /** - * Tests whether or not proposed algorithm has a potential for issues - * - * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html - * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291 - * @param string $algorithm Name of the encryption algorithm - * @return bool - * @access private - */ - function _bad_algorithm_candidate($algorithm) - { - switch ($algorithm) { - case 'arcfour256': - case 'aes192-ctr': - case 'aes256-ctr': - return true; - } - - return false; - } - - /** - * Login - * - * The $password parameter can be a plaintext password, a \phpseclib\Crypt\RSA object or an array - * - * @param string $username - * @return bool - * @see self::_login() - * @access public - */ - function login($username) - { - $args = func_get_args(); - $this->auth[] = $args; - - // try logging with 'none' as an authentication method first since that's what - // PuTTY does - if (substr($this->server_identifier, 0, 15) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) { - if ($this->_login($username)) { - return true; - } - if (count($args) == 1) { - return false; - } - } - return call_user_func_array(array(&$this, '_login'), $args); - } - - /** - * Login Helper - * - * @param string $username - * @return bool - * @see self::_login_helper() - * @access private - */ - function _login($username) - { - if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - if (!$this->_connect()) { - return false; - } - } - - $args = array_slice(func_get_args(), 1); - if (empty($args)) { - return $this->_login_helper($username); - } - - while (count($args)) { - if (!$this->auth_methods_to_continue || !$this->smartMFA) { - $newargs = $args; - $args = array(); - } else { - $newargs = array(); - foreach ($this->auth_methods_to_continue as $method) { - switch ($method) { - case 'publickey': - foreach ($args as $key => $arg) { - if (is_object($arg)) { - $newargs[] = $arg; - unset($args[$key]); - break; - } - } - break; - case 'keyboard-interactive': - $hasArray = $hasString = false; - foreach ($args as $arg) { - if ($hasArray || is_array($arg)) { - $hasArray = true; - break; - } - if ($hasString || is_string($arg)) { - $hasString = true; - break; - } - } - if ($hasArray && $hasString) { - foreach ($args as $key => $arg) { - if (is_array($arg)) { - $newargs[] = $arg; - break 2; - } - } - } - case 'password': - foreach ($args as $key => $arg) { - $newargs[] = $arg; - unset($args[$key]); - break; - } - } - } - } - - foreach ($newargs as $arg) { - if ($this->_login_helper($username, $arg)) { - return true; - } - } - } - return false; - } - - /** - * Login Helper - * - * @param string $username - * @param string $password - * @return bool - * @access private - * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} - * by sending dummy SSH_MSG_IGNORE messages. - */ - function _login_helper($username, $password = null) - { - if (!($this->bitmap & self::MASK_CONNECTED)) { - return false; - } - - if (!($this->bitmap & self::MASK_LOGIN_REQ)) { - $packet = pack( - 'CNa*', - NET_SSH2_MSG_SERVICE_REQUEST, - strlen('ssh-userauth'), - 'ssh-userauth' - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $response = $this->_get_binary_packet(); - if ($response === false) { - if ($this->retry_connect) { - $this->retry_connect = false; - if (!$this->_connect()) { - return false; - } - return $this->_login_helper($username, $password); - } - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (strlen($response) < 4) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) { - user_error('Expected SSH_MSG_SERVICE_ACCEPT'); - return false; - } - $this->bitmap |= self::MASK_LOGIN_REQ; - } - - if (strlen($this->last_interactive_response)) { - return !is_string($password) && !is_array($password) ? false : $this->_keyboard_interactive_process($password); - } - - if ($password instanceof RSA) { - return $this->_privatekey_login($username, $password); - } elseif ($password instanceof Agent) { - return $this->_ssh_agent_login($username, $password); - } - - if (is_array($password)) { - if ($this->_keyboard_interactive_login($username, $password)) { - $this->bitmap |= self::MASK_LOGIN; - return true; - } - return false; - } - - if (!isset($password)) { - $packet = pack( - 'CNa*Na*Na*', - NET_SSH2_MSG_USERAUTH_REQUEST, - strlen($username), - $username, - strlen('ssh-connection'), - 'ssh-connection', - strlen('none'), - 'none' - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - switch ($type) { - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - case NET_SSH2_MSG_USERAUTH_FAILURE: - extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); - $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); - default: - return false; - } - } - - $packet = pack( - 'CNa*Na*Na*CNa*', - NET_SSH2_MSG_USERAUTH_REQUEST, - strlen($username), - $username, - strlen('ssh-connection'), - 'ssh-connection', - strlen('password'), - 'password', - 0, - strlen($password), - $password - ); - - // remove the username and password from the logged packet - if (!defined('NET_SSH2_LOGGING')) { - $logged = null; - } else { - $logged = pack( - 'CNa*Na*Na*CNa*', - NET_SSH2_MSG_USERAUTH_REQUEST, - strlen('username'), - 'username', - strlen('ssh-connection'), - 'ssh-connection', - strlen('password'), - 'password', - 0, - strlen('password'), - 'password' - ); - } - - if (!$this->_send_binary_packet($packet, $logged)) { - return false; - } - - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - switch ($type) { - case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed - $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length); - return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); - case NET_SSH2_MSG_USERAUTH_FAILURE: - // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees - // multi-factor authentication - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $auth_methods = explode(',', $this->_string_shift($response, $length)); - $this->auth_methods_to_continue = $auth_methods; - if (!strlen($response)) { - return false; - } - extract(unpack('Cpartial_success', $this->_string_shift($response, 1))); - $partial_success = $partial_success != 0; - - if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { - if ($this->_keyboard_interactive_login($username, $password)) { - $this->bitmap |= self::MASK_LOGIN; - return true; - } - return false; - } - return false; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - } - - return false; - } - - /** - * Login via keyboard-interactive authentication - * - * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator. - * - * @param string $username - * @param string $password - * @return bool - * @access private - */ - function _keyboard_interactive_login($username, $password) - { - $packet = pack( - 'CNa*Na*Na*Na*Na*', - NET_SSH2_MSG_USERAUTH_REQUEST, - strlen($username), - $username, - strlen('ssh-connection'), - 'ssh-connection', - strlen('keyboard-interactive'), - 'keyboard-interactive', - 0, - '', - 0, - '' - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - return $this->_keyboard_interactive_process($password); - } - - /** - * Handle the keyboard-interactive requests / responses. - * - * @return bool - * @access private - */ - function _keyboard_interactive_process() - { - $responses = func_get_args(); - - if (strlen($this->last_interactive_response)) { - $response = $this->last_interactive_response; - } else { - $orig = $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - } - - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - switch ($type) { - case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->_string_shift($response, $length); // name; may be empty - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->_string_shift($response, $length); // instruction; may be empty - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->_string_shift($response, $length); // language tag; may be empty - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nnum_prompts', $this->_string_shift($response, 4))); - - for ($i = 0; $i < count($responses); $i++) { - if (is_array($responses[$i])) { - foreach ($responses[$i] as $key => $value) { - $this->keyboard_requests_responses[$key] = $value; - } - unset($responses[$i]); - } - } - $responses = array_values($responses); - - if (isset($this->keyboard_requests_responses)) { - for ($i = 0; $i < $num_prompts; $i++) { - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - // prompt - ie. "Password: "; must not be empty - $prompt = $this->_string_shift($response, $length); - //$echo = $this->_string_shift($response) != chr(0); - foreach ($this->keyboard_requests_responses as $key => $value) { - if (substr($prompt, 0, strlen($key)) == $key) { - $responses[] = $value; - break; - } - } - } - } - - // see http://tools.ietf.org/html/rfc4256#section-3.2 - if (strlen($this->last_interactive_response)) { - $this->last_interactive_response = ''; - } else { - $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); - } - - if (!count($responses) && $num_prompts) { - $this->last_interactive_response = $orig; - return false; - } - - /* - After obtaining the requested information from the user, the client - MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. - */ - // see http://tools.ietf.org/html/rfc4256#section-3.4 - $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); - for ($i = 0; $i < count($responses); $i++) { - $packet.= pack('Na*', strlen($responses[$i]), $responses[$i]); - $logged.= pack('Na*', strlen('dummy-answer'), 'dummy-answer'); - } - - if (!$this->_send_binary_packet($packet, $logged)) { - return false; - } - - $this->_updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); - - /* - After receiving the response, the server MUST send either an - SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another - SSH_MSG_USERAUTH_INFO_REQUEST message. - */ - // maybe phpseclib should force close the connection after x request / responses? unless something like that is done - // there could be an infinite loop of request / responses. - return $this->_keyboard_interactive_process(); - case NET_SSH2_MSG_USERAUTH_SUCCESS: - return true; - case NET_SSH2_MSG_USERAUTH_FAILURE: - extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); - $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); - return false; - } - - return false; - } - - /** - * Login with an ssh-agent provided key - * - * @param string $username - * @param \phpseclib\System\SSH\Agent $agent - * @return bool - * @access private - */ - function _ssh_agent_login($username, $agent) - { - $this->agent = $agent; - $keys = $agent->requestIdentities(); - foreach ($keys as $key) { - if ($this->_privatekey_login($username, $key)) { - return true; - } - } - - return false; - } - - /** - * Login with an RSA private key - * - * @param string $username - * @param \phpseclib\Crypt\RSA $privatekey - * @return bool - * @access private - * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} - * by sending dummy SSH_MSG_IGNORE messages. - */ - function _privatekey_login($username, $privatekey) - { - // see http://tools.ietf.org/html/rfc4253#page-15 - $publickey = $privatekey->getPublicKey(RSA::PUBLIC_FORMAT_RAW); - if ($publickey === false) { - return false; - } - - $publickey = array( - 'e' => $publickey['e']->toBytes(true), - 'n' => $publickey['n']->toBytes(true) - ); - $publickey = pack( - 'Na*Na*Na*', - strlen('ssh-rsa'), - 'ssh-rsa', - strlen($publickey['e']), - $publickey['e'], - strlen($publickey['n']), - $publickey['n'] - ); - - switch ($this->signature_format) { - case 'rsa-sha2-512': - $hash = 'sha512'; - $signatureType = 'rsa-sha2-512'; - break; - case 'rsa-sha2-256': - $hash = 'sha256'; - $signatureType = 'rsa-sha2-256'; - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - $signatureType = 'ssh-rsa'; - } - - $part1 = pack( - 'CNa*Na*Na*', - NET_SSH2_MSG_USERAUTH_REQUEST, - strlen($username), - $username, - strlen('ssh-connection'), - 'ssh-connection', - strlen('publickey'), - 'publickey' - ); - $part2 = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($publickey), $publickey); - - $packet = $part1 . chr(0) . $part2; - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - switch ($type) { - case NET_SSH2_MSG_USERAUTH_FAILURE: - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); - $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); - $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE'; - return false; - case NET_SSH2_MSG_USERAUTH_PK_OK: - // we'll just take it on faith that the public key blob and the public key algorithm name are as - // they should be - $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); - break; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - default: - user_error('Unexpected response to publickey authentication pt 1'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - - $packet = $part1 . chr(1) . $part2; - $privatekey->setSignatureMode(RSA::SIGNATURE_PKCS1); - $privatekey->setHash($hash); - $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet)); - $signature = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($signature), $signature); - $packet.= pack('Na*', strlen($signature), $signature); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - switch ($type) { - case NET_SSH2_MSG_USERAUTH_FAILURE: - // either the login is bad or the server employs multi-factor authentication - extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); - $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); - return false; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - } - - user_error('Unexpected response to publickey authentication pt 2'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - - /** - * Set Timeout - * - * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. - * Setting $timeout to false or 0 will mean there is no timeout. - * - * @param mixed $timeout - * @access public - */ - function setTimeout($timeout) - { - $this->timeout = $this->curTimeout = $timeout; - } - - /** - * Set Keep Alive - * - * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. - * - * @param int $interval - * @access public - */ - function setKeepAlive($interval) - { - $this->keepAlive = $interval; - } - - /** - * Get the output from stdError - * - * @access public - */ - function getStdError() - { - return $this->stdErrorLog; - } - - /** - * Execute Command - * - * If $callback is set to false then \phpseclib\Net\SSH2::_get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. - * In all likelihood, this is not a feature you want to be taking advantage of. - * - * @param string $command - * @param Callback $callback - * @return string - * @access public - */ - function exec($command, $callback = null) - { - $this->curTimeout = $this->timeout; - $this->is_timeout = false; - $this->stdErrorLog = ''; - - if (!$this->isAuthenticated()) { - return false; - } - - if ($this->in_request_pty_exec) { - user_error('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); - return false; - } - - // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to - // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, - // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. - // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info - $this->window_size_server_to_client[self::CHANNEL_EXEC] = $this->window_size; - // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy - // uses 0x4000, that's what will be used here, as well. - $packet_size = 0x4000; - - $packet = pack( - 'CNa*N3', - NET_SSH2_MSG_CHANNEL_OPEN, - strlen('session'), - 'session', - self::CHANNEL_EXEC, - $this->window_size_server_to_client[self::CHANNEL_EXEC], - $packet_size - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = $this->_get_channel_packet(self::CHANNEL_EXEC); - if ($response === false) { - return false; - } - - if ($this->request_pty === true) { - $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); - $packet = pack( - 'CNNa*CNa*N5a*', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_EXEC], - strlen('pty-req'), - 'pty-req', - 1, - strlen('vt100'), - 'vt100', - $this->windowColumns, - $this->windowRows, - 0, - 0, - strlen($terminal_modes), - $terminal_modes - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; - if (!$this->_get_channel_packet(self::CHANNEL_EXEC)) { - user_error('Unable to request pseudo-terminal'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - - $this->in_request_pty_exec = true; - } - - // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things - // down. the one place where it might be desirable is if you're doing something like \phpseclib\Net\SSH2::exec('ping localhost &'). - // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then - // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but - // neither will your script. - - // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by - // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the - // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. - $packet = pack( - 'CNNa*CNa*', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_EXEC], - strlen('exec'), - 'exec', - 1, - strlen($command), - $command - ); - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $response = $this->_get_channel_packet(self::CHANNEL_EXEC); - if ($response === false) { - return false; - } - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; - - if ($callback === false || $this->in_request_pty_exec) { - return true; - } - - $output = ''; - while (true) { - $temp = $this->_get_channel_packet(self::CHANNEL_EXEC); - switch (true) { - case $temp === true: - return is_callable($callback) ? true : $output; - case $temp === false: - return false; - default: - if (is_callable($callback)) { - if (call_user_func($callback, $temp) === true) { - $this->_close_channel(self::CHANNEL_EXEC); - return true; - } - } else { - $output.= $temp; - } - } - } - } - - /** - * Creates an interactive shell - * - * @see self::read() - * @see self::write() - * @return bool - * @access private - */ - function _initShell() - { - if ($this->in_request_pty_exec === true) { - return true; - } - - $this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size; - $packet_size = 0x4000; - - $packet = pack( - 'CNa*N3', - NET_SSH2_MSG_CHANNEL_OPEN, - strlen('session'), - 'session', - self::CHANNEL_SHELL, - $this->window_size_server_to_client[self::CHANNEL_SHELL], - $packet_size - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = $this->_get_channel_packet(self::CHANNEL_SHELL); - if ($response === false) { - return false; - } - - $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); - $packet = pack( - 'CNNa*CNa*N5a*', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_SHELL], - strlen('pty-req'), - 'pty-req', - 1, - strlen('vt100'), - 'vt100', - $this->windowColumns, - $this->windowRows, - 0, - 0, - strlen($terminal_modes), - $terminal_modes - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; - - if (!$this->_get_channel_packet(self::CHANNEL_SHELL)) { - user_error('Unable to request pseudo-terminal'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - - $packet = pack( - 'CNNa*C', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_SHELL], - strlen('shell'), - 'shell', - 1 - ); - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $response = $this->_get_channel_packet(self::CHANNEL_SHELL); - if ($response === false) { - return false; - } - - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; - - $this->bitmap |= self::MASK_SHELL; - - return true; - } - - /** - * Return the channel to be used with read() / write() - * - * @see self::read() - * @see self::write() - * @return int - * @access public - */ - function _get_interactive_channel() - { - switch (true) { - case $this->in_subsystem: - return self::CHANNEL_SUBSYSTEM; - case $this->in_request_pty_exec: - return self::CHANNEL_EXEC; - default: - return self::CHANNEL_SHELL; - } - } - - /** - * Return an available open channel - * - * @return int - * @access public - */ - function _get_open_channel() - { - $channel = self::CHANNEL_EXEC; - do { - if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) { - return $channel; - } - } while ($channel++ < self::CHANNEL_SUBSYSTEM); - - return false; - } - - /** - * Returns the output of an interactive shell - * - * Returns when there's a match for $expect, which can take the form of a string literal or, - * if $mode == self::READ_REGEX, a regular expression. - * - * @see self::write() - * @param string $expect - * @param int $mode - * @return string|bool - * @access public - */ - function read($expect = '', $mode = self::READ_SIMPLE) - { - $this->curTimeout = $this->timeout; - $this->is_timeout = false; - - if (!$this->isAuthenticated()) { - user_error('Operation disallowed prior to login()'); - return false; - } - - if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; - } - - $channel = $this->_get_interactive_channel(); - - if ($mode == self::READ_NEXT) { - return $this->_get_channel_packet($channel); - } - - $match = $expect; - while (true) { - if ($mode == self::READ_REGEX) { - preg_match($expect, substr($this->interactiveBuffer, -1024), $matches); - $match = isset($matches[0]) ? $matches[0] : ''; - } - $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; - if ($pos !== false) { - return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match)); - } - $response = $this->_get_channel_packet($channel); - if (is_bool($response)) { - $this->in_request_pty_exec = false; - return $response ? $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)) : false; - } - - $this->interactiveBuffer.= $response; - } - } - - /** - * Inputs a command into an interactive shell. - * - * @see self::read() - * @param string $cmd - * @return bool - * @access public - */ - function write($cmd) - { - if (!$this->isAuthenticated()) { - user_error('Operation disallowed prior to login()'); - return false; - } - - if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; - } - - return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd); - } - - /** - * Start a subsystem. - * - * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept - * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened. - * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and - * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented - * if there's sufficient demand for such a feature. - * - * @see self::stopSubsystem() - * @param string $subsystem - * @return bool - * @access public - */ - function startSubsystem($subsystem) - { - $this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size; - - $packet = pack( - 'CNa*N3', - NET_SSH2_MSG_CHANNEL_OPEN, - strlen('session'), - 'session', - self::CHANNEL_SUBSYSTEM, - $this->window_size, - 0x4000 - ); - - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM); - if ($response === false) { - return false; - } - - $packet = pack( - 'CNNa*CNa*', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_SUBSYSTEM], - strlen('subsystem'), - 'subsystem', - 1, - strlen($subsystem), - $subsystem - ); - if (!$this->_send_binary_packet($packet)) { - return false; - } - - $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM); - - if ($response === false) { - return false; - } - - $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; - - $this->bitmap |= self::MASK_SHELL; - $this->in_subsystem = true; - - return true; - } - - /** - * Stops a subsystem. - * - * @see self::startSubsystem() - * @return bool - * @access public - */ - function stopSubsystem() - { - $this->in_subsystem = false; - $this->_close_channel(self::CHANNEL_SUBSYSTEM); - return true; - } - - /** - * Closes a channel - * - * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call - * - * @access public - */ - function reset() - { - $this->_close_channel($this->_get_interactive_channel()); - } - - /** - * Is timeout? - * - * Did exec() or read() return because they timed out or because they encountered the end? - * - * @access public - */ - function isTimeout() - { - return $this->is_timeout; - } - - /** - * Disconnect - * - * @access public - */ - function disconnect() - { - $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { - fclose($this->realtime_log_file); - } - } - - /** - * Destructor. - * - * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call - * disconnect(). - * - * @access public - */ - function __destruct() - { - $this->disconnect(); - } - - /** - * Is the connection still active? - * - * @return bool - * @access public - */ - function isConnected() - { - return (bool) ($this->bitmap & self::MASK_CONNECTED); - } - - /** - * Have you successfully been logged in? - * - * @return bool - * @access public - */ - function isAuthenticated() - { - return (bool) ($this->bitmap & self::MASK_LOGIN); - } - - /** - * Pings a server connection, or tries to reconnect if the connection has gone down - * - * Inspired by http://php.net/manual/en/mysqli.ping.php - * - * @return bool - * @access public - */ - function ping() - { - if (!$this->isAuthenticated()) { - if (!empty($this->auth)) { - return $this->_reconnect(); - } - return false; - } - - $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE] = $this->window_size; - $packet_size = 0x4000; - $packet = pack( - 'CNa*N3', - NET_SSH2_MSG_CHANNEL_OPEN, - strlen('session'), - 'session', - self::CHANNEL_KEEP_ALIVE, - $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE], - $packet_size - ); - - if (!@$this->_send_binary_packet($packet)) { - return $this->_reconnect(); - } - - $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = @$this->_get_channel_packet(self::CHANNEL_KEEP_ALIVE); - if ($response !== false) { - $this->_close_channel(self::CHANNEL_KEEP_ALIVE); - return true; - } - - return $this->_reconnect(); - } - - /** - * In situ reconnect method - * - * @return boolean - * @access private - */ - function _reconnect() - { - $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); - $this->retry_connect = true; - if (!$this->_connect()) { - return false; - } - foreach ($this->auth as $auth) { - $result = call_user_func_array(array(&$this, 'login'), $auth); - } - return $result; - } - - /** - * Resets a connection for re-use - * - * @param int $reason - * @access private - */ - function _reset_connection($reason) - { - $this->_disconnect($reason); - $this->decrypt = $this->encrypt = false; - $this->decrypt_block_size = $this->encrypt_block_size = 8; - $this->hmac_check = $this->hmac_create = false; - $this->hmac_size = false; - $this->session_id = false; - $this->retry_connect = true; - $this->get_seq_no = $this->send_seq_no = 0; - } - - /** - * Gets Binary Packets - * - * See '6. Binary Packet Protocol' of rfc4253 for more info. - * - * @see self::_send_binary_packet() - * @return string - * @access private - */ - function _get_binary_packet($skip_channel_filter = false) - { - if ($skip_channel_filter) { - $read = array($this->fsock); - $write = $except = null; - - if (!$this->curTimeout) { - if ($this->keepAlive <= 0) { - @stream_select($read, $write, $except, null); - } else { - if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - return $this->_get_binary_packet(true); - } - } - } else { - if ($this->curTimeout < 0) { - $this->is_timeout = true; - return true; - } - - $read = array($this->fsock); - $write = $except = null; - - $start = microtime(true); - - if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { - if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; - return $this->_get_binary_packet(true); - } - $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; - } - - $sec = floor($this->curTimeout); - $usec = 1000000 * ($this->curTimeout - $sec); - - // on windows this returns a "Warning: Invalid CRT parameters detected" error - if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { - $this->is_timeout = true; - return true; - } - $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; - } - } - - if (!is_resource($this->fsock) || feof($this->fsock)) { - $this->bitmap = 0; - user_error('Connection closed (by server) prematurely ' . $elapsed . 's'); - return false; - } - - $start = microtime(true); - $raw = stream_get_contents($this->fsock, $this->decrypt_block_size); - - if (!strlen($raw)) { - user_error('No data received from server'); - return false; - } - - if ($this->decrypt !== false) { - $raw = $this->decrypt->decrypt($raw); - } - if ($raw === false) { - user_error('Unable to decrypt content'); - return false; - } - - if (strlen($raw) < 5) { - return false; - } - extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5))); - - $remaining_length = $packet_length + 4 - $this->decrypt_block_size; - - // quoting , - // "implementations SHOULD check that the packet length is reasonable" - // PuTTY uses 0x9000 as the actual max packet size and so to shall we - if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { - if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt->name) && !($this->bitmap & SSH2::MASK_LOGIN)) { - $this->bad_key_size_fix = true; - $this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - return false; - } - user_error('Invalid size'); - return false; - } - - $buffer = ''; - while ($remaining_length > 0) { - $temp = stream_get_contents($this->fsock, $remaining_length); - if ($temp === false || feof($this->fsock)) { - $this->bitmap = 0; - user_error('Error reading from socket'); - return false; - } - $buffer.= $temp; - $remaining_length-= strlen($temp); - } - - $stop = microtime(true); - if (strlen($buffer)) { - $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer; - } - - $payload = $this->_string_shift($raw, $packet_length - $padding_length - 1); - $padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty - - if ($this->hmac_check !== false) { - $hmac = stream_get_contents($this->fsock, $this->hmac_size); - if ($hmac === false || strlen($hmac) != $this->hmac_size) { - $this->bitmap = 0; - user_error('Error reading socket'); - return false; - } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) { - user_error('Invalid HMAC'); - return false; - } - } - - switch ($this->decompress) { - case NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: - if (!$this->isAuthenticated()) { - break; - } - case NET_SSH2_COMPRESSION_ZLIB: - if ($this->regenerate_decompression_context) { - $this->regenerate_decompression_context = false; - - $cmf = ord($payload[0]); - $cm = $cmf & 0x0F; - if ($cm != 8) { // deflate - user_error("Only CM = 8 ('deflate') is supported ($cm)"); - } - $cinfo = ($cmf & 0xF0) >> 4; - if ($cinfo > 7) { - user_error("CINFO above 7 is not allowed ($cinfo)"); - } - $windowSize = 1 << ($cinfo + 8); - - $flg = ord($payload[1]); - //$fcheck = $flg && 0x0F; - if ((($cmf << 8) | $flg) % 31) { - user_error('fcheck failed'); - } - $fdict = boolval($flg & 0x20); - $flevel = ($flg & 0xC0) >> 6; - - $this->decompress_context = inflate_init(ZLIB_ENCODING_RAW, array('window' => $cinfo + 8)); - $payload = substr($payload, 2); - } - if ($this->decompress_context) { - $payload = inflate_add($this->decompress_context, $payload, ZLIB_PARTIAL_FLUSH); - } - } - - $this->get_seq_no++; - - if (defined('NET_SSH2_LOGGING')) { - $current = microtime(true); - $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; - $message_number = '<- ' . $message_number . - ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; - $this->_append_log($message_number, $payload); - $this->last_packet = $current; - } - - return $this->_filter($payload, $skip_channel_filter); - } - - /** - * Filter Binary Packets - * - * Because some binary packets need to be ignored... - * - * @see self::_get_binary_packet() - * @return string - * @access private - */ - function _filter($payload, $skip_channel_filter) - { - switch (ord($payload[0])) { - case NET_SSH2_MSG_DISCONNECT: - $this->_string_shift($payload, 1); - if (strlen($payload) < 8) { - return false; - } - extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8))); - $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length); - $this->bitmap = 0; - return false; - case NET_SSH2_MSG_IGNORE: - $payload = $this->_get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_DEBUG: - $this->_string_shift($payload, 2); - if (strlen($payload) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($payload, 4))); - $this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length); - $payload = $this->_get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_UNIMPLEMENTED: - return false; - case NET_SSH2_MSG_KEXINIT: - if ($this->session_id !== false) { - $this->send_kex_first = false; - if (!$this->_key_exchange($payload)) { - $this->bitmap = 0; - return false; - } - $payload = $this->_get_binary_packet($skip_channel_filter); - } - } - - // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in - if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { - $this->_string_shift($payload, 1); - if (strlen($payload) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($payload, 4))); - $this->banner_message = $this->_string_shift($payload, $length); - $payload = $this->_get_binary_packet(); - } - - // only called when we've already logged in - if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { - if (is_bool($payload)) { - return $payload; - } - - switch (ord($payload[0])) { - case NET_SSH2_MSG_CHANNEL_REQUEST: - if (strlen($payload) == 31) { - extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); - if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { - if (ord(substr($payload, 9 + $length))) { // want reply - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); - } - $payload = $this->_get_binary_packet($skip_channel_filter); - } - } - break; - case NET_SSH2_MSG_CHANNEL_DATA: - case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: - case NET_SSH2_MSG_CHANNEL_CLOSE: - case NET_SSH2_MSG_CHANNEL_EOF: - if (!$skip_channel_filter && !empty($this->server_channels)) { - $this->binary_packet_buffer = $payload; - $this->_get_channel_packet(true); - $payload = $this->_get_binary_packet(); - } - break; - case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 - if (strlen($payload) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($payload, 4))); - $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . $this->_string_shift($payload, $length); - - if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) { - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - - $payload = $this->_get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 - $this->_string_shift($payload, 1); - if (strlen($payload) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($payload, 4))); - $data = $this->_string_shift($payload, $length); - if (strlen($payload) < 4) { - return false; - } - extract(unpack('Nserver_channel', $this->_string_shift($payload, 4))); - switch ($data) { - case 'auth-agent': - case 'auth-agent@openssh.com': - if (isset($this->agent)) { - $new_channel = self::CHANNEL_AGENT_FORWARD; - - if (strlen($payload) < 8) { - return false; - } - extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4))); - extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4))); - - $this->packet_size_client_to_server[$new_channel] = $remote_window_size; - $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; - $this->window_size_client_to_server[$new_channel] = $this->window_size; - - $packet_size = 0x4000; - - $packet = pack( - 'CN4', - NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, - $server_channel, - $new_channel, - $packet_size, - $packet_size - ); - - $this->server_channels[$new_channel] = $server_channel; - $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; - if (!$this->_send_binary_packet($packet)) { - return false; - } - } - break; - default: - $packet = pack( - 'CN3a*Na*', - NET_SSH2_MSG_REQUEST_FAILURE, - $server_channel, - NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, - 0, - '', - 0, - '' - ); - - if (!$this->_send_binary_packet($packet)) { - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - } - $payload = $this->_get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: - $this->_string_shift($payload, 1); - if (strlen($payload) < 8) { - return false; - } - extract(unpack('Nchannel', $this->_string_shift($payload, 4))); - extract(unpack('Nwindow_size', $this->_string_shift($payload, 4))); - $this->window_size_client_to_server[$channel]+= $window_size; - - $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet($skip_channel_filter); - } - } - - return $payload; - } - - /** - * Enable Quiet Mode - * - * Suppress stderr from output - * - * @access public - */ - function enableQuietMode() - { - $this->quiet_mode = true; - } - - /** - * Disable Quiet Mode - * - * Show stderr in output - * - * @access public - */ - function disableQuietMode() - { - $this->quiet_mode = false; - } - - /** - * Returns whether Quiet Mode is enabled or not - * - * @see self::enableQuietMode() - * @see self::disableQuietMode() - * @access public - * @return bool - */ - function isQuietModeEnabled() - { - return $this->quiet_mode; - } - - /** - * Enable request-pty when using exec() - * - * @access public - */ - function enablePTY() - { - $this->request_pty = true; - } - - /** - * Disable request-pty when using exec() - * - * @access public - */ - function disablePTY() - { - if ($this->in_request_pty_exec) { - $this->_close_channel(self::CHANNEL_EXEC); - $this->in_request_pty_exec = false; - } - $this->request_pty = false; - } - - /** - * Returns whether request-pty is enabled or not - * - * @see self::enablePTY() - * @see self::disablePTY() - * @access public - * @return bool - */ - function isPTYEnabled() - { - return $this->request_pty; - } - - /** - * Gets channel data - * - * Returns the data as a string if it's available and false if not. - * - * @param int $client_channel - * @param bool $skip_extended - * @return mixed|bool - * @access private - */ - function _get_channel_packet($client_channel, $skip_extended = false) - { - if (!empty($this->channel_buffers[$client_channel])) { - switch ($this->channel_status[$client_channel]) { - case NET_SSH2_MSG_CHANNEL_REQUEST: - foreach ($this->channel_buffers[$client_channel] as $i => $packet) { - switch (ord($packet[0])) { - case NET_SSH2_MSG_CHANNEL_SUCCESS: - case NET_SSH2_MSG_CHANNEL_FAILURE: - unset($this->channel_buffers[$client_channel][$i]); - return substr($packet, 1); - } - } - break; - default: - return substr(array_shift($this->channel_buffers[$client_channel]), 1); - } - } - - while (true) { - if ($this->binary_packet_buffer !== false) { - $response = $this->binary_packet_buffer; - $this->binary_packet_buffer = false; - } else { - $response = $this->_get_binary_packet(true); - if ($response === true && $this->is_timeout) { - if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { - $this->_close_channel($client_channel); - } - return true; - } - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - } - - if ($client_channel == -1 && $response === true) { - return true; - } - if (!strlen($response)) { - return false; - } - extract(unpack('Ctype', $this->_string_shift($response, 1))); - - if (strlen($response) < 4) { - return false; - } - if ($type == NET_SSH2_MSG_CHANNEL_OPEN) { - extract(unpack('Nlength', $this->_string_shift($response, 4))); - } else { - extract(unpack('Nchannel', $this->_string_shift($response, 4))); - } - - // will not be setup yet on incoming channel open request - if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { - $this->window_size_server_to_client[$channel]-= strlen($response); - - // resize the window, if appropriate - if ($this->window_size_server_to_client[$channel] < 0) { - // PuTTY does something more analogous to the following: - //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { - $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); - if (!$this->_send_binary_packet($packet)) { - return false; - } - $this->window_size_server_to_client[$channel]+= $this->window_resize; - } - - switch ($type) { - case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: - /* - if ($client_channel == self::CHANNEL_EXEC) { - $this->_send_channel_packet($client_channel, chr(0)); - } - */ - // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR - if (strlen($response) < 8) { - return false; - } - extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8))); - $data = $this->_string_shift($response, $length); - $this->stdErrorLog.= $data; - if ($skip_extended || $this->quiet_mode) { - continue 2; - } - if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) { - return $data; - } - $this->channel_buffers[$channel][] = chr($type) . $data; - - continue 2; - case NET_SSH2_MSG_CHANNEL_REQUEST: - if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) { - continue 2; - } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $value = $this->_string_shift($response, $length); - switch ($value) { - case 'exit-signal': - $this->_string_shift($response, 1); - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length); - $this->_string_shift($response, 1); - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - if ($length) { - $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length); - } - - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); - - $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF; - - continue 3; - case 'exit-status': - if (strlen($response) < 5) { - return false; - } - extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5))); - $this->exit_status = $exit_status; - - // "The client MAY ignore these messages." - // -- http://tools.ietf.org/html/rfc4254#section-6.10 - - continue 3; - default: - // "Some systems may not implement signals, in which case they SHOULD ignore this message." - // -- http://tools.ietf.org/html/rfc4254#section-6.9 - continue 3; - } - } - - switch ($this->channel_status[$channel]) { - case NET_SSH2_MSG_CHANNEL_OPEN: - switch ($type) { - case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nserver_channel', $this->_string_shift($response, 4))); - $this->server_channels[$channel] = $server_channel; - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nwindow_size', $this->_string_shift($response, 4))); - if ($window_size < 0) { - $window_size&= 0x7FFFFFFF; - $window_size+= 0x80000000; - } - $this->window_size_client_to_server[$channel] = $window_size; - if (strlen($response) < 4) { - return false; - } - $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4)); - $this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server']; - $result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended); - $this->_on_channel_open(); - return $result; - case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: - user_error('Unable to open channel'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - default: - if ($client_channel == $channel) { - user_error('Unexpected response to open request'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - return $this->_get_channel_packet($client_channel, $skip_extended); - } - break; - case NET_SSH2_MSG_CHANNEL_REQUEST: - switch ($type) { - case NET_SSH2_MSG_CHANNEL_SUCCESS: - return true; - case NET_SSH2_MSG_CHANNEL_FAILURE: - return false; - case NET_SSH2_MSG_CHANNEL_DATA: - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $data = $this->_string_shift($response, $length); - $this->channel_buffers[$channel][] = chr($type) . $data; - return $this->_get_channel_packet($client_channel, $skip_extended); - default: - user_error('Unable to fulfill channel request'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - case NET_SSH2_MSG_CHANNEL_CLOSE: - return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended); - } - } - - // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA - - switch ($type) { - case NET_SSH2_MSG_CHANNEL_DATA: - /* - if ($channel == self::CHANNEL_EXEC) { - // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server - // this actually seems to make things twice as fast. more to the point, the message right after - // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. - // in OpenSSH it slows things down but only by a couple thousandths of a second. - $this->_send_channel_packet($channel, chr(0)); - } - */ - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $data = $this->_string_shift($response, $length); - - if ($channel == self::CHANNEL_AGENT_FORWARD) { - $agent_response = $this->agent->_forward_data($data); - if (!is_bool($agent_response)) { - $this->_send_channel_packet($channel, $agent_response); - } - break; - } - - if ($client_channel == $channel) { - return $data; - } - $this->channel_buffers[$channel][] = chr($type) . $data; - break; - case NET_SSH2_MSG_CHANNEL_CLOSE: - $this->curTimeout = 5; - - if ($this->bitmap & self::MASK_SHELL) { - $this->bitmap&= ~self::MASK_SHELL; - } - if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); - } - - $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; - if ($client_channel == $channel) { - return true; - } - case NET_SSH2_MSG_CHANNEL_EOF: - break; - default: - user_error("Error reading channel data ($type)"); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - } - } - - /** - * Sends Binary Packets - * - * See '6. Binary Packet Protocol' of rfc4253 for more info. - * - * @param string $data - * @param string $logged - * @see self::_get_binary_packet() - * @return bool - * @access private - */ - function _send_binary_packet($data, $logged = null) - { - if (!is_resource($this->fsock) || feof($this->fsock)) { - $this->bitmap = 0; - user_error('Connection closed prematurely'); - return false; - } - - if (!isset($logged)) { - $logged = $data; - } - - switch ($this->compress) { - case NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: - if (!$this->isAuthenticated()) { - break; - } - case NET_SSH2_COMPRESSION_ZLIB: - if (!$this->regenerate_compression_context) { - $header = ''; - } else { - $this->regenerate_compression_context = false; - $this->compress_context = deflate_init(ZLIB_ENCODING_RAW, ['window' => 15]); - $header = "\x78\x9C"; - } - if ($this->compress_context) { - $data = $header . deflate_add($this->compress_context, $data, ZLIB_PARTIAL_FLUSH); - } - } - - // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 - $packet_length = strlen($data) + 9; - // round up to the nearest $this->encrypt_block_size - $packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; - // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length - $padding_length = $packet_length - strlen($data) - 5; - $padding = Random::string($padding_length); - - // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself - $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); - - $hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : ''; - $this->send_seq_no++; - - if ($this->encrypt !== false) { - $packet = $this->encrypt->encrypt($packet); - } - - $packet.= $hmac; - - $start = microtime(true); - $result = strlen($packet) == @fputs($this->fsock, $packet); - $stop = microtime(true); - - if (defined('NET_SSH2_LOGGING')) { - $current = microtime(true); - $message_number = isset($this->message_numbers[ord($logged[0])]) ? $this->message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; - $message_number = '-> ' . $message_number . - ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; - $this->_append_log($message_number, $logged); - $this->last_packet = $current; - } - - return $result; - } - - /** - * Logs data packets - * - * Makes sure that only the last 1MB worth of packets will be logged - * - * @param string $message_number - * @param string $message - * @access private - */ - function _append_log($message_number, $message) - { - // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) - if (strlen($message_number) > 2) { - $this->_string_shift($message); - } - - switch (NET_SSH2_LOGGING) { - // useful for benchmarks - case self::LOG_SIMPLE: - $this->message_number_log[] = $message_number; - break; - // the most useful log for SSH2 - case self::LOG_COMPLEX: - $this->message_number_log[] = $message_number; - $this->log_size+= strlen($message); - $this->message_log[] = $message; - while ($this->log_size > self::LOG_MAX_SIZE) { - $this->log_size-= strlen(array_shift($this->message_log)); - array_shift($this->message_number_log); - } - break; - // dump the output out realtime; packets may be interspersed with non packets, - // passwords won't be filtered out and select other packets may not be correctly - // identified - case self::LOG_REALTIME: - switch (PHP_SAPI) { - case 'cli': - $start = $stop = "\r\n"; - break; - default: - $start = '
';
-                        $stop = '
'; - } - echo $start . $this->_format_log(array($message), array($message_number)) . $stop; - @flush(); - @ob_flush(); - break; - // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE - // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. - // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily - // at the beginning of the file - case self::LOG_REALTIME_FILE: - if (!isset($this->realtime_log_file)) { - // PHP doesn't seem to like using constants in fopen() - $filename = self::LOG_REALTIME_FILENAME; - $fp = fopen($filename, 'w'); - $this->realtime_log_file = $fp; - } - if (!is_resource($this->realtime_log_file)) { - break; - } - $entry = $this->_format_log(array($message), array($message_number)); - if ($this->realtime_log_wrap) { - $temp = "<<< START >>>\r\n"; - $entry.= $temp; - fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp)); - } - $this->realtime_log_size+= strlen($entry); - if ($this->realtime_log_size > self::LOG_MAX_SIZE) { - fseek($this->realtime_log_file, 0); - $this->realtime_log_size = strlen($entry); - $this->realtime_log_wrap = true; - } - fputs($this->realtime_log_file, $entry); - } - } - - /** - * Sends channel data - * - * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate - * - * @param int $client_channel - * @param string $data - * @return bool - * @access private - */ - function _send_channel_packet($client_channel, $data) - { - while (strlen($data)) { - if (!$this->window_size_client_to_server[$client_channel]) { - $this->bitmap^= self::MASK_WINDOW_ADJUST; - // using an invalid channel will let the buffers be built up for the valid channels - $this->_get_channel_packet(-1); - $this->bitmap^= self::MASK_WINDOW_ADJUST; - } - - /* The maximum amount of data allowed is determined by the maximum - packet size for the channel, and the current window size, whichever - is smaller. - -- http://tools.ietf.org/html/rfc4254#section-5.2 */ - $max_size = min( - $this->packet_size_client_to_server[$client_channel], - $this->window_size_client_to_server[$client_channel] - ); - - $temp = $this->_string_shift($data, $max_size); - $packet = pack( - 'CN2a*', - NET_SSH2_MSG_CHANNEL_DATA, - $this->server_channels[$client_channel], - strlen($temp), - $temp - ); - $this->window_size_client_to_server[$client_channel]-= strlen($temp); - if (!$this->_send_binary_packet($packet)) { - return false; - } - } - - return true; - } - - /** - * Closes and flushes a channel - * - * \phpseclib\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server - * and for SFTP channels are presumably closed when the client disconnects. This functions is intended - * for SCP more than anything. - * - * @param int $client_channel - * @param bool $want_reply - * @return bool - * @access private - */ - function _close_channel($client_channel, $want_reply = false) - { - // see http://tools.ietf.org/html/rfc4254#section-5.3 - - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); - - if (!$want_reply) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); - } - - $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; - - $this->curTimeout = 5; - - while (!is_bool($this->_get_channel_packet($client_channel))) { - } - - if ($this->is_timeout) { - $this->disconnect(); - } - - if ($want_reply) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); - } - - if ($this->bitmap & self::MASK_SHELL) { - $this->bitmap&= ~self::MASK_SHELL; - } - } - - /** - * Disconnect - * - * @param int $reason - * @return bool - * @access private - */ - function _disconnect($reason) - { - if ($this->bitmap & self::MASK_CONNECTED) { - $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, ''); - $this->_send_binary_packet($data); - } - - $this->bitmap = 0; - if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') { - fclose($this->fsock); - } - - return false; - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } - - /** - * Define Array - * - * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of - * named constants from it, using the value as the name of the constant and the index as the value of the constant. - * If any of the constants that would be defined already exists, none of the constants will be defined. - * - * @access private - */ - function _define_array() - { - $args = func_get_args(); - foreach ($args as $arg) { - foreach ($arg as $key => $value) { - if (!defined($value)) { - define($value, $key); - } else { - break 2; - } - } - } - } - - /** - * Returns a log of the packets that have been sent and received. - * - * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') - * - * @access public - * @return array|false|string - */ - function getLog() - { - if (!defined('NET_SSH2_LOGGING')) { - return false; - } - - switch (NET_SSH2_LOGGING) { - case self::LOG_SIMPLE: - return $this->message_number_log; - case self::LOG_COMPLEX: - $log = $this->_format_log($this->message_log, $this->message_number_log); - return PHP_SAPI == 'cli' ? $log : '
' . $log . '
'; - default: - return false; - } - } - - /** - * Formats a log for printing - * - * @param array $message_log - * @param array $message_number_log - * @access private - * @return string - */ - function _format_log($message_log, $message_number_log) - { - $output = ''; - for ($i = 0; $i < count($message_log); $i++) { - $output.= $message_number_log[$i] . "\r\n"; - $current_log = $message_log[$i]; - $j = 0; - do { - if (strlen($current_log)) { - $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; - } - $fragment = $this->_string_shift($current_log, $this->log_short_width); - $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary)); - // replace non ASCII printable characters with dots - // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters - // also replace < with a . since < messes up the output on web browsers - $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); - $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; - $j++; - } while (strlen($current_log)); - $output.= "\r\n"; - } - - return $output; - } - - /** - * Helper function for _format_log - * - * For use with preg_replace_callback() - * - * @param array $matches - * @access private - * @return string - */ - function _format_log_helper($matches) - { - return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); - } - - /** - * Helper function for agent->_on_channel_open() - * - * Used when channels are created to inform agent - * of said channel opening. Must be called after - * channel open confirmation received - * - * @access private - */ - function _on_channel_open() - { - if (isset($this->agent)) { - $this->agent->_on_channel_open($this); - } - } - - /** - * Returns the first value of the intersection of two arrays or false if - * the intersection is empty. The order is defined by the first parameter. - * - * @param array $array1 - * @param array $array2 - * @return mixed False if intersection is empty, else intersected value. - * @access private - */ - function _array_intersect_first($array1, $array2) - { - foreach ($array1 as $value) { - if (in_array($value, $array2)) { - return $value; - } - } - return false; - } - - /** - * Returns all errors - * - * @return string[] - * @access public - */ - function getErrors() - { - return $this->errors; - } - - /** - * Returns the last error - * - * @return string - * @access public - */ - function getLastError() - { - $count = count($this->errors); - - if ($count > 0) { - return $this->errors[$count - 1]; - } - } - - /** - * Return the server identification. - * - * @return string - * @access public - */ - function getServerIdentification() - { - $this->_connect(); - - return $this->server_identifier; - } - - /** - * Return a list of the key exchange algorithms the server supports. - * - * @return array - * @access public - */ - function getKexAlgorithms() - { - $this->_connect(); - - return $this->kex_algorithms; - } - - /** - * Return a list of the host key (public key) algorithms the server supports. - * - * @return array - * @access public - */ - function getServerHostKeyAlgorithms() - { - $this->_connect(); - - return $this->server_host_key_algorithms; - } - - /** - * Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client. - * - * @return array - * @access public - */ - function getEncryptionAlgorithmsClient2Server() - { - $this->_connect(); - - return $this->encryption_algorithms_client_to_server; - } - - /** - * Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client. - * - * @return array - * @access public - */ - function getEncryptionAlgorithmsServer2Client() - { - $this->_connect(); - - return $this->encryption_algorithms_server_to_client; - } - - /** - * Return a list of the MAC algorithms the server supports, when receiving stuff from the client. - * - * @return array - * @access public - */ - function getMACAlgorithmsClient2Server() - { - $this->_connect(); - - return $this->mac_algorithms_client_to_server; - } - - /** - * Return a list of the MAC algorithms the server supports, when sending stuff to the client. - * - * @return array - * @access public - */ - function getMACAlgorithmsServer2Client() - { - $this->_connect(); - - return $this->mac_algorithms_server_to_client; - } - - /** - * Return a list of the compression algorithms the server supports, when receiving stuff from the client. - * - * @return array - * @access public - */ - function getCompressionAlgorithmsClient2Server() - { - $this->_connect(); - - return $this->compression_algorithms_client_to_server; - } - - /** - * Return a list of the compression algorithms the server supports, when sending stuff to the client. - * - * @return array - * @access public - */ - function getCompressionAlgorithmsServer2Client() - { - $this->_connect(); - - return $this->compression_algorithms_server_to_client; - } - - /** - * Return a list of the languages the server supports, when sending stuff to the client. - * - * @return array - * @access public - */ - function getLanguagesServer2Client() - { - $this->_connect(); - - return $this->languages_server_to_client; - } - - /** - * Return a list of the languages the server supports, when receiving stuff from the client. - * - * @return array - * @access public - */ - function getLanguagesClient2Server() - { - $this->_connect(); - - return $this->languages_client_to_server; - } - - /** - * Returns a list of algorithms the server supports - * - * @return array - * @access public - */ - function getServerAlgorithms() - { - $this->_connect(); - - return array( - 'kex' => $this->kex_algorithms, - 'hostkey' => $this->server_host_key_algorithms, - 'client_to_server' => array( - 'crypt' => $this->encryption_algorithms_client_to_server, - 'mac' => $this->mac_algorithms_client_to_server, - 'comp' => $this->compression_algorithms_client_to_server, - 'lang' => $this->languages_client_to_server - ), - 'server_to_client' => array( - 'crypt' => $this->encryption_algorithms_server_to_client, - 'mac' => $this->mac_algorithms_server_to_client, - 'comp' => $this->compression_algorithms_server_to_client, - 'lang' => $this->languages_server_to_client - ) - ); - } - - /** - * Returns a list of KEX algorithms that phpseclib supports - * - * @return array - * @access public - */ - function getSupportedKEXAlgorithms() - { - $kex_algorithms = array( - // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using - // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the - // libssh repository for more information. - 'curve25519-sha256@libssh.org', - - 'diffie-hellman-group-exchange-sha256',// RFC 4419 - 'diffie-hellman-group-exchange-sha1', // RFC 4419 - - // Diffie-Hellman Key Agreement (DH) using integer modulo prime - // groups. - 'diffie-hellman-group14-sha1', // REQUIRED - 'diffie-hellman-group1-sha1', // REQUIRED - ); - - if (!function_exists('sodium_crypto_box_publickey_from_secretkey')) { - $kex_algorithms = array_diff( - $kex_algorithms, - array('curve25519-sha256@libssh.org') - ); - } - - return $kex_algorithms; - } - - /** - * Returns a list of host key algorithms that phpseclib supports - * - * @return array - * @access public - */ - function getSupportedHostKeyAlgorithms() - { - return array( - 'rsa-sha2-256', // RFC 8332 - 'rsa-sha2-512', // RFC 8332 - 'ssh-rsa', // RECOMMENDED sign Raw RSA Key - 'ssh-dss' // REQUIRED sign Raw DSS Key - ); - } - - /** - * Returns a list of symmetric key algorithms that phpseclib supports - * - * @return array - * @access public - */ - function getSupportedEncryptionAlgorithms() - { - $algos = array( - // from : - 'arcfour256', - 'arcfour128', - - //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key - - // CTR modes from : - 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key - 'aes192-ctr', // RECOMMENDED AES with 192-bit key - 'aes256-ctr', // RECOMMENDED AES with 256-bit key - - 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key - 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key - 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key - - 'aes128-cbc', // RECOMMENDED AES with a 128-bit key - 'aes192-cbc', // OPTIONAL AES with a 192-bit key - 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key - - 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key - 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key - 'twofish256-cbc', - 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc" - // (this is being retained for historical reasons) - - 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode - - 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode - - '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode - - '3des-cbc', // REQUIRED three-key 3DES in CBC mode - - //'none' // OPTIONAL no encryption; NOT RECOMMENDED - ); - - if ($this->crypto_engine) { - $engines = array($this->crypto_engine); - } else { - $engines = array( - Base::ENGINE_OPENSSL, - Base::ENGINE_MCRYPT, - Base::ENGINE_INTERNAL - ); - } - - $ciphers = array(); - foreach ($engines as $engine) { - foreach ($algos as $algo) { - $obj = $this->_encryption_algorithm_to_crypt_instance($algo); - if ($obj instanceof Rijndael) { - $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); - } - switch ($algo) { - case 'arcfour128': - case 'arcfour256': - if ($engine != Base::ENGINE_INTERNAL) { - continue 2; - } - } - if ($obj->isValidEngine($engine)) { - $algos = array_diff($algos, array($algo)); - $ciphers[] = $algo; - } - } - } - - return $ciphers; - } - - /** - * Returns a list of MAC algorithms that phpseclib supports - * - * @return array - * @access public - */ - function getSupportedMACAlgorithms() - { - return array( - // from : - 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) - - 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) - 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) - 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) - 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) - //'none' // OPTIONAL no MAC; NOT RECOMMENDED - ); - } - - /** - * Returns a list of compression algorithms that phpseclib supports - * - * @return array - * @access public - */ - function getSupportedCompressionAlgorithms() - { - $algos = array('none'); // REQUIRED no compression - if (function_exists('deflate_init')) { - $algos[] = 'zlib@openssh.com'; // https://datatracker.ietf.org/doc/html/draft-miller-secsh-compression-delayed - $algos[] = 'zlib'; - } - return $algos; - } - - /** - * Return list of negotiated algorithms - * - * Uses the same format as https://www.php.net/ssh2-methods-negotiated - * - * @return array - * @access public - */ - function getAlgorithmsNegotiated() - { - $this->_connect(); - - $compression_map = array( - NET_SSH2_COMPRESSION_NONE => 'none', - NET_SSH2_COMPRESSION_ZLIB => 'zlib', - NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com' - ); - - return array( - 'kex' => $this->kex_algorithm, - 'hostkey' => $this->signature_format, - 'client_to_server' => array( - 'crypt' => $this->encrypt->name, - 'mac' => $this->hmac_create->name, - 'comp' => $compression_map[$this->compress], - ), - 'server_to_client' => array( - 'crypt' => $this->decrypt->name, - 'mac' => $this->hmac_check->name, - 'comp' => $compression_map[$this->decompress], - ) - ); - } - - /** - * Accepts an associative array with up to four parameters as described at - * - * - * @param array $methods - * @access public - */ - function setPreferredAlgorithms($methods) - { - $preferred = $methods; - - if (isset($preferred['kex'])) { - $preferred['kex'] = array_intersect( - $preferred['kex'], - $this->getSupportedKEXAlgorithms() - ); - } - - if (isset($preferred['hostkey'])) { - $preferred['hostkey'] = array_intersect( - $preferred['hostkey'], - $this->getSupportedHostKeyAlgorithms() - ); - } - - $keys = array('client_to_server', 'server_to_client'); - foreach ($keys as $key) { - if (isset($preferred[$key])) { - $a = &$preferred[$key]; - if (isset($a['crypt'])) { - $a['crypt'] = array_intersect( - $a['crypt'], - $this->getSupportedEncryptionAlgorithms() - ); - } - if (isset($a['comp'])) { - $a['comp'] = array_intersect( - $a['comp'], - $this->getSupportedCompressionAlgorithms() - ); - } - if (isset($a['mac'])) { - $a['mac'] = array_intersect( - $a['mac'], - $this->getSupportedMACAlgorithms() - ); - } - } - } - - $keys = array( - 'kex', - 'hostkey', - 'client_to_server/crypt', - 'client_to_server/comp', - 'client_to_server/mac', - 'server_to_client/crypt', - 'server_to_client/comp', - 'server_to_client/mac', - ); - foreach ($keys as $key) { - $p = $preferred; - $m = $methods; - - $subkeys = explode('/', $key); - foreach ($subkeys as $subkey) { - if (!isset($p[$subkey])) { - continue 2; - } - $p = $p[$subkey]; - $m = $m[$subkey]; - } - - if (count($p) != count($m)) { - $diff = array_diff($m, $p); - $msg = count($diff) == 1 ? - ' is not a supported algorithm' : - ' are not supported algorithms'; - user_error(implode(', ', $diff) . $msg); - return false; - } - } - - $this->preferred = $preferred; - } - - /** - * Returns the banner message. - * - * Quoting from the RFC, "in some jurisdictions, sending a warning message before - * authentication may be relevant for getting legal protection." - * - * @return string - * @access public - */ - function getBannerMessage() - { - return $this->banner_message; - } - - /** - * Returns the server public host key. - * - * Caching this the first time you connect to a server and checking the result on subsequent connections - * is recommended. Returns false if the server signature is not signed correctly with the public host key. - * - * @return mixed - * @access public - */ - function getServerPublicHostKey() - { - if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - if (!$this->_connect()) { - return false; - } - } - - $signature = $this->signature; - $server_public_host_key = $this->server_public_host_key; - - if (strlen($server_public_host_key) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4))); - $this->_string_shift($server_public_host_key, $length); - - if ($this->signature_validated) { - return $this->bitmap ? - $this->signature_format . ' ' . base64_encode($this->server_public_host_key) : - false; - } - - $this->signature_validated = true; - - switch ($this->signature_format) { - case 'ssh-dss': - $zero = new BigInteger(); - - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $p = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); - - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $q = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); - - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $g = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); - - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $y = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); - - /* The value for 'dss_signature_blob' is encoded as a string containing - r, followed by s (which are 160-bit integers, without lengths or - padding, unsigned, and in network byte order). */ - $temp = unpack('Nlength', $this->_string_shift($signature, 4)); - if ($temp['length'] != 40) { - user_error('Invalid signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $r = new BigInteger($this->_string_shift($signature, 20), 256); - $s = new BigInteger($this->_string_shift($signature, 20), 256); - - switch (true) { - case $r->equals($zero): - case $r->compare($q) >= 0: - case $s->equals($zero): - case $s->compare($q) >= 0: - user_error('Invalid signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $w = $s->modInverse($q); - - $u1 = $w->multiply(new BigInteger(sha1($this->exchange_hash), 16)); - list(, $u1) = $u1->divide($q); - - $u2 = $w->multiply($r); - list(, $u2) = $u2->divide($q); - - $g = $g->modPow($u1, $p); - $y = $y->modPow($u2, $p); - - $v = $g->multiply($y); - list(, $v) = $v->divide($p); - list(, $v) = $v->divide($q); - - if (!$v->equals($r)) { - user_error('Bad server signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - } - - break; - case 'ssh-rsa': - case 'rsa-sha2-256': - case 'rsa-sha2-512': - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $e = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256); - - if (strlen($server_public_host_key) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4)); - $rawN = $this->_string_shift($server_public_host_key, $temp['length']); - $n = new BigInteger($rawN, -256); - $nLength = strlen(ltrim($rawN, "\0")); - - /* - if (strlen($signature) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($signature, 4)); - $signature = $this->_string_shift($signature, $temp['length']); - - $rsa = new RSA(); - switch ($this->signature_format) { - case 'rsa-sha2-512': - $hash = 'sha512'; - break; - case 'rsa-sha2-256': - $hash = 'sha256'; - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - } - $rsa->setHash($hash); - $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); - $rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW); - - if (!$rsa->verify($this->exchange_hash, $signature)) { - user_error('Bad server signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - } - */ - - if (strlen($signature) < 4) { - return false; - } - $temp = unpack('Nlength', $this->_string_shift($signature, 4)); - $s = new BigInteger($this->_string_shift($signature, $temp['length']), 256); - - // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the - // following URL: - // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf - - // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source. - - if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) { - user_error('Invalid signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - - $s = $s->modPow($e, $n); - $s = $s->toBytes(); - - switch ($this->signature_format) { - case 'rsa-sha2-512': - $hash = 'sha512'; - break; - case 'rsa-sha2-256': - $hash = 'sha256'; - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - } - $hashObj = new Hash($hash); - switch ($this->signature_format) { - case 'rsa-sha2-512': - $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash)); - break; - case 'rsa-sha2-256': - $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash)); - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash)); - } - $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h; - - if ($s != $h) { - user_error('Bad server signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - } - break; - default: - user_error('Unsupported signature format'); - return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - } - - return $this->signature_format . ' ' . base64_encode($this->server_public_host_key); - } - - /** - * Returns the exit status of an SSH command or false. - * - * @return false|int - * @access public - */ - function getExitStatus() - { - if (is_null($this->exit_status)) { - return false; - } - return $this->exit_status; - } - - /** - * Returns the number of columns for the terminal window size. - * - * @return int - * @access public - */ - function getWindowColumns() - { - return $this->windowColumns; - } - - /** - * Returns the number of rows for the terminal window size. - * - * @return int - * @access public - */ - function getWindowRows() - { - return $this->windowRows; - } - - /** - * Sets the number of columns for the terminal window size. - * - * @param int $value - * @access public - */ - function setWindowColumns($value) - { - $this->windowColumns = $value; - } - - /** - * Sets the number of rows for the terminal window size. - * - * @param int $value - * @access public - */ - function setWindowRows($value) - { - $this->windowRows = $value; - } - - /** - * Sets the number of columns and rows for the terminal window size. - * - * @param int $columns - * @param int $rows - * @access public - */ - function setWindowSize($columns = 80, $rows = 24) - { - $this->windowColumns = $columns; - $this->windowRows = $rows; - } - - /** - * Update packet types in log history - * - * @param string $old - * @param string $new - * @access private - */ - function _updateLogHistory($old, $new) - { - if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { - $this->message_number_log[count($this->message_number_log) - 1] = str_replace( - $old, - $new, - $this->message_number_log[count($this->message_number_log) - 1] - ); - } - } - - /** - * Return the list of authentication methods that may productively continue authentication. - * - * @see https://tools.ietf.org/html/rfc4252#section-5.1 - * @return array|null - */ - function getAuthMethodsToContinue() - { - return $this->auth_methods_to_continue; - } - - /** - * Enables "smart" multi-factor authentication (MFA) - */ - function enableSmartMFA() - { - $this->smartMFA = true; - } - - /** - * Disables "smart" multi-factor authentication (MFA) - */ - function disableSmartMFA() - { - $this->smartMFA = false; - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php deleted file mode 100644 index 2b25250bd..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php +++ /dev/null @@ -1,351 +0,0 @@ - - * login('username', $agent)) { - * exit('Login Failed'); - * } - * - * echo $ssh->exec('pwd'); - * echo $ssh->exec('ls -la'); - * ?> - * - * - * @category System - * @package SSH\Agent - * @author Jim Wigginton - * @copyright 2014 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - * @internal See http://api.libssh.org/rfc/PROTOCOL.agent - */ - -namespace phpseclib\System\SSH; - -use phpseclib\Crypt\RSA; -use phpseclib\System\SSH\Agent\Identity; - -/** - * Pure-PHP ssh-agent client identity factory - * - * requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects - * - * @package SSH\Agent - * @author Jim Wigginton - * @access public - */ -class Agent -{ - /**#@+ - * Message numbers - * - * @access private - */ - // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) - const SSH_AGENTC_REQUEST_IDENTITIES = 11; - // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). - const SSH_AGENT_IDENTITIES_ANSWER = 12; - // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) - const SSH_AGENTC_SIGN_REQUEST = 13; - // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) - const SSH_AGENT_SIGN_RESPONSE = 14; - /**#@-*/ - - /**@+ - * Agent forwarding status - * - * @access private - */ - // no forwarding requested and not active - const FORWARD_NONE = 0; - // request agent forwarding when opportune - const FORWARD_REQUEST = 1; - // forwarding has been request and is active - const FORWARD_ACTIVE = 2; - /**#@-*/ - - /** - * Unused - */ - const SSH_AGENT_FAILURE = 5; - - /** - * Socket Resource - * - * @var resource - * @access private - */ - var $fsock; - - /** - * Agent forwarding status - * - * @access private - */ - var $forward_status = self::FORWARD_NONE; - - /** - * Buffer for accumulating forwarded authentication - * agent data arriving on SSH data channel destined - * for agent unix socket - * - * @access private - */ - var $socket_buffer = ''; - - /** - * Tracking the number of bytes we are expecting - * to arrive for the agent socket on the SSH data - * channel - */ - var $expected_bytes = 0; - - /** - * Default Constructor - * - * @return \phpseclib\System\SSH\Agent - * @access public - */ - function __construct($address = null) - { - if (!$address) { - switch (true) { - case isset($_SERVER['SSH_AUTH_SOCK']): - $address = $_SERVER['SSH_AUTH_SOCK']; - break; - case isset($_ENV['SSH_AUTH_SOCK']): - $address = $_ENV['SSH_AUTH_SOCK']; - break; - default: - user_error('SSH_AUTH_SOCK not found'); - return false; - } - } - - $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); - if (!$this->fsock) { - user_error("Unable to connect to ssh-agent (Error $errno: $errstr)"); - } - } - - /** - * Request Identities - * - * See "2.5.2 Requesting a list of protocol 2 keys" - * Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects - * - * @return array - * @access public - */ - function requestIdentities() - { - if (!$this->fsock) { - return array(); - } - - $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); - if (strlen($packet) != fputs($this->fsock, $packet)) { - user_error('Connection closed while requesting identities'); - return array(); - } - - $temp = fread($this->fsock, 4); - if (strlen($temp) != 4) { - user_error('Connection closed while requesting identities'); - return array(); - } - $length = current(unpack('N', $temp)); - $type = ord(fread($this->fsock, 1)); - if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { - user_error('Unable to request identities'); - return array(); - } - - $identities = array(); - $temp = fread($this->fsock, 4); - if (strlen($temp) != 4) { - user_error('Connection closed while requesting identities'); - return array(); - } - $keyCount = current(unpack('N', $temp)); - for ($i = 0; $i < $keyCount; $i++) { - $temp = fread($this->fsock, 4); - if (strlen($temp) != 4) { - user_error('Connection closed while requesting identities'); - return array(); - } - $length = current(unpack('N', $temp)); - $key_blob = fread($this->fsock, $length); - if (strlen($key_blob) != $length) { - user_error('Connection closed while requesting identities'); - return array(); - } - $key_str = 'ssh-rsa ' . base64_encode($key_blob); - $temp = fread($this->fsock, 4); - if (strlen($temp) != 4) { - user_error('Connection closed while requesting identities'); - return array(); - } - $length = current(unpack('N', $temp)); - if ($length) { - $temp = fread($this->fsock, $length); - if (strlen($temp) != $length) { - user_error('Connection closed while requesting identities'); - return array(); - } - $key_str.= ' ' . $temp; - } - $length = current(unpack('N', substr($key_blob, 0, 4))); - $key_type = substr($key_blob, 4, $length); - switch ($key_type) { - case 'ssh-rsa': - $key = new RSA(); - $key->loadKey($key_str); - break; - case 'ssh-dss': - // not currently supported - break; - } - // resources are passed by reference by default - if (isset($key)) { - $identity = new Identity($this->fsock); - $identity->setPublicKey($key); - $identity->setPublicKeyBlob($key_blob); - $identities[] = $identity; - unset($key); - } - } - - return $identities; - } - - /** - * Signal that agent forwarding should - * be requested when a channel is opened - * - * @param Net_SSH2 $ssh - * @return bool - * @access public - */ - function startSSHForwarding($ssh) - { - if ($this->forward_status == self::FORWARD_NONE) { - $this->forward_status = self::FORWARD_REQUEST; - } - } - - /** - * Request agent forwarding of remote server - * - * @param Net_SSH2 $ssh - * @return bool - * @access private - */ - function _request_forwarding($ssh) - { - $request_channel = $ssh->_get_open_channel(); - if ($request_channel === false) { - return false; - } - - $packet = pack( - 'CNNa*C', - NET_SSH2_MSG_CHANNEL_REQUEST, - $ssh->server_channels[$request_channel], - strlen('auth-agent-req@openssh.com'), - 'auth-agent-req@openssh.com', - 1 - ); - - $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; - - if (!$ssh->_send_binary_packet($packet)) { - return false; - } - - $response = $ssh->_get_channel_packet($request_channel); - if ($response === false) { - return false; - } - - $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; - $this->forward_status = self::FORWARD_ACTIVE; - - return true; - } - - /** - * On successful channel open - * - * This method is called upon successful channel - * open to give the SSH Agent an opportunity - * to take further action. i.e. request agent forwarding - * - * @param Net_SSH2 $ssh - * @access private - */ - function _on_channel_open($ssh) - { - if ($this->forward_status == self::FORWARD_REQUEST) { - $this->_request_forwarding($ssh); - } - } - - /** - * Forward data to SSH Agent and return data reply - * - * @param string $data - * @return data from SSH Agent - * @access private - */ - function _forward_data($data) - { - if ($this->expected_bytes > 0) { - $this->socket_buffer.= $data; - $this->expected_bytes -= strlen($data); - } else { - $agent_data_bytes = current(unpack('N', $data)); - $current_data_bytes = strlen($data); - $this->socket_buffer = $data; - if ($current_data_bytes != $agent_data_bytes + 4) { - $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes; - return false; - } - } - - if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { - user_error('Connection closed attempting to forward data to SSH agent'); - return false; - } - - $this->socket_buffer = ''; - $this->expected_bytes = 0; - - $temp = fread($this->fsock, 4); - if (strlen($temp) != 4) { - user_error('Connection closed while reading data response'); - return false; - } - $agent_reply_bytes = current(unpack('N', $temp)); - - $agent_reply_data = fread($this->fsock, $agent_reply_bytes); - if (strlen($agent_reply_data) != $agent_reply_bytes) { - user_error('Connection closed while reading data response'); - return false; - } - $agent_reply_data = current(unpack('a*', $agent_reply_data)); - - return pack('Na*', $agent_reply_bytes, $agent_reply_data); - } -} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php deleted file mode 100644 index 68b6bfdfa..000000000 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - * @internal See http://api.libssh.org/rfc/PROTOCOL.agent - */ - -namespace phpseclib\System\SSH\Agent; - -use phpseclib\System\SSH\Agent; - -/** - * Pure-PHP ssh-agent client identity object - * - * Instantiation should only be performed by \phpseclib\System\SSH\Agent class. - * This could be thought of as implementing an interface that phpseclib\Crypt\RSA - * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. - * The methods in this interface would be getPublicKey and sign since those are the - * methods phpseclib looks for to perform public key authentication. - * - * @package SSH\Agent - * @author Jim Wigginton - * @access internal - */ -class Identity -{ - /**@+ - * Signature Flags - * - * See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 - * - * @access private - */ - const SSH_AGENT_RSA2_256 = 2; - const SSH_AGENT_RSA2_512 = 4; - /**#@-*/ - - /** - * Key Object - * - * @var \phpseclib\Crypt\RSA - * @access private - * @see self::getPublicKey() - */ - var $key; - - /** - * Key Blob - * - * @var string - * @access private - * @see self::sign() - */ - var $key_blob; - - /** - * Socket Resource - * - * @var resource - * @access private - * @see self::sign() - */ - var $fsock; - - /** - * Signature flags - * - * @var int - * @access private - * @see self::sign() - * @see self::setHash() - */ - var $flags = 0; - - /** - * Default Constructor. - * - * @param resource $fsock - * @return \phpseclib\System\SSH\Agent\Identity - * @access private - */ - function __construct($fsock) - { - $this->fsock = $fsock; - } - - /** - * Set Public Key - * - * Called by \phpseclib\System\SSH\Agent::requestIdentities() - * - * @param \phpseclib\Crypt\RSA $key - * @access private - */ - function setPublicKey($key) - { - $this->key = $key; - $this->key->setPublicKey(); - } - - /** - * Set Public Key - * - * Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key - * but this saves a small amount of computation. - * - * @param string $key_blob - * @access private - */ - function setPublicKeyBlob($key_blob) - { - $this->key_blob = $key_blob; - } - - /** - * Get Public Key - * - * Wrapper for $this->key->getPublicKey() - * - * @param int $format optional - * @return mixed - * @access public - */ - function getPublicKey($format = null) - { - return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format); - } - - /** - * Set Signature Mode - * - * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie. - * ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1 - * - * @param int $mode - * @access public - */ - function setSignatureMode($mode) - { - } - - /** - * Set Hash - * - * ssh-agent doesn't support using hashes for RSA other than SHA1 - * - * @param string $hash - * @access public - */ - function setHash($hash) - { - $this->flags = 0; - switch ($hash) { - case 'sha1': - break; - case 'sha256': - $this->flags = self::SSH_AGENT_RSA2_256; - break; - case 'sha512': - $this->flags = self::SSH_AGENT_RSA2_512; - break; - default: - user_error('The only supported hashes for RSA are sha1, sha256 and sha512'); - } - } - - /** - * Create a signature - * - * See "2.6.2 Protocol 2 private key signature request" - * - * @param string $message - * @return string - * @access public - */ - function sign($message) - { - // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE - $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags); - $packet = pack('Na*', strlen($packet), $packet); - if (strlen($packet) != fputs($this->fsock, $packet)) { - user_error('Connection closed during signing'); - return false; - } - - $temp = fread($this->fsock, 4); - if (strlen($temp) != 4) { - user_error('Connection closed during signing'); - return false; - } - $length = current(unpack('N', $temp)); - $type = ord(fread($this->fsock, 1)); - if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { - user_error('Unable to retrieve signature'); - return false; - } - - $signature_blob = fread($this->fsock, $length - 1); - if (strlen($signature_blob) != $length - 1) { - user_error('Connection closed during signing'); - return false; - } - $length = current(unpack('N', $this->_string_shift($signature_blob, 4))); - if ($length != strlen($signature_blob)) { - user_error('Malformed signature blob'); - } - $length = current(unpack('N', $this->_string_shift($signature_blob, 4))); - if ($length > strlen($signature_blob) + 4) { - user_error('Malformed signature blob'); - } - $type = $this->_string_shift($signature_blob, $length); - $this->_string_shift($signature_blob, 4); - - return $signature_blob; - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } -} diff --git a/libraries/phpseclib3/index.html b/libraries/phpseclib3/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/phpseclib3/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/phpseclib/vendor/.htaccess b/libraries/phpseclib3/vendor/.htaccess similarity index 100% rename from libraries/phpseclib/vendor/.htaccess rename to libraries/phpseclib3/vendor/.htaccess diff --git a/libraries/phpseclib/vendor/autoload.php b/libraries/phpseclib3/vendor/autoload.php similarity index 64% rename from libraries/phpseclib/vendor/autoload.php rename to libraries/phpseclib3/vendor/autoload.php index 87a2a0a05..bb12cfd93 100644 --- a/libraries/phpseclib/vendor/autoload.php +++ b/libraries/phpseclib3/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4::getLoader(); +return ComposerAutoloaderInit702c2783321e592c0d762284b651595c::getLoader(); diff --git a/libraries/phpseclib/vendor/composer/ClassLoader.php b/libraries/phpseclib3/vendor/composer/ClassLoader.php similarity index 99% rename from libraries/phpseclib/vendor/composer/ClassLoader.php rename to libraries/phpseclib3/vendor/composer/ClassLoader.php index 0cd6055d1..afef3fa2a 100644 --- a/libraries/phpseclib/vendor/composer/ClassLoader.php +++ b/libraries/phpseclib3/vendor/composer/ClassLoader.php @@ -149,7 +149,7 @@ class ClassLoader /** * @return string[] Array of classname => path - * @psalm-var array + * @psalm-return array */ public function getClassMap() { diff --git a/libraries/phpseclib/vendor/composer/InstalledVersions.php b/libraries/phpseclib3/vendor/composer/InstalledVersions.php similarity index 100% rename from libraries/phpseclib/vendor/composer/InstalledVersions.php rename to libraries/phpseclib3/vendor/composer/InstalledVersions.php diff --git a/libraries/phpseclib/vendor/composer/LICENSE b/libraries/phpseclib3/vendor/composer/LICENSE similarity index 99% rename from libraries/phpseclib/vendor/composer/LICENSE rename to libraries/phpseclib3/vendor/composer/LICENSE index f27399a04..62ecfd8d0 100644 --- a/libraries/phpseclib/vendor/composer/LICENSE +++ b/libraries/phpseclib3/vendor/composer/LICENSE @@ -1,4 +1,3 @@ - Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy @@ -18,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/libraries/phpseclib/vendor/composer/autoload_classmap.php b/libraries/phpseclib3/vendor/composer/autoload_classmap.php similarity index 100% rename from libraries/phpseclib/vendor/composer/autoload_classmap.php rename to libraries/phpseclib3/vendor/composer/autoload_classmap.php diff --git a/libraries/phpseclib/vendor/composer/autoload_files.php b/libraries/phpseclib3/vendor/composer/autoload_files.php similarity index 100% rename from libraries/phpseclib/vendor/composer/autoload_files.php rename to libraries/phpseclib3/vendor/composer/autoload_files.php diff --git a/libraries/phpseclib/vendor/composer/autoload_namespaces.php b/libraries/phpseclib3/vendor/composer/autoload_namespaces.php similarity index 100% rename from libraries/phpseclib/vendor/composer/autoload_namespaces.php rename to libraries/phpseclib3/vendor/composer/autoload_namespaces.php diff --git a/libraries/phpseclib3/vendor/composer/autoload_psr4.php b/libraries/phpseclib3/vendor/composer/autoload_psr4.php new file mode 100644 index 000000000..c12a8d7f2 --- /dev/null +++ b/libraries/phpseclib3/vendor/composer/autoload_psr4.php @@ -0,0 +1,11 @@ + array($vendorDir . '/phpseclib/phpseclib/phpseclib'), + 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), +); diff --git a/libraries/phpseclib/vendor/composer/autoload_real.php b/libraries/phpseclib3/vendor/composer/autoload_real.php similarity index 76% rename from libraries/phpseclib/vendor/composer/autoload_real.php rename to libraries/phpseclib3/vendor/composer/autoload_real.php index bd5b5f004..d18002467 100644 --- a/libraries/phpseclib/vendor/composer/autoload_real.php +++ b/libraries/phpseclib3/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4 +class ComposerAutoloaderInit702c2783321e592c0d762284b651595c { private static $loader; @@ -24,15 +24,15 @@ class ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4 require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit702c2783321e592c0d762284b651595c', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit702c2783321e592c0d762284b651595c', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit10d22a526bd476954b93748a871e7ad4::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit702c2783321e592c0d762284b651595c::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -53,23 +53,28 @@ class ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit702c2783321e592c0d762284b651595c::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire10d22a526bd476954b93748a871e7ad4($fileIdentifier, $file); + composerRequire702c2783321e592c0d762284b651595c($fileIdentifier, $file); } return $loader; } } -function composerRequire10d22a526bd476954b93748a871e7ad4($fileIdentifier, $file) +/** + * @param string $fileIdentifier + * @param string $file + * @return void + */ +function composerRequire702c2783321e592c0d762284b651595c($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; } } diff --git a/libraries/phpseclib/vendor/composer/autoload_static.php b/libraries/phpseclib3/vendor/composer/autoload_static.php similarity index 54% rename from libraries/phpseclib/vendor/composer/autoload_static.php rename to libraries/phpseclib3/vendor/composer/autoload_static.php index e4fa4644c..d1192e195 100644 --- a/libraries/phpseclib/vendor/composer/autoload_static.php +++ b/libraries/phpseclib3/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit10d22a526bd476954b93748a871e7ad4 +class ComposerStaticInit702c2783321e592c0d762284b651595c { public static $files = array ( 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', @@ -13,15 +13,23 @@ class ComposerStaticInit10d22a526bd476954b93748a871e7ad4 public static $prefixLengthsPsr4 = array ( 'p' => array ( - 'phpseclib\\' => 10, + 'phpseclib3\\' => 11, + ), + 'P' => + array ( + 'ParagonIE\\ConstantTime\\' => 23, ), ); public static $prefixDirsPsr4 = array ( - 'phpseclib\\' => + 'phpseclib3\\' => array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), + 'ParagonIE\\ConstantTime\\' => + array ( + 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', + ), ); public static $classMap = array ( @@ -31,9 +39,9 @@ class ComposerStaticInit10d22a526bd476954b93748a871e7ad4 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit702c2783321e592c0d762284b651595c::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit702c2783321e592c0d762284b651595c::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit702c2783321e592c0d762284b651595c::$classMap; }, null, ClassLoader::class); } diff --git a/libraries/phpseclib3/vendor/composer/installed.json b/libraries/phpseclib3/vendor/composer/installed.json new file mode 100644 index 000000000..e1f5d8705 --- /dev/null +++ b/libraries/phpseclib3/vendor/composer/installed.json @@ -0,0 +1,242 @@ +{ + "packages": [ + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "version_normalized": "2.6.3.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "time": "2022-06-14T06:56:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "install-path": "../paragonie/constant_time_encoding" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "version_normalized": "9.99.100.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2020-10-15T08:29:30+00:00", + "type": "library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "install-path": "../paragonie/random_compat" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.33", + "version_normalized": "3.0.33.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "33fa69b2514a61138dd48e7a49f99445711e0ad0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/33fa69b2514a61138dd48e7a49f99445711e0ad0", + "reference": "33fa69b2514a61138dd48e7a49f99445711e0ad0", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "time": "2023-10-21T14:00:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-JĂŒrgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.33" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "install-path": "../phpseclib/phpseclib" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/libraries/phpseclib3/vendor/composer/installed.php b/libraries/phpseclib3/vendor/composer/installed.php new file mode 100644 index 000000000..a9ca29ef5 --- /dev/null +++ b/libraries/phpseclib3/vendor/composer/installed.php @@ -0,0 +1,50 @@ + array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'name' => '__root__', + 'dev' => true, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'dev_requirement' => false, + ), + 'paragonie/constant_time_encoding' => array( + 'pretty_version' => 'v2.6.3', + 'version' => '2.6.3.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', + 'aliases' => array(), + 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', + 'dev_requirement' => false, + ), + 'paragonie/random_compat' => array( + 'pretty_version' => 'v9.99.100', + 'version' => '9.99.100.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/random_compat', + 'aliases' => array(), + 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', + 'dev_requirement' => false, + ), + 'phpseclib/phpseclib' => array( + 'pretty_version' => '3.0.33', + 'version' => '3.0.33.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpseclib/phpseclib', + 'aliases' => array(), + 'reference' => '33fa69b2514a61138dd48e7a49f99445711e0ad0', + 'dev_requirement' => false, + ), + ), +); diff --git a/libraries/phpseclib/vendor/composer/platform_check.php b/libraries/phpseclib3/vendor/composer/platform_check.php similarity index 90% rename from libraries/phpseclib/vendor/composer/platform_check.php rename to libraries/phpseclib3/vendor/composer/platform_check.php index 7f0d16c70..f79e574be 100644 --- a/libraries/phpseclib/vendor/composer/platform_check.php +++ b/libraries/phpseclib3/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 50303)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 5.3.3". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 70000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/libraries/phpseclib/vendor/htaccess.txt b/libraries/phpseclib3/vendor/htaccess.txt similarity index 100% rename from libraries/phpseclib/vendor/htaccess.txt rename to libraries/phpseclib3/vendor/htaccess.txt diff --git a/libraries/phpseclib3/vendor/index.html b/libraries/phpseclib3/vendor/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/phpseclib3/vendor/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/LICENSE.txt b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/LICENSE.txt new file mode 100644 index 000000000..91acaca67 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/LICENSE.txt @@ -0,0 +1,48 @@ +The MIT License (MIT) + +Copyright (c) 2016 - 2022 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ +This library was based on the work of Steve "Sc00bz" Thomas. +------------------------------------------------------------------------------ + +The MIT License (MIT) + +Copyright (c) 2014 Steve Thomas + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/README.md b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/README.md new file mode 100644 index 000000000..cedddd863 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/README.md @@ -0,0 +1,84 @@ +# Constant-Time Encoding + +[![Build Status](https://github.com/paragonie/constant_time_encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions) +[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) + +Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), +this library aims to offer character encoding functions that do not leak +information about what you are encoding/decoding via processor cache +misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). + +Our fork offers the following enchancements: + +* `mbstring.func_overload` resistance +* Unit tests +* Composer- and Packagist-ready +* Base16 encoding +* Base32 encoding +* Uses `pack()` and `unpack()` instead of `chr()` and `ord()` + +## PHP Version Requirements + +Version 2 of this library should work on **PHP 7** or newer. For PHP 5 +support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). + +If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`. + +## How to Install + +```sh +composer require paragonie/constant_time_encoding +``` + +## How to Use + +```php +use ParagonIE\ConstantTime\Encoding; + +// possibly (if applicable): +// require 'vendor/autoload.php'; + +$data = random_bytes(32); +echo Encoding::base64Encode($data), "\n"; +echo Encoding::base32EncodeUpper($data), "\n"; +echo Encoding::base32Encode($data), "\n"; +echo Encoding::hexEncode($data), "\n"; +echo Encoding::hexEncodeUpper($data), "\n"; +``` + +Example output: + +``` +1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= +2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== +2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== +d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 +D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 +``` + +If you only need a particular variant, you can just reference the +required class like so: + +```php +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Base32; + +$data = random_bytes(32); +echo Base64::encode($data), "\n"; +echo Base32::encode($data), "\n"; +``` + +Example output: + +``` +1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= +2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== +``` + +## Support Contracts + +If your company uses this library in their products or services, you may be +interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/composer.json b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/composer.json new file mode 100644 index 000000000..2fe9717ad --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/composer.json @@ -0,0 +1,56 @@ +{ + "name": "paragonie/constant_time_encoding", + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base64", + "encoding", + "rfc4648", + "base32", + "base16", + "hex", + "bin2hex", + "hex2bin", + "base64_encode", + "base64_decode", + "base32_encode", + "base32_decode" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "support": { + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "ParagonIE\\ConstantTime\\Tests\\": "tests/" + } + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base32.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base32.php new file mode 100644 index 000000000..7508b3df6 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base32.php @@ -0,0 +1,519 @@ + 96 && $src < 123) $ret += $src - 97 + 1; // -64 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); + + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src): int + { + $ret = -1; + + // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src): string + { + $diff = 0x61; + + // if ($src > 25) $ret -= 72; + $diff -= ((25 - $src) >> 8) & 73; + + return \pack('C', $src + $diff); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $ret -= 40; + $diff -= ((25 - $src) >> 8) & 41; + + return \pack('C', $src + $diff); + } + + /** + * @param string $encodedString + * @param bool $upper + * @return string + */ + public static function decodeNoPadding(string $encodedString, bool $upper = false): string + { + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7 && $j < $srcLen; ++$j) { + if ($encodedString[$srcLen - $j - 1] === '=') { + throw new InvalidArgumentException( + "decodeNoPadding() doesn't tolerate padding" + ); + } + } + } + return static::doDecode( + $encodedString, + $upper, + true + ); + } + + /** + * Base32 decoding + * + * @param string $src + * @param bool $upper + * @param bool $strictPadding + * @return string + * + * @throws TypeError + * @psalm-suppress RedundantCondition + */ + protected static function doDecode( + string $src, + bool $upper = false, + bool $strictPadding = false + ): string { + // We do this to reduce code duplication: + $method = $upper + ? 'decode5BitsUpper' + : 'decode5Bits'; + + // Remove padding + $srcLen = Binary::safeStrlen($src); + if ($srcLen === 0) { + return ''; + } + if ($strictPadding) { + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7; ++$j) { + if ($src[$srcLen - 1] === '=') { + $srcLen--; + } else { + break; + } + } + } + if (($srcLen & 7) === 1) { + throw new RangeException( + 'Incorrect padding' + ); + } + } else { + $src = \rtrim($src, '='); + $srcLen = Binary::safeStrlen($src); + } + + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 8 <= $srcLen; $i += 8) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + /** @var int $c7 */ + $c7 = static::$method($chunk[8]); + + $dest .= \pack( + 'CCCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, + (($c6 << 5) | ($c7 ) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + + if ($i + 6 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + + $dest .= \pack( + 'CCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; + if ($strictPadding) { + $err |= ($c6 << 5) & 0xff; + } + } elseif ($i + 5 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + + $dest .= \pack( + 'CCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; + } elseif ($i + 4 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + + $dest .= \pack( + 'CCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; + if ($strictPadding) { + $err |= ($c4 << 7) & 0xff; + } + } elseif ($i + 3 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + + $dest .= \pack( + 'CC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + if ($strictPadding) { + $err |= ($c3 << 4) & 0xff; + } + } elseif ($i + 2 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + + $dest .= \pack( + 'CC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= ($c2 << 6) & 0xff; + } + } elseif ($i + 1 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + + $dest .= \pack( + 'C', + (($c0 << 3) | ($c1 >> 2) ) & 0xff + ); + $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= ($c1 << 6) & 0xff; + } + } else { + $dest .= \pack( + 'C', + (($c0 << 3) ) & 0xff + ); + $err |= ($c0) >> 8; + } + } + $check = ($err === 0); + if (!$check) { + throw new RangeException( + 'Base32::doDecode() only expects characters in the correct base32 alphabet' + ); + } + return $dest; + } + + /** + * Base32 Encoding + * + * @param string $src + * @param bool $upper + * @param bool $pad + * @return string + * @throws TypeError + */ + protected static function doEncode(string $src, bool $upper = false, $pad = true): string + { + // We do this to reduce code duplication: + $method = $upper + ? 'encode5BitsUpper' + : 'encode5Bits'; + + $dest = ''; + $srcLen = Binary::safeStrlen($src); + + // Main loop (no padding): + for ($i = 0; $i + 5 <= $srcLen; $i += 5) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $b4 = $chunk[5]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . + static::$method((($b3 >> 2) ) & 31) . + static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . + static::$method( $b4 & 31); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 3 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . + static::$method((($b3 >> 2) ) & 31) . + static::$method((($b3 << 3) ) & 31); + if ($pad) { + $dest .= '='; + } + } elseif ($i + 2 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) ) & 31); + if ($pad) { + $dest .= '==='; + } + } elseif ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) ) & 31); + if ($pad) { + $dest .= '===='; + } + } else { + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method( ($b0 << 2) & 31); + if ($pad) { + $dest .= '======'; + } + } + } + return $dest; + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base32Hex.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base32Hex.php new file mode 100644 index 000000000..b868dd048 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base32Hex.php @@ -0,0 +1,111 @@ + 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); + + // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 + $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src): int + { + $ret = -1; + + // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); + + // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 + $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src): string + { + $src += 0x30; + + // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 + $src += ((0x39 - $src) >> 8) & 39; + + return \pack('C', $src); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src): string + { + $src += 0x30; + + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += ((0x39 - $src) >> 8) & 7; + + return \pack('C', $src); + } +} \ No newline at end of file diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64.php new file mode 100644 index 000000000..f5716179f --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64.php @@ -0,0 +1,314 @@ + $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + + $dest .= + static::encode6Bits( $b0 >> 2 ) . + static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . + static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . + static::encode6Bits( $b2 & 63); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= + static::encode6Bits($b0 >> 2) . + static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . + static::encode6Bits(($b1 << 2) & 63); + if ($pad) { + $dest .= '='; + } + } else { + $dest .= + static::encode6Bits( $b0 >> 2) . + static::encode6Bits(($b0 << 4) & 63); + if ($pad) { + $dest .= '=='; + } + } + } + return $dest; + } + + /** + * decode from base64 into binary + * + * Base64 character set "./[A-Z][a-z][0-9]" + * + * @param string $encodedString + * @param bool $strictPadding + * @return string + * + * @throws RangeException + * @throws TypeError + * @psalm-suppress RedundantCondition + */ + public static function decode(string $encodedString, bool $strictPadding = false): string + { + // Remove padding + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + + if ($strictPadding) { + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + } + } + } + if (($srcLen & 3) === 1) { + throw new RangeException( + 'Incorrect padding' + ); + } + if ($encodedString[$srcLen - 1] === '=') { + throw new RangeException( + 'Incorrect padding' + ); + } + } else { + $encodedString = \rtrim($encodedString, '='); + $srcLen = Binary::safeStrlen($encodedString); + } + + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 4 <= $srcLen; $i += 4) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4)); + $c0 = static::decode6Bits($chunk[1]); + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $c3 = static::decode6Bits($chunk[4]); + + $dest .= \pack( + 'CCC', + ((($c0 << 2) | ($c1 >> 4)) & 0xff), + ((($c1 << 4) | ($c2 >> 2)) & 0xff), + ((($c2 << 6) | $c3 ) & 0xff) + ); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i)); + $c0 = static::decode6Bits($chunk[1]); + + if ($i + 2 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $dest .= \pack( + 'CC', + ((($c0 << 2) | ($c1 >> 4)) & 0xff), + ((($c1 << 4) | ($c2 >> 2)) & 0xff) + ); + $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= ($c2 << 6) & 0xff; + } + } elseif ($i + 1 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $dest .= \pack( + 'C', + ((($c0 << 2) | ($c1 >> 4)) & 0xff) + ); + $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= ($c1 << 4) & 0xff; + } + } elseif ($strictPadding) { + $err |= 1; + } + } + $check = ($err === 0); + if (!$check) { + throw new RangeException( + 'Base64::decode() only expects characters in the correct base64 alphabet' + ); + } + return $dest; + } + + /** + * @param string $encodedString + * @return string + */ + public static function decodeNoPadding(string $encodedString): string + { + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + throw new InvalidArgumentException( + "decodeNoPadding() doesn't tolerate padding" + ); + } + if (($srcLen & 3) > 1) { + if ($encodedString[$srcLen - 2] === '=') { + throw new InvalidArgumentException( + "decodeNoPadding() doesn't tolerate padding" + ); + } + } + } + return static::decode( + $encodedString, + true + ); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 6-bit integers + * into 8-bit integers. + * + * Base64 character set: + * [A-Z] [a-z] [0-9] + / + * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + * + * @param int $src + * @return int + */ + protected static function decode6Bits(int $src): int + { + $ret = -1; + + // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); + + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); + + // if ($src == 0x2b) $ret += 62 + 1; + $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; + + // if ($src == 0x2f) ret += 63 + 1; + $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += ((25 - $src) >> 8) & 6; + + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= ((51 - $src) >> 8) & 75; + + // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 + $diff -= ((61 - $src) >> 8) & 15; + + // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 + $diff += ((62 - $src) >> 8) & 3; + + return \pack('C', $src + $diff); + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php new file mode 100644 index 000000000..5e98a8f79 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php @@ -0,0 +1,88 @@ + 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 + $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); + + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); + + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); + + // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $src += 0x2e; + + // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 + $src += ((0x2f - $src) >> 8) & 17; + + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += ((0x5a - $src) >> 8) & 6; + + // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 + $src -= ((0x7a - $src) >> 8) & 75; + + return \pack('C', $src); + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php new file mode 100644 index 000000000..9780b14bb --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php @@ -0,0 +1,82 @@ + 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 + $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); + + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); + + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $src += 0x2e; + + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += ((0x39 - $src) >> 8) & 7; + + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += ((0x5a - $src) >> 8) & 6; + + return \pack('C', $src); + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php new file mode 100644 index 000000000..8192c63d5 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php @@ -0,0 +1,95 @@ + 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); + + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); + + // if ($src == 0x2c) $ret += 62 + 1; + $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; + + // if ($src == 0x5f) ret += 63 + 1; + $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += ((25 - $src) >> 8) & 6; + + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= ((51 - $src) >> 8) & 75; + + // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 + $diff -= ((61 - $src) >> 8) & 13; + + // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 + $diff += ((62 - $src) >> 8) & 49; + + return \pack('C', $src + $diff); + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Binary.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Binary.php new file mode 100644 index 000000000..828f3e0f6 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/Binary.php @@ -0,0 +1,90 @@ + $chunk */ + $chunk = \unpack('C', $binString[$i]); + $c = $chunk[1] & 0xf; + $b = $chunk[1] >> 4; + + $hex .= \pack( + 'CC', + (87 + $b + ((($b - 10) >> 8) & ~38)), + (87 + $c + ((($c - 10) >> 8) & ~38)) + ); + } + return $hex; + } + + /** + * Convert a binary string into a hexadecimal string without cache-timing + * leaks, returning uppercase letters (as per RFC 4648) + * + * @param string $binString (raw binary) + * @return string + * @throws TypeError + */ + public static function encodeUpper(string $binString): string + { + $hex = ''; + $len = Binary::safeStrlen($binString); + + for ($i = 0; $i < $len; ++$i) { + /** @var array $chunk */ + $chunk = \unpack('C', $binString[$i]); + $c = $chunk[1] & 0xf; + $b = $chunk[1] >> 4; + + $hex .= \pack( + 'CC', + (55 + $b + ((($b - 10) >> 8) & ~6)), + (55 + $c + ((($c - 10) >> 8) & ~6)) + ); + } + return $hex; + } + + /** + * Convert a hexadecimal string into a binary string without cache-timing + * leaks + * + * @param string $encodedString + * @param bool $strictPadding + * @return string (raw binary) + * @throws RangeException + */ + public static function decode( + string $encodedString, + bool $strictPadding = false + ): string { + $hex_pos = 0; + $bin = ''; + $c_acc = 0; + $hex_len = Binary::safeStrlen($encodedString); + $state = 0; + if (($hex_len & 1) !== 0) { + if ($strictPadding) { + throw new RangeException( + 'Expected an even number of hexadecimal characters' + ); + } else { + $encodedString = '0' . $encodedString; + ++$hex_len; + } + } + + /** @var array $chunk */ + $chunk = \unpack('C*', $encodedString); + while ($hex_pos < $hex_len) { + ++$hex_pos; + $c = $chunk[$hex_pos]; + $c_num = $c ^ 48; + $c_num0 = ($c_num - 10) >> 8; + $c_alpha = ($c & ~32) - 55; + $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; + + if (($c_num0 | $c_alpha0) === 0) { + throw new RangeException( + 'Expected hexadecimal character' + ); + } + $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); + if ($state === 0) { + $c_acc = $c_val * 16; + } else { + $bin .= \pack('C', $c_acc | $c_val); + } + $state ^= 1; + } + return $bin; + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/RFC4648.php new file mode 100644 index 000000000..f124d65bf --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/constant_time_encoding/src/RFC4648.php @@ -0,0 +1,186 @@ + "Zm9v" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64Encode(string $str): string + { + return Base64::encode($str); + } + + /** + * RFC 4648 Base64 decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64Decode(string $str): string + { + return Base64::decode($str, true); + } + + /** + * RFC 4648 Base64 (URL Safe) encoding + * + * "foo" -> "Zm9v" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64UrlSafeEncode(string $str): string + { + return Base64UrlSafe::encode($str); + } + + /** + * RFC 4648 Base64 (URL Safe) decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64UrlSafeDecode(string $str): string + { + return Base64UrlSafe::decode($str, true); + } + + /** + * RFC 4648 Base32 encoding + * + * "foo" -> "MZXW6===" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32Encode(string $str): string + { + return Base32::encodeUpper($str); + } + + /** + * RFC 4648 Base32 encoding + * + * "MZXW6===" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32Decode(string $str): string + { + return Base32::decodeUpper($str, true); + } + + /** + * RFC 4648 Base32-Hex encoding + * + * "foo" -> "CPNMU===" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32HexEncode(string $str): string + { + return Base32::encodeUpper($str); + } + + /** + * RFC 4648 Base32-Hex decoding + * + * "CPNMU===" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32HexDecode(string $str): string + { + return Base32::decodeUpper($str, true); + } + + /** + * RFC 4648 Base16 decoding + * + * "foo" -> "666F6F" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base16Encode(string $str): string + { + return Hex::encodeUpper($str); + } + + /** + * RFC 4648 Base16 decoding + * + * "666F6F" -> "foo" + * + * @param string $str + * @return string + */ + public static function base16Decode(string $str): string + { + return Hex::decode($str, true); + } +} \ No newline at end of file diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/LICENSE b/libraries/phpseclib3/vendor/paragonie/random_compat/LICENSE new file mode 100644 index 000000000..45c7017df --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/build-phar.sh b/libraries/phpseclib3/vendor/paragonie/random_compat/build-phar.sh new file mode 100644 index 000000000..b4a5ba31c --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/build-phar.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) + +php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/composer.json b/libraries/phpseclib3/vendor/paragonie/random_compat/composer.json new file mode 100644 index 000000000..f2b9c4e51 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/composer.json @@ -0,0 +1,34 @@ +{ + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "polyfill", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "vimeo/psalm": "^1", + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/libraries/phpseclib3/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey new file mode 100644 index 000000000..eb50ebfcd --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm +pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p ++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc +-----END PUBLIC KEY----- diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/libraries/phpseclib3/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc new file mode 100644 index 000000000..6a1d7f300 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (MingW32) + +iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip +QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg +1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW +NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA +NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV +JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= +=B6+8 +-----END PGP SIGNATURE----- diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/lib/random.php b/libraries/phpseclib3/vendor/paragonie/random_compat/lib/random.php new file mode 100644 index 000000000..c7731a56f --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/lib/random.php @@ -0,0 +1,32 @@ +buildFromDirectory(dirname(__DIR__).'/lib'); +rename( + dirname(__DIR__).'/lib/index.php', + dirname(__DIR__).'/lib/random.php' +); + +/** + * If we pass an (optional) path to a private key as a second argument, we will + * sign the Phar with OpenSSL. + * + * If you leave this out, it will produce an unsigned .phar! + */ +if ($argc > 1) { + if (!@is_readable($argv[1])) { + echo 'Could not read the private key file:', $argv[1], "\n"; + exit(255); + } + $pkeyFile = file_get_contents($argv[1]); + + $private = openssl_get_privatekey($pkeyFile); + if ($private !== false) { + $pkey = ''; + openssl_pkey_export($private, $pkey); + $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + + /** + * Save the corresponding public key to the file + */ + if (!@is_readable($dist.'/random_compat.phar.pubkey')) { + $details = openssl_pkey_get_details($private); + file_put_contents( + $dist.'/random_compat.phar.pubkey', + $details['key'] + ); + } + } else { + echo 'An error occurred reading the private key from OpenSSL.', "\n"; + exit(255); + } +} diff --git a/libraries/phpseclib3/vendor/paragonie/random_compat/psalm-autoload.php b/libraries/phpseclib3/vendor/paragonie/random_compat/psalm-autoload.php new file mode 100644 index 000000000..d71d1b818 --- /dev/null +++ b/libraries/phpseclib3/vendor/paragonie/random_compat/psalm-autoload.php @@ -0,0 +1,9 @@ + + + + + + + + + + + + + + + diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/AUTHORS b/libraries/phpseclib3/vendor/phpseclib/phpseclib/AUTHORS similarity index 88% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/AUTHORS rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/AUTHORS index a08b3099c..9f10d2671 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/AUTHORS +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/AUTHORS @@ -4,3 +4,4 @@ phpseclib Developers: monnerat (Patrick Monnerat) bantu (Andreas Fischer) petrich (Hans-JĂŒrgen Petrich) GrahamCampbell (Graham Campbell) + hc-jworman \ No newline at end of file diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/BACKERS.md b/libraries/phpseclib3/vendor/phpseclib/phpseclib/BACKERS.md similarity index 55% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/BACKERS.md rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/BACKERS.md index a78bca691..4ee6a4f9b 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/BACKERS.md +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/BACKERS.md @@ -4,6 +4,13 @@ phpseclib ongoing development is made possible by [Tidelift](https://tidelift.co ## Backers +- Allan Simon +- [ChargeOver](https://chargeover.com/) +- Raghu Veer Dendukuri - Zane Hooper - [Setasign](https://www.setasign.com/) -- Allan Simon \ No newline at end of file +- [Charles Severance](https://github.com/csev) +- [Rachel Fish](https://github.com/itsrachelfish) +- Tharyrok +- [cjhaas](https://github.com/cjhaas) +- [istiak-tridip](https://github.com/istiak-tridip) \ No newline at end of file diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/LICENSE b/libraries/phpseclib3/vendor/phpseclib/phpseclib/LICENSE similarity index 100% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/LICENSE rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/LICENSE diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/README.md b/libraries/phpseclib3/vendor/phpseclib/phpseclib/README.md similarity index 73% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/README.md rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/README.md index c81c46920..bbb1e9f06 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/README.md +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/README.md @@ -1,6 +1,6 @@ # phpseclib - PHP Secure Communications Library -[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.com/phpseclib/phpseclib) +[![CI Status](https://github.com/phpseclib/phpseclib/actions/workflows/ci.yml/badge.svg?branch=3.0&event=push "CI Status")](https://github.com/phpseclib/phpseclib) ## Supporting phpseclib @@ -19,7 +19,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / ## Documentation * [Documentation / Manual](https://phpseclib.com/) -* [API Documentation](https://api.phpseclib.com/2.0/) (generated by Doctum) +* [API Documentation](https://api.phpseclib.com/3.0/) (generated by Doctum) ## Branches @@ -51,8 +51,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / * PHP4 compatible * Composer compatible (PSR-0 autoloading) * Install using Composer: `composer require phpseclib/phpseclib:~1.0` -* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm) -* [Download 1.0.19 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.19.zip/download) +* [Download 1.0.21 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.21.zip/download) ## Security contact information @@ -68,9 +67,10 @@ Need Support? ## Special Thanks -Special Thanks to our Patreon sponsors!: +Special Thanks to our $50+ sponsors!: - Allan Simon +- [ChargeOver](https://chargeover.com/) ## Contributing @@ -79,22 +79,19 @@ Special Thanks to our Patreon sponsors!: 2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/)) 3. Install Development Dependencies - - ``` sh + ```sh composer install ``` 4. Create a Feature Branch -5. (Recommended) Run the Test Suite - - ``` sh - vendor/bin/phpunit - ``` -6. (Recommended) Check whether your code conforms to our Coding Standards by running - - ``` sh - vendor/bin/phing -f build/build.xml sniff - ``` - -7. Send us a Pull Request +5. Run continuous integration checks: + ```sh + composer global require php:^8.1 squizlabs/php_codesniffer friendsofphp/php-cs-fixer vimeo/psalm + phpcs --standard=build/php_codesniffer.xml + php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no + psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text + vendor/bin/phpunit --verbose --configuration tests/phpunit.xml + ``` + +6. Send us a Pull Request diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json b/libraries/phpseclib3/vendor/phpseclib/phpseclib/composer.json similarity index 81% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/composer.json index 08b9c7c91..5052d5fb2 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/composer.json @@ -51,25 +51,34 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=5.6.1", + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99" }, "require-dev": { - "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", - "squizlabs/php_codesniffer": "~2.0" + "phpunit/phpunit": "*" }, "suggest": { "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations." + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-dom": "Install the DOM extension to load XML formatted public keys." }, "autoload": { "files": [ "phpseclib/bootstrap.php" ], "psr-4": { - "phpseclib\\": "phpseclib/" + "phpseclib3\\": "phpseclib/" } + }, + "autoload-dev": { + "psr-4": { + "phpseclib3\\Tests\\": "tests/" + } + }, + "config": { + "sort-packages": true } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php new file mode 100644 index 000000000..eac793a69 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php @@ -0,0 +1,505 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Common\Functions; + +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Base64UrlSafe; +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField; + +/** + * Common String Functions + * + * @author Jim Wigginton + */ +abstract class Strings +{ + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + */ + public static function shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + + /** + * String Pop + * + * Inspired by array_pop + * + * @param string $string + * @param int $index + * @return string + */ + public static function pop(&$string, $index = 1) + { + $substr = substr($string, -$index); + $string = substr($string, 0, -$index); + return $substr; + } + + /** + * Parse SSH2-style string + * + * Returns either an array or a boolean if $data is malformed. + * + * Valid characters for $format are as follows: + * + * C = byte + * b = boolean (true/false) + * N = uint32 + * Q = uint64 + * s = string + * i = mpint + * L = name-list + * + * uint64 is not supported. + * + * @param string $format + * @param string $data + * @return mixed + */ + public static function unpackSSH2($format, &$data) + { + $format = self::formatPack($format); + $result = []; + for ($i = 0; $i < strlen($format); $i++) { + switch ($format[$i]) { + case 'C': + case 'b': + if (!strlen($data)) { + throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); + } + break; + case 'N': + case 'i': + case 's': + case 'L': + if (strlen($data) < 4) { + throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); + } + break; + case 'Q': + if (strlen($data) < 8) { + throw new \LengthException('At least eight byte needs to be present for successful N / i / s / L decodes'); + } + break; + + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + switch ($format[$i]) { + case 'C': + $result[] = ord(self::shift($data)); + continue 2; + case 'b': + $result[] = ord(self::shift($data)) != 0; + continue 2; + case 'N': + list(, $temp) = unpack('N', self::shift($data, 4)); + $result[] = $temp; + continue 2; + case 'Q': + // pack() added support for Q in PHP 5.6.3 and PHP 5.6 is phpseclib 3's minimum version + // so in theory we could support this BUT, "64-bit format codes are not available for + // 32-bit versions" and phpseclib works on 32-bit installs. on 32-bit installs + // 64-bit floats can be used to get larger numbers then 32-bit signed ints would allow + // for. sure, you're not gonna get the full precision of 64-bit numbers but just because + // you need > 32-bit precision doesn't mean you need the full 64-bit precision + extract(unpack('Nupper/Nlower', self::shift($data, 8))); + $temp = $upper ? 4294967296 * $upper : 0; + $temp += $lower < 0 ? ($lower & 0x7FFFFFFFF) + 0x80000000 : $lower; + // $temp = hexdec(bin2hex(self::shift($data, 8))); + $result[] = $temp; + continue 2; + } + list(, $length) = unpack('N', self::shift($data, 4)); + if (strlen($data) < $length) { + throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); + } + $temp = self::shift($data, $length); + switch ($format[$i]) { + case 'i': + $result[] = new BigInteger($temp, -256); + break; + case 's': + $result[] = $temp; + break; + case 'L': + $result[] = explode(',', $temp); + } + } + + return $result; + } + + /** + * Create SSH2-style string + * + * @param string $format + * @param string|int|float|array|bool ...$elements + * @return string + */ + public static function packSSH2($format, ...$elements) + { + $format = self::formatPack($format); + if (strlen($format) != count($elements)) { + throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); + } + $result = ''; + for ($i = 0; $i < strlen($format); $i++) { + $element = $elements[$i]; + switch ($format[$i]) { + case 'C': + if (!is_int($element)) { + throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); + } + $result .= pack('C', $element); + break; + case 'b': + if (!is_bool($element)) { + throw new \InvalidArgumentException('A boolean parameter was expected.'); + } + $result .= $element ? "\1" : "\0"; + break; + case 'Q': + if (!is_int($element) && !is_float($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + // 4294967296 == 1 << 32 + $result .= pack('NN', $element / 4294967296, $element); + break; + case 'N': + if (is_float($element)) { + $element = (int) $element; + } + if (!is_int($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + $result .= pack('N', $element); + break; + case 's': + if (!self::is_stringable($element)) { + throw new \InvalidArgumentException('A string was expected.'); + } + $result .= pack('Na*', strlen($element), $element); + break; + case 'i': + if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { + throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); + } + $element = $element->toBytes(true); + $result .= pack('Na*', strlen($element), $element); + break; + case 'L': + if (!is_array($element)) { + throw new \InvalidArgumentException('An array was expected.'); + } + $element = implode(',', $element); + $result .= pack('Na*', strlen($element), $element); + break; + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + } + return $result; + } + + /** + * Expand a pack string + * + * Converts C5 to CCCCC, for example. + * + * @param string $format + * @return string + */ + private static function formatPack($format) + { + $parts = preg_split('#(\d+)#', $format, -1, PREG_SPLIT_DELIM_CAPTURE); + $format = ''; + for ($i = 1; $i < count($parts); $i += 2) { + $format .= substr($parts[$i - 1], 0, -1) . str_repeat(substr($parts[$i - 1], -1), $parts[$i]); + } + $format .= $parts[$i - 1]; + + return $format; + } + + /** + * Convert binary data into bits + * + * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst + * decbin / bindec refer to base-2 encoded data as binary. For the purposes + * of this function, bin refers to base-256 encoded data whilst bits refers + * to base-2 encoded data + * + * @param string $x + * @return string + */ + public static function bits2bin($x) + { + /* + // the pure-PHP approach is faster than the GMP approach + if (function_exists('gmp_export')) { + return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); + } + */ + + if (preg_match('#[^01]#', $x)) { + throw new \RuntimeException('The only valid characters are 0 and 1'); + } + + if (!defined('PHP_INT_MIN')) { + define('PHP_INT_MIN', ~PHP_INT_MAX); + } + + $length = strlen($x); + if (!$length) { + return ''; + } + $block_size = PHP_INT_SIZE << 3; + $pad = $block_size - ($length % $block_size); + if ($pad != $block_size) { + $x = str_repeat('0', $pad) . $x; + } + + $parts = str_split($x, $block_size); + $str = ''; + foreach ($parts as $part) { + $xor = $part[0] == '1' ? PHP_INT_MIN : 0; + $part[0] = '0'; + $str .= pack( + PHP_INT_SIZE == 4 ? 'N' : 'J', + $xor ^ eval('return 0b' . $part . ';') + ); + } + return ltrim($str, "\0"); + } + + /** + * Convert bits to binary data + * + * @param string $x + * @return string + */ + public static function bin2bits($x, $trim = true) + { + /* + // the pure-PHP approach is slower than the GMP approach BUT + // i want to the pure-PHP version to be easily unit tested as well + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + */ + + $len = strlen($x); + $mod = $len % PHP_INT_SIZE; + if ($mod) { + $x = str_pad($x, $len + PHP_INT_SIZE - $mod, "\0", STR_PAD_LEFT); + } + + $bits = ''; + if (PHP_INT_SIZE == 4) { + $digits = unpack('N*', $x); + foreach ($digits as $digit) { + $bits .= sprintf('%032b', $digit); + } + } else { + $digits = unpack('J*', $x); + foreach ($digits as $digit) { + $bits .= sprintf('%064b', $digit); + } + } + + return $trim ? ltrim($bits, '0') : $bits; + } + + /** + * Switch Endianness Bit Order + * + * @param string $x + * @return string + */ + public static function switchEndianness($x) + { + $r = ''; + for ($i = strlen($x) - 1; $i >= 0; $i--) { + $b = ord($x[$i]); + if (PHP_INT_SIZE === 8) { + // 3 operations + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv + $r .= chr((($b * 0x0202020202) & 0x010884422010) % 1023); + } else { + // 7 operations + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits + $p1 = ($b * 0x0802) & 0x22110; + $p2 = ($b * 0x8020) & 0x88440; + $r .= chr( + (($p1 | $p2) * 0x10101) >> 16 + ); + } + } + return $r; + } + + /** + * Increment the current string + * + * @param string $var + * @return string + */ + public static function increment_str(&$var) + { + if (function_exists('sodium_increment')) { + $var = strrev($var); + sodium_increment($var); + $var = strrev($var); + return $var; + } + + for ($i = 4; $i <= strlen($var); $i += 4) { + $temp = substr($var, -$i, 4); + switch ($temp) { + case "\xFF\xFF\xFF\xFF": + $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); + break; + case "\x7F\xFF\xFF\xFF": + $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); + return $var; + default: + $temp = unpack('Nnum', $temp); + $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); + return $var; + } + } + + $remainder = strlen($var) % 4; + + if ($remainder == 0) { + return $var; + } + + $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); + $temp = substr(pack('N', $temp['num'] + 1), -$remainder); + $var = substr_replace($var, $temp, 0, $remainder); + + return $var; + } + + /** + * Find whether the type of a variable is string (or could be converted to one) + * + * @param mixed $var + * @return bool + * @psalm-assert-if-true string|\Stringable $var + */ + public static function is_stringable($var) + { + return is_string($var) || (is_object($var) && method_exists($var, '__toString')); + } + + /** + * Constant Time Base64-decoding + * + * ParagoneIE\ConstantTime doesn't use libsodium if it's available so we'll do so + * ourselves. see https://github.com/paragonie/constant_time_encoding/issues/39 + * + * @param string $data + * @return string + */ + public static function base64_decode($data) + { + return function_exists('sodium_base642bin') ? + sodium_base642bin($data, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, '=') : + Base64::decode($data); + } + + /** + * Constant Time Base64-decoding (URL safe) + * + * @param string $data + * @return string + */ + public static function base64url_decode($data) + { + // return self::base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); + + return function_exists('sodium_base642bin') ? + sodium_base642bin($data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, '=') : + Base64UrlSafe::decode($data); + } + + /** + * Constant Time Base64-encoding + * + * @param string $data + * @return string + */ + public static function base64_encode($data) + { + return function_exists('sodium_bin2base64') ? + sodium_bin2base64($data, SODIUM_BASE64_VARIANT_ORIGINAL) : + Base64::encode($data); + } + + /** + * Constant Time Base64-encoding (URL safe) + * + * @param string $data + * @return string + */ + public static function base64url_encode($data) + { + // return str_replace(['+', '/'], ['-', '_'], self::base64_encode($data)); + + return function_exists('sodium_bin2base64') ? + sodium_bin2base64($data, SODIUM_BASE64_VARIANT_URLSAFE) : + Base64UrlSafe::encode($data); + } + + /** + * Constant Time Hex Decoder + * + * @param string $data + * @return string + */ + public static function hex2bin($data) + { + return function_exists('sodium_hex2bin') ? + sodium_hex2bin($data) : + Hex::decode($data); + } + + /** + * Constant Time Hex Encoder + * + * @param string $data + * @return string + */ + public static function bin2hex($data) + { + return function_exists('sodium_bin2hex') ? + sodium_bin2hex($data) : + Hex::encode($data); + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php similarity index 58% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php index 7d8cb8b03..403871627 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php @@ -16,7 +16,7 @@ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()} * is called, again, at which point, it'll be recalculated. * - * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't + * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't * make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function, * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one). * @@ -25,7 +25,7 @@ * setKey('abcdefghijklmnop'); * @@ -39,57 +39,53 @@ * ?> * * - * @category Crypt - * @package AES * @author Jim Wigginton * @copyright 2008 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; /** * Pure-PHP implementation of AES. * - * @package AES * @author Jim Wigginton - * @access public */ class AES extends Rijndael { /** * Dummy function * - * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. + * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. * - * @see \phpseclib\Crypt\Rijndael::setBlockLength() - * @access public + * @see \phpseclib3\Crypt\Rijndael::setBlockLength() * @param int $length + * @throws \BadMethodCallException anytime it's called */ - function setBlockLength($length) + public function setBlockLength($length) { - return; + throw new \BadMethodCallException('The block length cannot be set for AES.'); } /** * Sets the key length * - * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to - * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. + * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length * - * @see \phpseclib\Crypt\Rijndael:setKeyLength() - * @access public + * @see \phpseclib3\Crypt\Rijndael:setKeyLength() * @param int $length + * @throws \LengthException if the key length isn't supported */ - function setKeyLength($length) + public function setKeyLength($length) { switch ($length) { - case 160: - $length = 192; + case 128: + case 192: + case 256: break; - case 224: - $length = 256; + default: + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); } parent::setKeyLength($length); } @@ -99,28 +95,22 @@ class AES extends Rijndael * * Rijndael supports five different key lengths, AES only supports three. * - * @see \phpseclib\Crypt\Rijndael:setKey() + * @see \phpseclib3\Crypt\Rijndael:setKey() * @see setKeyLength() - * @access public * @param string $key + * @throws \LengthException if the key length isn't supported */ - function setKey($key) + public function setKey($key) { - parent::setKey($key); - - if (!$this->explicit_key_length) { - $length = strlen($key); - switch (true) { - case $length <= 16: - $this->key_length = 16; - break; - case $length <= 24: - $this->key_length = 24; - break; - default: - $this->key_length = 32; - } - $this->_setEngine(); + switch (strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); } + + parent::setKey($key); } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php new file mode 100644 index 000000000..122507089 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php @@ -0,0 +1,918 @@ + unpack('N*', $x), $blocks); it jumps up by an additional + * ~90MB, yielding a 106x increase in memory usage. Consequently, it bcrypt calls a different + * _encryptBlock() then the regular Blowfish does. That said, the Blowfish _encryptBlock() is + * basically just a thin wrapper around the bcrypt _encryptBlock(), so there's that. + * + * This explains 3 of the 4 _encryptBlock() implementations. the last _encryptBlock() + * implementation can best be understood by doing Ctrl + F and searching for where + * self::$use_reg_intval is defined. + * + * # phpseclib's three different _setupKey() implementations + * + * Every bcrypt round is the equivalent of encrypting 512KB of data. Since OpenSSH uses 16 + * rounds by default that's ~8MB of data that's essentially being encrypted whenever + * you use bcrypt. That's a lot of data, however, bcrypt operates within tighter constraints + * than regular Blowfish, so we can use that to our advantage. In particular, whereas Blowfish + * supports variable length keys, in bcrypt, the initial "key" is the sha512 hash of the + * password. sha512 hashes are 512 bits or 64 bytes long and thus the bcrypt keys are of a + * fixed length whereas Blowfish keys are not of a fixed length. + * + * bcrypt actually has two different key expansion steps. The first one (expandstate) is + * constantly XOR'ing every _encryptBlock() parameter against the salt prior _encryptBlock()'s + * being called. The second one (expand0state) is more similar to Blowfish's _setupKey() + * but it can still use the fixed length key optimization discussed above and can do away with + * the pack() / unpack() calls. + * + * I suppose _setupKey() could be made to be a thin wrapper around expandstate() but idk it's + * just a lot of work for very marginal benefits as _setupKey() is only called once for + * regular Blowfish vs the 128 times it's called --per round-- with bcrypt. + * + * # blowfish + bcrypt in the same class + * + * Altho there's a lot of Blowfish code that bcrypt doesn't re-use, bcrypt does re-use the + * initial S-boxes, the initial P-array and the int-only _encryptBlock() implementation. + * + * # Credit + * + * phpseclib's bcrypt implementation is based losely off of OpenSSH's implementation: + * + * https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c + * + * Here's a short example of how to use this library: + * + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; + +/** + * Pure-PHP implementation of Blowfish. + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +class Blowfish extends BlockCipher +{ + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 8; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'blowfish'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + */ + protected $cfb_init_len = 500; + + /** + * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each + * + * S-Box 0 + * + * @var array + */ + private static $sbox0 = [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + ]; + + /** + * S-Box 1 + * + * @var array + */ + private static $sbox1 = [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + ]; + + /** + * S-Box 2 + * + * @var array + */ + private static $sbox2 = [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + ]; + + /** + * S-Box 3 + * + * @var array + */ + private static $sbox3 = [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ]; + + /** + * P-Array consists of 18 32-bit subkeys + * + * @var array + */ + private static $parray = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, + 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b + ]; + + /** + * The BCTX-working Array + * + * Holds the expanded key [p] and the key-depended s-boxes [sb] + * + * @var array + */ + private $bctx; + + /** + * Holds the last used key + * + * @var array + */ + private $kl; + + /** + * The Key Length (in bytes) + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @var int + */ + protected $key_length = 16; + + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Sets the key length. + * + * Key lengths can be between 32 and 448 bits. + * + * @param int $length + */ + public function setKeyLength($length) + { + if ($length < 32 || $length > 448) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); + } + + $this->key_length = $length >> 3; + + parent::setKeyLength($length); + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + if ($this->key_length < 16) { + return false; + } + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } + $this->cipher_name_openssl_ecb = 'bf-ecb'; + $this->cipher_name_openssl = 'bf-' . $this->openssl_translate_mode(); + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key]; + + /* key-expanding p[] and S-Box building sb[] */ + $this->bctx = [ + 'p' => [], + 'sb' => [ + self::$sbox0, + self::$sbox1, + self::$sbox2, + self::$sbox3 + ] + ]; + + // unpack binary string in unsigned chars + $key = array_values(unpack('C*', $this->key)); + $keyl = count($key); + // with bcrypt $keyl will always be 16 (because the key is the sha512 of the key you provide) + for ($j = 0, $i = 0; $i < 18; ++$i) { + // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ... + for ($data = 0, $k = 0; $k < 4; ++$k) { + $data = ($data << 8) | $key[$j]; + if (++$j >= $keyl) { + $j = 0; + } + } + $this->bctx['p'][] = self::$parray[$i] ^ intval($data); + } + + // encrypt the zero-string, replace P1 and P2 with the encrypted data, + // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys + $data = "\0\0\0\0\0\0\0\0"; + for ($i = 0; $i < 18; $i += 2) { + list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + $this->bctx['p'][$i ] = $l; + $this->bctx['p'][$i + 1] = $r; + } + for ($i = 0; $i < 4; ++$i) { + for ($j = 0; $j < 256; $j += 2) { + list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + $this->bctx['sb'][$i][$j ] = $l; + $this->bctx['sb'][$i][$j + 1] = $r; + } + } + } + + /** + * Initialize Static Variables + */ + protected static function initialize_static_variables() + { + if (is_float(self::$sbox2[0])) { + self::$sbox0 = array_map('intval', self::$sbox0); + self::$sbox1 = array_map('intval', self::$sbox1); + self::$sbox2 = array_map('intval', self::$sbox2); + self::$sbox3 = array_map('intval', self::$sbox3); + self::$parray = array_map('intval', self::$parray); + } + + parent::initialize_static_variables(); + } + + /** + * bcrypt + * + * @param string $sha2pass + * @param string $sha2salt + * @access private + * @return string + */ + private static function bcrypt_hash($sha2pass, $sha2salt) + { + $p = self::$parray; + $sbox0 = self::$sbox0; + $sbox1 = self::$sbox1; + $sbox2 = self::$sbox2; + $sbox3 = self::$sbox3; + + $cdata = array_values(unpack('N*', 'OxychromaticBlowfishSwatDynamite')); + $sha2pass = array_values(unpack('N*', $sha2pass)); + $sha2salt = array_values(unpack('N*', $sha2salt)); + + self::expandstate($sha2salt, $sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 0; $i < 64; $i++) { + self::expand0state($sha2salt, $sbox0, $sbox1, $sbox2, $sbox3, $p); + self::expand0state($sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + for ($i = 0; $i < 64; $i++) { + for ($j = 0; $j < 8; $j += 2) { // count($cdata) == 8 + list($cdata[$j], $cdata[$j + 1]) = self::encryptBlockHelperFast($cdata[$j], $cdata[$j + 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + } + + return pack('L*', ...$cdata); + } + + /** + * Performs OpenSSH-style bcrypt + * + * @param string $pass + * @param string $salt + * @param int $keylen + * @param int $rounds + * @access public + * @return string + */ + public static function bcrypt_pbkdf($pass, $salt, $keylen, $rounds) + { + self::initialize_static_variables(); + + if (PHP_INT_SIZE == 4) { + throw new \RuntimeException('bcrypt is far too slow to be practical on 32-bit versions of PHP'); + } + + $sha2pass = hash('sha512', $pass, true); + $results = []; + $count = 1; + while (32 * count($results) < $keylen) { + $countsalt = $salt . pack('N', $count++); + $sha2salt = hash('sha512', $countsalt, true); + $out = $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); + for ($i = 1; $i < $rounds; $i++) { + $sha2salt = hash('sha512', $tmpout, true); + $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); + $out ^= $tmpout; + } + $results[] = $out; + } + $output = ''; + for ($i = 0; $i < 32; $i++) { + foreach ($results as $result) { + $output .= $result[$i]; + } + } + return substr($output, 0, $keylen); + } + + /** + * Key expansion without salt + * + * @access private + * @param int[] $key + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @see self::_bcrypt_hash() + */ + private static function expand0state(array $key, array &$sbox0, array &$sbox1, array &$sbox2, array &$sbox3, array &$p) + { + // expand0state is basically the same thing as this: + //return self::expandstate(array_fill(0, 16, 0), $key); + // but this separate function eliminates a bunch of XORs and array lookups + + $p = [ + $p[0] ^ $key[0], + $p[1] ^ $key[1], + $p[2] ^ $key[2], + $p[3] ^ $key[3], + $p[4] ^ $key[4], + $p[5] ^ $key[5], + $p[6] ^ $key[6], + $p[7] ^ $key[7], + $p[8] ^ $key[8], + $p[9] ^ $key[9], + $p[10] ^ $key[10], + $p[11] ^ $key[11], + $p[12] ^ $key[12], + $p[13] ^ $key[13], + $p[14] ^ $key[14], + $p[15] ^ $key[15], + $p[16] ^ $key[0], + $p[17] ^ $key[1] + ]; + + // @codingStandardsIgnoreStart + list( $p[0], $p[1]) = self::encryptBlockHelperFast( 0, 0, $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[2], $p[3]) = self::encryptBlockHelperFast($p[ 0], $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[4], $p[5]) = self::encryptBlockHelperFast($p[ 2], $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[6], $p[7]) = self::encryptBlockHelperFast($p[ 4], $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[8], $p[9]) = self::encryptBlockHelperFast($p[ 6], $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[10], $p[11]) = self::encryptBlockHelperFast($p[ 8], $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[12], $p[13]) = self::encryptBlockHelperFast($p[10], $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[14], $p[15]) = self::encryptBlockHelperFast($p[12], $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[16], $p[17]) = self::encryptBlockHelperFast($p[14], $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p); + // @codingStandardsIgnoreEnd + + list($sbox0[0], $sbox0[1]) = self::encryptBlockHelperFast($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox0[$i], $sbox0[$i + 1]) = self::encryptBlockHelperFast($sbox0[$i - 2], $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox1[0], $sbox1[1]) = self::encryptBlockHelperFast($sbox0[254], $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox1[$i], $sbox1[$i + 1]) = self::encryptBlockHelperFast($sbox1[$i - 2], $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox2[0], $sbox2[1]) = self::encryptBlockHelperFast($sbox1[254], $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox2[$i], $sbox2[$i + 1]) = self::encryptBlockHelperFast($sbox2[$i - 2], $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox3[0], $sbox3[1]) = self::encryptBlockHelperFast($sbox2[254], $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox3[$i], $sbox3[$i + 1]) = self::encryptBlockHelperFast($sbox3[$i - 2], $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + } + + /** + * Key expansion with salt + * + * @access private + * @param int[] $data + * @param int[] $key + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @see self::_bcrypt_hash() + */ + private static function expandstate(array $data, array $key, array &$sbox0, array &$sbox1, array &$sbox2, array &$sbox3, array &$p) + { + $p = [ + $p[0] ^ $key[0], + $p[1] ^ $key[1], + $p[2] ^ $key[2], + $p[3] ^ $key[3], + $p[4] ^ $key[4], + $p[5] ^ $key[5], + $p[6] ^ $key[6], + $p[7] ^ $key[7], + $p[8] ^ $key[8], + $p[9] ^ $key[9], + $p[10] ^ $key[10], + $p[11] ^ $key[11], + $p[12] ^ $key[12], + $p[13] ^ $key[13], + $p[14] ^ $key[14], + $p[15] ^ $key[15], + $p[16] ^ $key[0], + $p[17] ^ $key[1] + ]; + + // @codingStandardsIgnoreStart + list( $p[0], $p[1]) = self::encryptBlockHelperFast($data[ 0] , $data[ 1] , $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[2], $p[3]) = self::encryptBlockHelperFast($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[4], $p[5]) = self::encryptBlockHelperFast($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[6], $p[7]) = self::encryptBlockHelperFast($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[8], $p[9]) = self::encryptBlockHelperFast($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[10], $p[11]) = self::encryptBlockHelperFast($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[12], $p[13]) = self::encryptBlockHelperFast($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[14], $p[15]) = self::encryptBlockHelperFast($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[16], $p[17]) = self::encryptBlockHelperFast($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p); + // @codingStandardsIgnoreEnd + + list($sbox0[0], $sbox0[1]) = self::encryptBlockHelperFast($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better? + list($sbox0[$i], $sbox0[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox0[$i - 2], $data[$j + 1] ^ $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox1[0], $sbox1[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox0[254], $data[3] ^ $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { + list($sbox1[$i], $sbox1[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox1[$i - 2], $data[$j + 1] ^ $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox2[0], $sbox2[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox1[254], $data[3] ^ $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { + list($sbox2[$i], $sbox2[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox2[$i - 2], $data[$j + 1] ^ $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox3[0], $sbox3[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox2[254], $data[3] ^ $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { + list($sbox3[$i], $sbox3[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox3[$i - 2], $data[$j + 1] ^ $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + } + + /** + * Encrypts a block + * + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + $p = $this->bctx['p']; + // extract($this->bctx['sb'], EXTR_PREFIX_ALL, 'sb'); // slower + $sb_0 = $this->bctx['sb'][0]; + $sb_1 = $this->bctx['sb'][1]; + $sb_2 = $this->bctx['sb'][2]; + $sb_3 = $this->bctx['sb'][3]; + + $in = unpack('N*', $in); + $l = $in[1]; + $r = $in[2]; + + list($r, $l) = PHP_INT_SIZE == 4 ? + self::encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) : + self::encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p); + + return pack("N*", $r, $l); + } + + /** + * Fast helper function for block encryption + * + * @access private + * @param int $x0 + * @param int $x1 + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @return int[] + */ + private static function encryptBlockHelperFast($x0, $x1, array $sbox0, array $sbox1, array $sbox2, array $sbox3, array $p) + { + $x0 ^= $p[0]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; + + return [$x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF]; + } + + /** + * Slow helper function for block encryption + * + * @access private + * @param int $x0 + * @param int $x1 + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @return int[] + */ + private static function encryptBlockHelperSlow($x0, $x1, array $sbox0, array $sbox1, array $sbox2, array $sbox3, array $p) + { + // -16777216 == intval(0xFF000000) on 32-bit PHP installs + $x0 ^= $p[0]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; + + return [$x1 ^ $p[17], $x0]; + } + + /** + * Decrypts a block + * + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + $p = $this->bctx['p']; + $sb_0 = $this->bctx['sb'][0]; + $sb_1 = $this->bctx['sb'][1]; + $sb_2 = $this->bctx['sb'][2]; + $sb_3 = $this->bctx['sb'][3]; + + $in = unpack('N*', $in); + $l = $in[1]; + $r = $in[2]; + + for ($i = 17; $i > 2; $i -= 2) { + $l ^= $p[$i]; + $r ^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]); + + $r ^= $p[$i - 1]; + $l ^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]); + } + return pack('N*', $r ^ $p[0], $l ^ $p[1]); + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + $p = $this->bctx['p']; + $init_crypt = ' + static $sb_0, $sb_1, $sb_2, $sb_3; + if (!$sb_0) { + $sb_0 = $this->bctx["sb"][0]; + $sb_1 = $this->bctx["sb"][1]; + $sb_2 = $this->bctx["sb"][2]; + $sb_3 = $this->bctx["sb"][3]; + } + '; + + $safeint = self::safe_intval_inline(); + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + for ($i = 0; $i < 16; $i += 2) { + $encrypt_block .= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i + 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + $encrypt_block .= ' + $in = pack("N*", + $r ^ ' . $p[17] . ', + $l ^ ' . $p[16] . ' + ); + '; + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + + for ($i = 17; $i > 2; $i -= 2) { + $decrypt_block .= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i - 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + + $decrypt_block .= ' + $in = pack("N*", + $r ^ ' . $p[0] . ', + $l ^ ' . $p[1] . ' + ); + '; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php new file mode 100644 index 000000000..b2691b5dd --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php @@ -0,0 +1,799 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\InsufficientSetupException; + +/** + * Pure-PHP implementation of ChaCha20. + * + * @author Jim Wigginton + */ +class ChaCha20 extends Salsa20 +{ + /** + * The OpenSSL specific name of the cipher + * + * @var string + */ + protected $cipher_name_openssl = 'chacha20'; + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_LIBSODIUM: + // PHP 7.2.0 (30 Nov 2017) added support for libsodium + + // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL + // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm + + // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string + // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority + return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') && + $this->key_length == 32 && + (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) && + !$this->continuousBuffer; + case self::ENGINE_OPENSSL: + // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20. + // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017) + + // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null + // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that + // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode + // whereas libsodium does not + if ($this->key_length != 32) { + return false; + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + $this->setup(); + + if ($this->engine == self::ENGINE_LIBSODIUM) { + return $this->encrypt_with_libsodium($plaintext); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + $this->setup(); + + if ($this->engine == self::ENGINE_LIBSODIUM) { + return $this->decrypt_with_libsodium($ciphertext); + } + + return parent::decrypt($ciphertext); + } + + /** + * Encrypts a message with libsodium + * + * @see self::encrypt() + * @param string $plaintext + * @return string $text + */ + private function encrypt_with_libsodium($plaintext) + { + $params = [$plaintext, $this->aad, $this->nonce, $this->key]; + $ciphertext = strlen($this->nonce) == 8 ? + sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : + sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); + if (!$this->usePoly1305) { + return substr($ciphertext, 0, strlen($plaintext)); + } + + $newciphertext = substr($ciphertext, 0, strlen($plaintext)); + + $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ? + substr($ciphertext, strlen($plaintext)) : + $this->poly1305($newciphertext); + + return $newciphertext; + } + + /** + * Decrypts a message with libsodium + * + * @see self::decrypt() + * @param string $ciphertext + * @return string $text + */ + private function decrypt_with_libsodium($ciphertext) + { + $params = [$ciphertext, $this->aad, $this->nonce, $this->key]; + + if (isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) { + $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params); + $this->oldtag = false; + if ($plaintext === false) { + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + return $plaintext; + } + $newtag = $this->poly1305($ciphertext); + if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + } + + $plaintext = strlen($this->nonce) == 8 ? + sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : + sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); + + return substr($plaintext, 0, strlen($ciphertext)); + } + + /** + * Sets the nonce. + * + * @param string $nonce + */ + public function setNonce($nonce) + { + if (!is_string($nonce)) { + throw new \UnexpectedValueException('The nonce should be a string'); + } + + /* + from https://tools.ietf.org/html/rfc7539#page-7 + + "Note also that the original ChaCha had a 64-bit nonce and 64-bit + block count. We have modified this here to be more consistent with + recommendations in Section 3.2 of [RFC5116]." + */ + switch (strlen($nonce)) { + case 8: // 64 bits + case 12: // 96 bits + break; + default: + throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); + } + + $this->nonce = $nonce; + $this->changed = true; + $this->setEngine(); + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setNonce() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setNonce() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; + + $this->changed = $this->nonIVChanged = false; + + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + if ($this->usePoly1305 && !isset($this->poly1305Key)) { + $this->usingGeneratedPoly1305Key = true; + if ($this->engine == self::ENGINE_LIBSODIUM) { + return; + } + $this->createPoly1305Key(); + } + + $key = $this->key; + if (strlen($key) == 16) { + $constant = 'expand 16-byte k'; + $key .= $key; + } else { + $constant = 'expand 32-byte k'; + } + + $this->p1 = $constant . $key; + $this->p2 = $this->nonce; + if (strlen($this->nonce) == 8) { + $this->p2 = "\0\0\0\0" . $this->p2; + } + } + + /** + * The quarterround function + * + * @param int $a + * @param int $b + * @param int $c + * @param int $d + */ + protected static function quarterRound(&$a, &$b, &$c, &$d) + { + // in https://datatracker.ietf.org/doc/html/rfc7539#section-2.1 the addition, + // xor'ing and rotation are all on the same line so i'm keeping it on the same + // line here as well + // @codingStandardsIgnoreStart + $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 16); + $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 12); + $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 8); + $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 7); + // @codingStandardsIgnoreEnd + } + + /** + * The doubleround function + * + * @param int $x0 (by reference) + * @param int $x1 (by reference) + * @param int $x2 (by reference) + * @param int $x3 (by reference) + * @param int $x4 (by reference) + * @param int $x5 (by reference) + * @param int $x6 (by reference) + * @param int $x7 (by reference) + * @param int $x8 (by reference) + * @param int $x9 (by reference) + * @param int $x10 (by reference) + * @param int $x11 (by reference) + * @param int $x12 (by reference) + * @param int $x13 (by reference) + * @param int $x14 (by reference) + * @param int $x15 (by reference) + */ + protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) + { + // columnRound + static::quarterRound($x0, $x4, $x8, $x12); + static::quarterRound($x1, $x5, $x9, $x13); + static::quarterRound($x2, $x6, $x10, $x14); + static::quarterRound($x3, $x7, $x11, $x15); + // rowRound + static::quarterRound($x0, $x5, $x10, $x15); + static::quarterRound($x1, $x6, $x11, $x12); + static::quarterRound($x2, $x7, $x8, $x13); + static::quarterRound($x3, $x4, $x9, $x14); + } + + /** + * The Salsa20 hash function function + * + * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in + * 0.65s vs the 0.85s that it takes with the parent method. + * + * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could + * be eliminated and we could knock this done to 0.60s. + * + * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s. + * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval + * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc + * + * @param string $x + */ + protected static function salsa20($x) + { + list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x); + $z0 = $x0; + $z1 = $x1; + $z2 = $x2; + $z3 = $x3; + $z4 = $x4; + $z5 = $x5; + $z6 = $x6; + $z7 = $x7; + $z8 = $x8; + $z9 = $x9; + $z10 = $x10; + $z11 = $x11; + $z12 = $x12; + $z13 = $x13; + $z14 = $x14; + $z15 = $x15; + + // @codingStandardsIgnoreStart + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + // @codingStandardsIgnoreEnd + + $x0 += $z0; + $x1 += $z1; + $x2 += $z2; + $x3 += $z3; + $x4 += $z4; + $x5 += $z5; + $x6 += $z6; + $x7 += $z7; + $x8 += $z8; + $x9 += $z9; + $x10 += $z10; + $x11 += $z11; + $x12 += $z12; + $x13 += $z13; + $x14 += $z14; + $x15 += $z15; + + return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php new file mode 100644 index 000000000..256c86906 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php @@ -0,0 +1,581 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Base Class for all asymmetric cipher classes + * + * @author Jim Wigginton + */ +abstract class AsymmetricKey +{ + /** + * Precomputed Zero + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $zero; + + /** + * Precomputed One + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $one; + + /** + * Format of the loaded key + * + * @var string + */ + protected $format; + + /** + * Hash function + * + * @var \phpseclib3\Crypt\Hash + */ + protected $hash; + + /** + * HMAC function + * + * @var \phpseclib3\Crypt\Hash + */ + private $hmac; + + /** + * Supported plugins (lower case) + * + * @see self::initialize_static_variables() + * @var array + */ + private static $plugins = []; + + /** + * Invisible plugins + * + * @see self::initialize_static_variables() + * @var array + */ + private static $invisiblePlugins = []; + + /** + * Available Engines + * + * @var boolean[] + */ + protected static $engines = []; + + /** + * Key Comment + * + * @var null|string + */ + private $comment; + + /** + * @param string $type + * @return string + */ + abstract public function toString($type, array $options = []); + + /** + * The constructor + */ + protected function __construct() + { + self::initialize_static_variables(); + + $this->hash = new Hash('sha256'); + $this->hmac = new Hash('sha256'); + } + + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$zero)) { + self::$zero = new BigInteger(0); + self::$one = new BigInteger(1); + } + + self::loadPlugins('Keys'); + if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { + self::loadPlugins('Signature'); + } + } + + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return \phpseclib3\Crypt\Common\PublicKey|\phpseclib3\Crypt\Common\PrivateKey + */ + public static function load($key, $password = false) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('load() should not be called from final classes (' . static::class . ')'); + } + + $components = false; + foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { + if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { + continue; + } + try { + $components = $format::load($key, $password); + } catch (\Exception $e) { + $components = false; + } + if ($components !== false) { + break; + } + } + + if ($components === false) { + throw new NoKeyLoadedException('Unable to read key'); + } + + $components['format'] = $format; + $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; + $comment = isset($components['comment']) ? $components['comment'] : null; + $new = static::onLoad($components); + $new->format = $format; + $new->comment = $comment; + return $new instanceof PrivateKey ? + $new->withPassword($password) : + $new; + } + + /** + * Loads a private key + * + * @return PrivateKey + * @param string|array $key + * @param string $password optional + */ + public static function loadPrivateKey($key, $password = '') + { + $key = self::load($key, $password); + if (!$key instanceof PrivateKey) { + throw new NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + + /** + * Loads a public key + * + * @return PublicKey + * @param string|array $key + */ + public static function loadPublicKey($key) + { + $key = self::load($key); + if (!$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string|array $key + */ + public static function loadParameters($key) + { + $key = self::load($key); + if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } + + /** + * Load the key, assuming a specific format + * + * @param string $type + * @param string $key + * @param string $password optional + * @return static + */ + public static function loadFormat($type, $key, $password = false) + { + self::initialize_static_variables(); + + $components = false; + $format = strtolower($type); + if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { + $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; + $components = $format::load($key, $password); + } + + if ($components === false) { + throw new NoKeyLoadedException('Unable to read key'); + } + + $components['format'] = $format; + $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; + + $new = static::onLoad($components); + $new->format = $format; + return $new instanceof PrivateKey ? + $new->withPassword($password) : + $new; + } + + /** + * Loads a private key + * + * @return PrivateKey + * @param string $type + * @param string $key + * @param string $password optional + */ + public static function loadPrivateKeyFormat($type, $key, $password = false) + { + $key = self::loadFormat($type, $key, $password); + if (!$key instanceof PrivateKey) { + throw new NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + + /** + * Loads a public key + * + * @return PublicKey + * @param string $type + * @param string $key + */ + public static function loadPublicKeyFormat($type, $key) + { + $key = self::loadFormat($type, $key); + if (!$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string $type + * @param string|array $key + */ + public static function loadParametersFormat($type, $key) + { + $key = self::loadFormat($type, $key); + if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } + + /** + * Validate Plugin + * + * @param string $format + * @param string $type + * @param string $method optional + * @return mixed + */ + protected static function validatePlugin($format, $type, $method = null) + { + $type = strtolower($type); + if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { + throw new UnsupportedFormatException("$type is not a supported format"); + } + $type = self::$plugins[static::ALGORITHM][$format][$type]; + if (isset($method) && !method_exists($type, $method)) { + throw new UnsupportedFormatException("$type does not implement $method"); + } + + return $type; + } + + /** + * Load Plugins + * + * @param string $format + */ + private static function loadPlugins($format) + { + if (!isset(self::$plugins[static::ALGORITHM][$format])) { + self::$plugins[static::ALGORITHM][$format] = []; + foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $name = $file->getBasename('.php'); + if ($name[0] == '.') { + continue; + } + $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; + $reflect = new \ReflectionClass($type); + if ($reflect->isTrait()) { + continue; + } + self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type; + if ($reflect->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM][] = $type; + } + } + } + } + + /** + * Returns a list of supported formats. + * + * @return array + */ + public static function getSupportedKeyFormats() + { + self::initialize_static_variables(); + + return self::$plugins[static::ALGORITHM]['Keys']; + } + + /** + * Add a fileformat plugin + * + * The plugin needs to either already be loaded or be auto-loadable. + * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. + * + * @see self::load() + * @param string $fullname + * @return bool + */ + public static function addFileFormat($fullname) + { + self::initialize_static_variables(); + + if (class_exists($fullname)) { + $meta = new \ReflectionClass($fullname); + $shortname = $meta->getShortName(); + self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; + if ($meta->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM] = strtolower($name); + } + } + } + + /** + * Returns the format of the loaded key. + * + * If the key that was loaded wasn't in a valid or if the key was auto-generated + * with RSA::createKey() then this will throw an exception. + * + * @see self::load() + * @return mixed + */ + public function getLoadedFormat() + { + if (empty($this->format)) { + throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); + } + + $meta = new \ReflectionClass($this->format); + return $meta->getShortName(); + } + + /** + * Returns the key's comment + * + * Not all key formats support comments. If you want to set a comment use toString() + * + * @return null|string + */ + public function getComment() + { + return $this->comment; + } + + /** + * Tests engine validity + * + */ + public static function useBestEngine() + { + static::$engines = [ + 'PHP' => true, + 'OpenSSL' => extension_loaded('openssl'), + // this test can be satisfied by either of the following: + // http://php.net/manual/en/book.sodium.php + // https://github.com/paragonie/sodium_compat + 'libsodium' => function_exists('sodium_crypto_sign_keypair') + ]; + + return static::$engines; + } + + /** + * Flag to use internal engine only (useful for unit testing) + * + */ + public static function useInternalEngine() + { + static::$engines = [ + 'PHP' => true, + 'OpenSSL' => false, + 'libsodium' => false + ]; + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return $this->toString('PKCS8'); + } + + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + $new->hash = new Hash($hash); + $new->hmac = new Hash($hash); + + return $new; + } + + /** + * Returns the hash algorithm currently being used + * + */ + public function getHash() + { + return clone $this->hash; + } + + /** + * Compute the pseudorandom k for signature generation, + * using the process specified for deterministic DSA. + * + * @param string $h1 + * @return string + */ + protected function computek($h1) + { + $v = str_repeat("\1", strlen($h1)); + + $k = str_repeat("\0", strlen($h1)); + + $x = $this->int2octets($this->x); + $h1 = $this->bits2octets($h1); + + $this->hmac->setKey($k); + $k = $this->hmac->hash($v . "\0" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + $k = $this->hmac->hash($v . "\1" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + + $qlen = $this->q->getLengthInBytes(); + + while (true) { + $t = ''; + while (strlen($t) < $qlen) { + $v = $this->hmac->hash($v); + $t = $t . $v; + } + $k = $this->bits2int($t); + + if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { + break; + } + $k = $this->hmac->hash($v . "\0"); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + } + + return $k; + } + + /** + * Integer to Octet String + * + * @param \phpseclib3\Math\BigInteger $v + * @return string + */ + private function int2octets($v) + { + $out = $v->toBytes(); + $rolen = $this->q->getLengthInBytes(); + if (strlen($out) < $rolen) { + return str_pad($out, $rolen, "\0", STR_PAD_LEFT); + } elseif (strlen($out) > $rolen) { + return substr($out, -$rolen); + } else { + return $out; + } + } + + /** + * Bit String to Integer + * + * @param string $in + * @return \phpseclib3\Math\BigInteger + */ + protected function bits2int($in) + { + $v = new BigInteger($in, 256); + $vlen = strlen($in) << 3; + $qlen = $this->q->getLength(); + if ($vlen > $qlen) { + return $v->bitwise_rightShift($vlen - $qlen); + } + return $v; + } + + /** + * Bit String to Octet String + * + * @param string $in + * @return string + */ + private function bits2octets($in) + { + $z1 = $this->bits2int($in); + $z2 = $z1->subtract($this->q); + return $z2->compare(self::$zero) < 0 ? + $this->int2octets($z1) : + $this->int2octets($z2); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php new file mode 100644 index 000000000..b2642be11 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php @@ -0,0 +1,24 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * Base Class for all block cipher classes + * + * @author Jim Wigginton + */ +abstract class BlockCipher extends SymmetricKey +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php new file mode 100644 index 000000000..4c761b839 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php @@ -0,0 +1,69 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; + +/** + * JSON Web Key Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class JWK +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $key = preg_replace('#\s#', '', $key); // remove whitespace + + if (PHP_VERSION_ID >= 73000) { + $key = json_decode($key, null, 512, JSON_THROW_ON_ERROR); + } else { + $key = json_decode($key); + if (!$key) { + throw new \RuntimeException('Unable to decode JSON'); + } + } + + if (isset($key->kty)) { + return $key; + } + + if (count($key->keys) != 1) { + throw new \RuntimeException('Although the JWK key format supports multiple keys phpseclib does not'); + } + + return $key->keys[0]; + } + + /** + * Wrap a key appropriately + * + * @return string + */ + protected static function wrapKey(array $key, array $options) + { + return json_encode(['keys' => [$key + $options]]); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..fe3d85bd6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php @@ -0,0 +1,220 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\Random; + +/** + * OpenSSH Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH +{ + /** + * Default comment + * + * @var string + */ + protected static $comment = 'phpseclib-generated-key'; + + /** + * Binary key flag + * + * @var bool + */ + protected static $binary = false; + + /** + * Sets the default comment + * + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = str_replace(["\r", "\n"], '', $comment); + } + + /** + * Break a public or private key down into its constituent components + * + * $type can be either ssh-dss or ssh-rsa + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + // key format is described here: + // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD + + if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { + $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); + $key = Strings::base64_decode($key); + $magic = Strings::shift($key, 15); + if ($magic != "openssh-key-v1\0") { + throw new \RuntimeException('Expected openssh-key-v1'); + } + list($ciphername, $kdfname, $kdfoptions, $numKeys) = Strings::unpackSSH2('sssN', $key); + if ($numKeys != 1) { + // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys + // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass + // that to the appropriate key loading parser $numKey times or something + throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); + } + switch ($ciphername) { + case 'none': + break; + case 'aes256-ctr': + if ($kdfname != 'bcrypt') { + throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)'); + } + list($salt, $rounds) = Strings::unpackSSH2('sN', $kdfoptions); + $crypto = new AES('ctr'); + //$crypto->setKeyLength(256); + //$crypto->disablePadding(); + $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); + break; + default: + throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)'); + } + + list($publicKey, $paddedKey) = Strings::unpackSSH2('ss', $key); + list($type) = Strings::unpackSSH2('s', $publicKey); + if (isset($crypto)) { + $paddedKey = $crypto->decrypt($paddedKey); + } + list($checkint1, $checkint2) = Strings::unpackSSH2('NN', $paddedKey); + // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. + if ($checkint1 != $checkint2) { + throw new \RuntimeException('The two checkints do not match'); + } + self::checkType($type); + + return compact('type', 'publicKey', 'paddedKey'); + } + + $parts = explode(' ', $key, 3); + + if (!isset($parts[1])) { + $key = base64_decode($parts[0]); + $comment = false; + } else { + $asciiType = $parts[0]; + self::checkType($parts[0]); + $key = base64_decode($parts[1]); + $comment = isset($parts[2]) ? $parts[2] : false; + } + if ($key === false) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + list($type) = Strings::unpackSSH2('s', $key); + self::checkType($type); + if (isset($asciiType) && $asciiType != $type) { + throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); + } + if (strlen($key) <= 4) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $publicKey = $key; + + return compact('type', 'publicKey', 'comment'); + } + + /** + * Toggle between binary and printable keys + * + * Printable keys are what are generated by default. These are the ones that go in + * $HOME/.ssh/authorized_key. + * + * @param bool $enabled + */ + public static function setBinaryOutput($enabled) + { + self::$binary = $enabled; + } + + /** + * Checks to see if the type is valid + * + * @param string $candidate + */ + private static function checkType($candidate) + { + if (!in_array($candidate, static::$types)) { + throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); + } + } + + /** + * Wrap a private key appropriately + * + * @param string $publicKey + * @param string $privateKey + * @param string $password + * @param array $options + * @return string + */ + protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) + { + list(, $checkint) = unpack('N', Random::string(4)); + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $paddedKey = Strings::packSSH2('NN', $checkint, $checkint) . + $privateKey . + Strings::packSSH2('s', $comment); + + $usesEncryption = !empty($password) && is_string($password); + + /* + from http://tools.ietf.org/html/rfc4253#section-6 : + + Note that the length of the concatenation of 'packet_length', + 'padding_length', 'payload', and 'random padding' MUST be a multiple + of the cipher block size or 8, whichever is larger. + */ + $blockSize = $usesEncryption ? 16 : 8; + $paddingLength = (($blockSize - 1) * strlen($paddedKey)) % $blockSize; + for ($i = 1; $i <= $paddingLength; $i++) { + $paddedKey .= chr($i); + } + if (!$usesEncryption) { + $key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); + } else { + $rounds = isset($options['rounds']) ? $options['rounds'] : 16; + $salt = Random::string(16); + $kdfoptions = Strings::packSSH2('sN', $salt, $rounds); + $crypto = new AES('ctr'); + $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); + $paddedKey = $crypto->encrypt($paddedKey); + $key = Strings::packSSH2('sssNss', 'aes256-ctr', 'bcrypt', $kdfoptions, 1, $publicKey, $paddedKey); + } + $key = "openssh-key-v1\0$key"; + + return "-----BEGIN OPENSSH PRIVATE KEY-----\n" . + chunk_split(Strings::base64_encode($key), 70, "\n") . + "-----END OPENSSH PRIVATE KEY-----\n"; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php new file mode 100644 index 000000000..0219400bc --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php @@ -0,0 +1,72 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +/** + * PKCS1 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS +{ + /** + * Auto-detect the format + */ + const MODE_ANY = 0; + /** + * Require base64-encoded PEM's be supplied + */ + const MODE_PEM = 1; + /** + * Require raw DER's be supplied + */ + const MODE_DER = 2; + /**#@-*/ + + /** + * Is the key a base-64 encoded PEM, DER or should it be auto-detected? + * + * @var int + */ + protected static $format = self::MODE_ANY; + + /** + * Require base64-encoded PEM's be supplied + * + */ + public static function requirePEM() + { + self::$format = self::MODE_PEM; + } + + /** + * Require raw DER's be supplied + * + */ + public static function requireDER() + { + self::$format = self::MODE_DER; + } + + /** + * Accept any format and auto detect the format + * + * This is the default setting + * + */ + public static function requireAny() + { + self::$format = self::MODE_ANY; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..4c639c05e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php @@ -0,0 +1,209 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\DES; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1; + +/** + * PKCS1 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends PKCS +{ + /** + * Default encryption algorithm + * + * @var string + */ + private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; + + /** + * Sets the default encryption algorithm + * + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + + /** + * Returns the mode constant corresponding to the mode string + * + * @param string $mode + * @return int + * @throws \UnexpectedValueException if the block cipher mode is unsupported + */ + private static function getEncryptionMode($mode) + { + switch ($mode) { + case 'CBC': + case 'ECB': + case 'CFB': + case 'OFB': + case 'CTR': + return $mode; + } + throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); + } + + /** + * Returns a cipher object corresponding to a string + * + * @param string $algo + * @return string + * @throws \UnexpectedValueException if the encryption algorithm is unsupported + */ + private static function getEncryptionObject($algo) + { + $modes = '(CBC|ECB|CFB|OFB|CTR)'; + switch (true) { + case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches): + $cipher = new AES(self::getEncryptionMode($matches[2])); + $cipher->setKeyLength($matches[1]); + return $cipher; + case preg_match("#^DES-EDE3-$modes$#", $algo, $matches): + return new TripleDES(self::getEncryptionMode($matches[1])); + case preg_match("#^DES-$modes$#", $algo, $matches): + return new DES(self::getEncryptionMode($matches[1])); + default: + throw new UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); + } + } + + /** + * Generate a symmetric key for PKCS#1 keys + * + * @param string $password + * @param string $iv + * @param int $length + * @return string + */ + private static function generateSymmetricKey($password, $iv, $length) + { + $symkey = ''; + $iv = substr($iv, 0, 8); + while (strlen($symkey) < $length) { + $symkey .= md5($symkey . $password . $iv, true); + } + return substr($symkey, 0, $length); + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is + "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to + protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding + two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: + + http://tools.ietf.org/html/rfc1421#section-4.6.1.1 + http://tools.ietf.org/html/rfc1421#section-4.6.1.3 + + DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. + DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation + function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's + own implementation. ie. the implementation *is* the standard and any bugs that may exist in that + implementation are part of the standard, as well. + + * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ + if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { + $iv = Strings::hex2bin(trim($matches[2])); + // remove the Proc-Type / DEK-Info sections as they're no longer needed + $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); + $ciphertext = ASN1::extractBER($key); + if ($ciphertext === false) { + $ciphertext = $key; + } + $crypto = self::getEncryptionObject($matches[1]); + $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); + $crypto->setIV($iv); + $key = $crypto->decrypt($ciphertext); + } else { + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + } + + return $key; + } + + /** + * Wrap a private key appropriately + * + * @param string $key + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $type, $password, array $options = []) + { + if (empty($password) || !is_string($password)) { + return "-----BEGIN $type PRIVATE KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END $type PRIVATE KEY-----"; + } + + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + + $cipher = self::getEncryptionObject($encryptionAlgorithm); + $iv = Random::string($cipher->getBlockLength() >> 3); + $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); + $cipher->setIV($iv); + $iv = strtoupper(Strings::bin2hex($iv)); + return "-----BEGIN $type PRIVATE KEY-----\r\n" . + "Proc-Type: 4,ENCRYPTED\r\n" . + "DEK-Info: " . $encryptionAlgorithm . ",$iv\r\n" . + "\r\n" . + chunk_split(Strings::base64_encode($cipher->encrypt($key)), 64) . + "-----END $type PRIVATE KEY-----"; + } + + /** + * Wrap a public key appropriately + * + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + return "-----BEGIN $type PUBLIC KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END $type PUBLIC KEY-----"; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..4638a5393 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -0,0 +1,724 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\DES; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RC2; +use phpseclib3\Crypt\RC4; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; + +/** + * PKCS#8 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends PKCS +{ + /** + * Default encryption algorithm + * + * @var string + */ + private static $defaultEncryptionAlgorithm = 'id-PBES2'; + + /** + * Default encryption scheme + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + */ + private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; + + /** + * Default PRF + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + */ + private static $defaultPRF = 'id-hmacWithSHA256'; + + /** + * Default Iteration Count + * + * @var int + */ + private static $defaultIterationCount = 2048; + + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = false; + + /** + * Sets the default encryption algorithm + * + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + + /** + * Sets the default encryption algorithm for PBES2 + * + * @param string $algo + */ + public static function setEncryptionScheme($algo) + { + self::$defaultEncryptionScheme = $algo; + } + + /** + * Sets the iteration count + * + * @param int $count + */ + public static function setIterationCount($count) + { + self::$defaultIterationCount = $count; + } + + /** + * Sets the PRF for PBES2 + * + * @param string $algo + */ + public static function setPRF($algo) + { + self::$defaultPRF = $algo; + } + + /** + * Returns a SymmetricKey object based on a PBES1 $algo + * + * @return \phpseclib3\Crypt\Common\SymmetricKey + * @param string $algo + */ + private static function getPBES1EncryptionObject($algo) + { + $algo = preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? + $matches[1] : + substr($algo, 13); // strlen('pbeWithSHAAnd') == 13 + + switch ($algo) { + case 'DES': + $cipher = new DES('cbc'); + break; + case 'RC2': + $cipher = new RC2('cbc'); + break; + case '3-KeyTripleDES': + $cipher = new TripleDES('cbc'); + break; + case '2-KeyTripleDES': + $cipher = new TripleDES('cbc'); + $cipher->setKeyLength(128); + break; + case '128BitRC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(128); + break; + case '40BitRC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(40); + break; + case '128BitRC4': + $cipher = new RC4(); + $cipher->setKeyLength(128); + break; + case '40BitRC4': + $cipher = new RC4(); + $cipher->setKeyLength(40); + break; + default: + throw new UnsupportedAlgorithmException("$algo is not a supported algorithm"); + } + + return $cipher; + } + + /** + * Returns a hash based on a PBES1 $algo + * + * @return string + * @param string $algo + */ + private static function getPBES1Hash($algo) + { + if (preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { + return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; + } + + return 'sha1'; + } + + /** + * Returns a KDF baesd on a PBES1 $algo + * + * @return string + * @param string $algo + */ + private static function getPBES1KDF($algo) + { + switch ($algo) { + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + return 'pbkdf1'; + } + + return 'pkcs12'; + } + + /** + * Returns a SymmetricKey object baesd on a PBES2 $algo + * + * @return SymmetricKey + * @param string $algo + */ + private static function getPBES2EncryptionObject($algo) + { + switch ($algo) { + case 'desCBC': + $cipher = new TripleDES('cbc'); + break; + case 'des-EDE3-CBC': + $cipher = new TripleDES('cbc'); + break; + case 'rc2CBC': + $cipher = new RC2('cbc'); + // in theory this can be changed + $cipher->setKeyLength(128); + break; + case 'rc5-CBC-PAD': + throw new UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); + case 'aes128-CBC-PAD': + case 'aes192-CBC-PAD': + case 'aes256-CBC-PAD': + $cipher = new AES('cbc'); + $cipher->setKeyLength(substr($algo, 3, 3)); + break; + default: + throw new UnsupportedAlgorithmException("$algo is not supported"); + } + + return $cipher; + } + + /** + * Initialize static variables + * + */ + private static function initialize_static_variables() + { + if (!isset(static::$childOIDsLoaded)) { + throw new InsufficientSetupException('This class should not be called directly'); + } + + if (!static::$childOIDsLoaded) { + ASN1::loadOIDs(is_array(static::OID_NAME) ? + array_combine(static::OID_NAME, static::OID_VALUE) : + [static::OID_NAME => static::OID_VALUE]); + static::$childOIDsLoaded = true; + } + if (!self::$oidsLoaded) { + // from https://tools.ietf.org/html/rfc2898 + ASN1::loadOIDs([ + // PBES1 encryption schemes + 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', + 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', + 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', + 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', + 'pbeWithSHA1AndDES-CBC' => '1.2.840.113549.1.5.10', + 'pbeWithSHA1AndRC2-CBC' => '1.2.840.113549.1.5.11', + + // from PKCS#12: + // https://tools.ietf.org/html/rfc7292 + 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', + 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', + 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', + 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', + 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', + 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', + + 'id-PBKDF2' => '1.2.840.113549.1.5.12', + 'id-PBES2' => '1.2.840.113549.1.5.13', + 'id-PBMAC1' => '1.2.840.113549.1.5.14', + + // from PKCS#5 v2.1: + // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf + 'id-hmacWithSHA1' => '1.2.840.113549.2.7', + 'id-hmacWithSHA224' => '1.2.840.113549.2.8', + 'id-hmacWithSHA256' => '1.2.840.113549.2.9', + 'id-hmacWithSHA384' => '1.2.840.113549.2.10', + 'id-hmacWithSHA512' => '1.2.840.113549.2.11', + 'id-hmacWithSHA512-224' => '1.2.840.113549.2.12', + 'id-hmacWithSHA512-256' => '1.2.840.113549.2.13', + + 'desCBC' => '1.3.14.3.2.7', + 'des-EDE3-CBC' => '1.2.840.113549.3.7', + 'rc2CBC' => '1.2.840.113549.3.2', + 'rc5-CBC-PAD' => '1.2.840.113549.3.9', + + 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', + 'aes192-CBC-PAD' => '2.16.840.1.101.3.4.1.22', + 'aes256-CBC-PAD' => '2.16.840.1.101.3.4.1.42' + ]); + self::$oidsLoaded = true; + } + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $isPublic = strpos($key, 'PUBLIC') !== false; + $isPrivate = strpos($key, 'PRIVATE') !== false; + + $decoded = self::preParse($key); + + $meta = []; + + $decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); + if (strlen($password) && is_array($decrypted)) { + $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; + switch ($algorithm) { + // PBES1 + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + case 'pbeWithSHAAnd3-KeyTripleDES-CBC': + case 'pbeWithSHAAnd2-KeyTripleDES-CBC': + case 'pbeWithSHAAnd128BitRC2-CBC': + case 'pbeWithSHAAnd40BitRC2-CBC': + case 'pbeWithSHAAnd128BitRC4': + case 'pbeWithSHAAnd40BitRC4': + $cipher = self::getPBES1EncryptionObject($algorithm); + $hash = self::getPBES1Hash($algorithm); + $kdf = self::getPBES1KDF($algorithm); + + $meta['meta']['algorithm'] = $algorithm; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); + $iterationCount = (int) $iterationCount->toString(); + $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER 2'); + } + + break; + case 'id-PBES2': + $meta['meta']['algorithm'] = $algorithm; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); + extract($temp); + + $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); + $meta['meta']['cipher'] = $encryptionScheme['algorithm']; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); + extract($temp); + + if (!$cipher instanceof RC2) { + $cipher->setIV($encryptionScheme['parameters']['octetString']); + } else { + $temp = ASN1::decodeBER($encryptionScheme['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); + $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); + switch ($effectiveKeyLength) { + case 160: + $effectiveKeyLength = 40; + break; + case 120: + $effectiveKeyLength = 64; + break; + case 58: + $effectiveKeyLength = 128; + break; + //default: // should be >= 256 + } + $cipher->setIV($iv); + $cipher->setKeyLength($effectiveKeyLength); + } + + $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; + switch ($keyDerivationFunc['algorithm']) { + case 'id-PBKDF2': + $temp = ASN1::decodeBER($keyDerivationFunc['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $prf = ['algorithm' => 'id-hmacWithSHA1']; + $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); + extract($params); + $meta['meta']['prf'] = $prf['algorithm']; + $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); + $params = [ + $password, + 'pbkdf2', + $hash, + $salt, + (int) $iterationCount->toString() + ]; + if (isset($keyLength)) { + $params[] = (int) $keyLength->toString(); + } + $cipher->setPassword(...$params); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER 3'); + } + break; + default: + throw new UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); + } + break; + case 'id-PBMAC1': + //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); + // since i can't find any implementation that does PBMAC1 it is unsupported + throw new UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); + // at this point we'll assume that the key conforms to PublicKeyInfo + } + } + + $private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP); + if (is_array($private)) { + if ($isPublic) { + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + + if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { + $temp = $decoded[0]['content'][1]['content'][1]; + $private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); + } + if (is_array(static::OID_NAME)) { + if (!in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($private['publicKey'])) { + if ($private['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); + } + $private['publicKey'] = substr($private['publicKey'], 1); + } + return $private + $meta; + } + + // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference + // is that the former has an octet string and the later has a bit string. the first byte of a bit + // string represents the number of bits in the last byte that are to be ignored but, currently, + // bit strings wanting a non-zero amount of bits trimmed are not supported + $public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP); + + if (is_array($public)) { + if ($isPrivate) { + throw new \UnexpectedValueException('Human readable string claims private key but DER encoded string claims public key'); + } + + if ($public['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); + } + if (is_array(static::OID_NAME)) { + if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { + $temp = $decoded[0]['content'][0]['content'][1]; + $public['publicKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); + } + $public['publicKey'] = substr($public['publicKey'], 1); + return $public; + } + + throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); + } + + /** + * Wrap a private key appropriately + * + * @param string $key + * @param string $attr + * @param mixed $params + * @param string $password + * @param string $oid optional + * @param string $publicKey optional + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) + { + self::initialize_static_variables(); + + $key = [ + 'version' => 'v1', + 'privateKeyAlgorithm' => [ + 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid + ], + 'privateKey' => $key + ]; + if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { + $key['privateKeyAlgorithm']['parameters'] = $params; + } + if (!empty($attr)) { + $key['attributes'] = $attr; + } + if (!empty($publicKey)) { + $key['version'] = 'v2'; + $key['publicKey'] = $publicKey; + } + $key = ASN1::encodeDER($key, Maps\OneAsymmetricKey::MAP); + if (!empty($password) && is_string($password)) { + $salt = Random::string(8); + + $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; + $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; + + if ($encryptionAlgorithm == 'id-PBES2') { + $crypto = self::getPBES2EncryptionObject($encryptionScheme); + $hash = str_replace('-', '/', substr($prf, 11)); + $kdf = 'pbkdf2'; + $iv = Random::string($crypto->getBlockLength() >> 3); + + $PBKDF2params = [ + 'salt' => $salt, + 'iterationCount' => $iterationCount, + 'prf' => ['algorithm' => $prf, 'parameters' => null] + ]; + $PBKDF2params = ASN1::encodeDER($PBKDF2params, Maps\PBKDF2params::MAP); + + if (!$crypto instanceof RC2) { + $params = ['octetString' => $iv]; + } else { + $params = [ + 'rc2ParametersVersion' => 58, + 'iv' => $iv + ]; + $params = ASN1::encodeDER($params, Maps\RC2CBCParameter::MAP); + $params = new ASN1\Element($params); + } + + $params = [ + 'keyDerivationFunc' => [ + 'algorithm' => 'id-PBKDF2', + 'parameters' => new ASN1\Element($PBKDF2params) + ], + 'encryptionScheme' => [ + 'algorithm' => $encryptionScheme, + 'parameters' => $params + ] + ]; + $params = ASN1::encodeDER($params, Maps\PBES2params::MAP); + + $crypto->setIV($iv); + } else { + $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); + $hash = self::getPBES1Hash($encryptionAlgorithm); + $kdf = self::getPBES1KDF($encryptionAlgorithm); + + $params = [ + 'salt' => $salt, + 'iterationCount' => $iterationCount + ]; + $params = ASN1::encodeDER($params, Maps\PBEParameter::MAP); + } + $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $crypto->encrypt($key); + + $key = [ + 'encryptionAlgorithm' => [ + 'algorithm' => $encryptionAlgorithm, + 'parameters' => new ASN1\Element($params) + ], + 'encryptedData' => $key + ]; + + $key = ASN1::encodeDER($key, Maps\EncryptedPrivateKeyInfo::MAP); + + return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END ENCRYPTED PRIVATE KEY-----"; + } + + return "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END PRIVATE KEY-----"; + } + + /** + * Wrap a public key appropriately + * + * @param string $key + * @param mixed $params + * @param string $oid + * @return string + */ + protected static function wrapPublicKey($key, $params, $oid = null) + { + self::initialize_static_variables(); + + $key = [ + 'publicKeyAlgorithm' => [ + 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid + ], + 'publicKey' => "\0" . $key + ]; + + if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { + $key['publicKeyAlgorithm']['parameters'] = $params; + } + + $key = ASN1::encodeDER($key, Maps\PublicKeyInfo::MAP); + + return "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + } + + /** + * Perform some preliminary parsing of the key + * + * @param string $key + * @return array + */ + private static function preParse(&$key) + { + self::initialize_static_variables(); + + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + return $decoded; + } + + /** + * Returns the encryption parameters used by the key + * + * @param string $key + * @return array + */ + public static function extractEncryptionAlgorithm($key) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $decoded = self::preParse($key); + + $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + if (!is_array($r)) { + throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); + } + + if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { + $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); + + $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; + switch ($kdf['algorithm']) { + case 'id-PBKDF2': + $decoded = ASN1::decodeBER($kdf['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); + } + } + + return $r['encryptionAlgorithm']; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..85da83a73 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php @@ -0,0 +1,374 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Exception\UnsupportedAlgorithmException; + +/** + * PuTTY Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY +{ + /** + * Default comment + * + * @var string + */ + private static $comment = 'phpseclib-generated-key'; + + /** + * Default version + * + * @var int + */ + private static $version = 2; + + /** + * Sets the default comment + * + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = str_replace(["\r", "\n"], '', $comment); + } + + /** + * Sets the default version + * + * @param int $version + */ + public static function setVersion($version) + { + if ($version != 2 && $version != 3) { + throw new \RuntimeException('Only supported versions are 2 and 3'); + } + self::$version = $version; + } + + /** + * Generate a symmetric key for PuTTY v2 keys + * + * @param string $password + * @param int $length + * @return string + */ + private static function generateV2Key($password, $length) + { + $symkey = ''; + $sequence = 0; + while (strlen($symkey) < $length) { + $temp = pack('Na*', $sequence++, $password); + $symkey .= Strings::hex2bin(sha1($temp)); + } + return substr($symkey, 0, $length); + } + + /** + * Generate a symmetric key for PuTTY v3 keys + * + * @param string $password + * @param string $flavour + * @param int $memory + * @param int $passes + * @param string $salt + * @return array + */ + private static function generateV3Key($password, $flavour, $memory, $passes, $salt) + { + if (!function_exists('sodium_crypto_pwhash')) { + throw new \RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing'); + } + + switch ($flavour) { + case 'Argon2i': + $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13; + break; + case 'Argon2id': + $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13; + break; + default: + throw new UnsupportedAlgorithmException('Only Argon2i and Argon2id are supported'); + } + + $length = 80; // keylen + ivlen + mac_keylen + $temp = sodium_crypto_pwhash($length, $password, $salt, $passes, $memory << 10, $flavour); + + $symkey = substr($temp, 0, 32); + $symiv = substr($temp, 32, 16); + $hashkey = substr($temp, -32); + + return compact('symkey', 'symiv', 'hashkey'); + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { + $lines = preg_split('#[\r\n]+#', $key); + switch (true) { + case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); + case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); + } + $lines = array_splice($lines, 1, -1); + $lines = array_map(function ($line) { + return rtrim($line, "\r\n"); + }, $lines); + $data = $current = ''; + $values = []; + $in_value = false; + foreach ($lines as $line) { + switch (true) { + case preg_match('#^(.*?): (.*)#', $line, $match): + $in_value = $line[strlen($line) - 1] == '\\'; + $current = strtolower($match[1]); + $values[$current] = $in_value ? substr($match[2], 0, -1) : $match[2]; + break; + case $in_value: + $in_value = $line[strlen($line) - 1] == '\\'; + $values[$current] .= $in_value ? substr($line, 0, -1) : $line; + break; + default: + $data .= $line; + } + } + + $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); + if ($components === false) { + throw new \UnexpectedValueException('Unable to decode public key'); + } + $components += $values; + $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); + + return $components; + } + + $components = []; + + $key = preg_split('#\r\n|\r|\n#', trim($key)); + if (Strings::shift($key[0], strlen('PuTTY-User-Key-File-')) != 'PuTTY-User-Key-File-') { + return false; + } + $version = (int) Strings::shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting + if ($version != 2 && $version != 3) { + throw new \RuntimeException('Only v2 and v3 PuTTY private keys are supported'); + } + $components['type'] = $type = rtrim($key[0]); + if (!in_array($type, static::$types)) { + $error = count(static::$types) == 1 ? + 'Only ' . static::$types[0] . ' keys are supported. ' : + ''; + throw new UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); + } + $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); + $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); + + $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); + $public = Strings::base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); + + $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); + + extract(unpack('Nlength', Strings::shift($public, 4))); + $newtype = Strings::shift($public, $length); + if ($newtype != $type) { + throw new \RuntimeException('The binary type does not match the human readable type field'); + } + + $components['public'] = $public; + + switch ($version) { + case 3: + $hashkey = ''; + break; + case 2: + $hashkey = 'putty-private-key-file-mac-key'; + } + + $offset = $publicLength + 4; + switch ($encryption) { + case 'aes256-cbc': + $crypto = new AES('cbc'); + switch ($version) { + case 3: + $flavour = trim(preg_replace('#Key-Derivation: (.*)#', '$1', $key[$offset++])); + $memory = trim(preg_replace('#Argon2-Memory: (\d+)#', '$1', $key[$offset++])); + $passes = trim(preg_replace('#Argon2-Passes: (\d+)#', '$1', $key[$offset++])); + $parallelism = trim(preg_replace('#Argon2-Parallelism: (\d+)#', '$1', $key[$offset++])); + $salt = Strings::hex2bin(trim(preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++]))); + + extract(self::generateV3Key($password, $flavour, $memory, $passes, $salt)); + + break; + case 2: + $symkey = self::generateV2Key($password, 32); + $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); + $hashkey .= $password; + } + } + + switch ($version) { + case 3: + $hash = new Hash('sha256'); + $hash->setKey($hashkey); + break; + case 2: + $hash = new Hash('sha1'); + $hash->setKey(sha1($hashkey, true)); + } + + $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$offset++])); + $private = Strings::base64_decode(implode('', array_map('trim', array_slice($key, $offset, $privateLength)))); + + if ($encryption != 'none') { + $crypto->setKey($symkey); + $crypto->setIV($symiv); + $crypto->disablePadding(); + $private = $crypto->decrypt($private); + } + + $source .= Strings::packSSH2('s', $private); + + $hmac = trim(preg_replace('#Private-MAC: (.+)#', '$1', $key[$offset + $privateLength])); + $hmac = Strings::hex2bin($hmac); + + if (!hash_equals($hash->hash($source), $hmac)) { + throw new \UnexpectedValueException('MAC validation error'); + } + + $components['private'] = $private; + + return $components; + } + + /** + * Wrap a private key appropriately + * + * @param string $public + * @param string $private + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) + { + $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $version = isset($options['version']) ? $options['version'] : self::$version; + + $key = "PuTTY-User-Key-File-$version: $type\r\n"; + $key .= "Encryption: $encryption\r\n"; + $key .= "Comment: $comment\r\n"; + + $public = Strings::packSSH2('s', $type) . $public; + + $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); + + $public = Strings::base64_encode($public); + $key .= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; + $key .= chunk_split($public, 64); + + if (empty($password) && !is_string($password)) { + $source .= Strings::packSSH2('s', $private); + switch ($version) { + case 3: + $hash = new Hash('sha256'); + $hash->setKey(''); + break; + case 2: + $hash = new Hash('sha1'); + $hash->setKey(sha1('putty-private-key-file-mac-key', true)); + } + } else { + $private .= Random::string(16 - (strlen($private) & 15)); + $source .= Strings::packSSH2('s', $private); + $crypto = new AES('cbc'); + + switch ($version) { + case 3: + $salt = Random::string(16); + $key .= "Key-Derivation: Argon2id\r\n"; + $key .= "Argon2-Memory: 8192\r\n"; + $key .= "Argon2-Passes: 13\r\n"; + $key .= "Argon2-Parallelism: 1\r\n"; + $key .= "Argon2-Salt: " . Strings::bin2hex($salt) . "\r\n"; + extract(self::generateV3Key($password, 'Argon2id', 8192, 13, $salt)); + + $hash = new Hash('sha256'); + $hash->setKey($hashkey); + + break; + case 2: + $symkey = self::generateV2Key($password, 32); + $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); + $hashkey = 'putty-private-key-file-mac-key' . $password; + + $hash = new Hash('sha1'); + $hash->setKey(sha1($hashkey, true)); + } + + $crypto->setKey($symkey); + $crypto->setIV($symiv); + $crypto->disablePadding(); + $private = $crypto->encrypt($private); + $mac = $hash->hash($source); + } + + $private = Strings::base64_encode($private); + $key .= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; + $key .= chunk_split($private, 64); + $key .= 'Private-MAC: ' . Strings::bin2hex($hash->hash($source)) . "\r\n"; + + return $key; + } + + /** + * Wrap a public key appropriately + * + * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) + * + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + $key = pack('Na*a*', strlen($type), $type, $key); + $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . + 'Comment: "' . str_replace(['\\', '"'], ['\\\\', '\"'], self::$comment) . "\"\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + '---- END SSH2 PUBLIC KEY ----'; + return $key; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php new file mode 100644 index 000000000..ab8e7e460 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php @@ -0,0 +1,60 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Signature; + +use phpseclib3\Math\BigInteger; + +/** + * Raw Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Loads a signature + * + * @param array $sig + * @return array|bool + */ + public static function load($sig) + { + switch (true) { + case !is_array($sig): + case !isset($sig['r']) || !isset($sig['s']): + case !$sig['r'] instanceof BigInteger: + case !$sig['s'] instanceof BigInteger: + return false; + } + + return [ + 'r' => $sig['r'], + 's' => $sig['s'] + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return compact('r', 's'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php new file mode 100644 index 000000000..a6e1eb0b4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php @@ -0,0 +1,31 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * PrivateKey interface + * + * @author Jim Wigginton + */ +interface PrivateKey +{ + public function sign($message); + //public function decrypt($ciphertext); + public function getPublicKey(); + public function toString($type, array $options = []); + + /** + * @param string|false $password + * @return mixed + */ + public function withPassword($password = false); +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php new file mode 100644 index 000000000..48a5875b1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php @@ -0,0 +1,25 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * PublicKey interface + * + * @author Jim Wigginton + */ +interface PublicKey +{ + public function verify($message, $signature); + //public function encrypt($plaintext); + public function toString($type, array $options = []); + public function getFingerprint($algorithm); +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php new file mode 100644 index 000000000..0e2d6f0c3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php @@ -0,0 +1,54 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * Base Class for all stream cipher classes + * + * @author Jim Wigginton + */ +abstract class StreamCipher extends SymmetricKey +{ + /** + * Block Length of the cipher + * + * Stream ciphers do not have a block size + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 0; + + /** + * Default Constructor. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @return \phpseclib3\Crypt\Common\StreamCipher + */ + public function __construct() + { + parent::__construct('stream'); + } + + /** + * Stream ciphers not use an IV + * + * @return bool + */ + public function usesIV() + { + return false; + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php similarity index 52% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php index 8822b9b88..00bfdd45c 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php @@ -1,32 +1,30 @@ * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton @@ -34,174 +32,250 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt\Common; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Blowfish; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\BadModeException; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\PrimeField; /** - * Base Class for all \phpseclib\Crypt\* cipher classes + * Base Class for all \phpseclib3\Crypt\* cipher classes * - * @package Base * @author Jim Wigginton * @author Hans-Juergen Petrich */ -abstract class Base +abstract class SymmetricKey { - /**#@+ - * @access public - * @see \phpseclib\Crypt\Base::encrypt() - * @see \phpseclib\Crypt\Base::decrypt() - */ /** * Encrypt / decrypt using the Counter mode. * * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CTR = -1; /** * Encrypt / decrypt using the Electronic Code Book mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_ECB = 1; /** * Encrypt / decrypt using the Code Book Chaining mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CBC = 2; /** * Encrypt / decrypt using the Cipher Feedback mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CFB = 3; /** * Encrypt / decrypt using the Cipher Feedback mode (8bit) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ - const MODE_CFB8 = 38; + const MODE_CFB8 = 7; + /** + * Encrypt / decrypt using the Output Feedback mode (8bit) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_OFB8 = 8; /** * Encrypt / decrypt using the Output Feedback mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_OFB = 4; /** - * Encrypt / decrypt using streaming mode. + * Encrypt / decrypt using Galois/Counter mode. + * + * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ - const MODE_STREAM = 5; - /**#@-*/ + const MODE_GCM = 5; + /** + * Encrypt / decrypt using streaming mode. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_STREAM = 6; /** - * Whirlpool available flag + * Mode Map * - * @see \phpseclib\Crypt\Base::_hashInlineCryptFunction() - * @var bool - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ - static $WHIRLPOOL_AVAILABLE; + const MODE_MAP = [ + 'ctr' => self::MODE_CTR, + 'ecb' => self::MODE_ECB, + 'cbc' => self::MODE_CBC, + 'cfb' => self::MODE_CFB, + 'cfb8' => self::MODE_CFB8, + 'ofb' => self::MODE_OFB, + 'ofb8' => self::MODE_OFB8, + 'gcm' => self::MODE_GCM, + 'stream' => self::MODE_STREAM + ]; - /**#@+ - * @access private - * @see \phpseclib\Crypt\Base::__construct() - */ /** * Base value for the internal implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_INTERNAL = 1; /** - * Base value for the mcrypt implementation $engine switch + * Base value for the eval() implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ - const ENGINE_MCRYPT = 2; + const ENGINE_EVAL = 2; /** * Base value for the mcrypt implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ - const ENGINE_OPENSSL = 3; - /**#@-*/ + const ENGINE_MCRYPT = 3; + /** + * Base value for the openssl implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL = 4; + /** + * Base value for the libsodium implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_LIBSODIUM = 5; + /** + * Base value for the openssl / gcm implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL_GCM = 6; + + /** + * Engine Reverse Map + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() + */ + const ENGINE_MAP = [ + self::ENGINE_INTERNAL => 'PHP', + self::ENGINE_EVAL => 'Eval', + self::ENGINE_MCRYPT => 'mcrypt', + self::ENGINE_OPENSSL => 'OpenSSL', + self::ENGINE_LIBSODIUM => 'libsodium', + self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' + ]; /** * The Encryption Mode * * @see self::__construct() * @var int - * @access private */ - var $mode; + protected $mode; /** * The Block Length of the block cipher * * @var int - * @access private */ - var $block_size = 16; + protected $block_size = 16; /** * The Key * * @see self::setKey() * @var string - * @access private */ - var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + protected $key = false; + + /** + * HMAC Key + * + * @see self::setupGCM() + * @var ?string + */ + protected $hKey = false; /** * The Initialization Vector * * @see self::setIV() * @var string - * @access private */ - var $iv; + protected $iv = false; /** * A "sliding" Initialization Vector * * @see self::enableContinuousBuffer() - * @see self::_clearBuffers() + * @see self::clearBuffers() * @var string - * @access private */ - var $encryptIV; + protected $encryptIV; /** * A "sliding" Initialization Vector * * @see self::enableContinuousBuffer() - * @see self::_clearBuffers() + * @see self::clearBuffers() * @var string - * @access private */ - var $decryptIV; + protected $decryptIV; /** * Continuous Buffer status * * @see self::enableContinuousBuffer() * @var bool - * @access private */ - var $continuousBuffer = false; + protected $continuousBuffer = false; /** * Encryption buffer for CTR, OFB and CFB modes * * @see self::encrypt() - * @see self::_clearBuffers() + * @see self::clearBuffers() * @var array - * @access private */ - var $enbuffer; + protected $enbuffer; /** * Decryption buffer for CTR, OFB and CFB modes * * @see self::decrypt() - * @see self::_clearBuffers() + * @see self::clearBuffers() * @var array - * @access private */ - var $debuffer; + protected $debuffer; /** * mcrypt resource for encryption @@ -211,9 +285,8 @@ abstract class Base * * @see self::encrypt() * @var resource - * @access private */ - var $enmcrypt; + private $enmcrypt; /** * mcrypt resource for decryption @@ -223,29 +296,26 @@ abstract class Base * * @see self::decrypt() * @var resource - * @access private */ - var $demcrypt; + private $demcrypt; /** * Does the enmcrypt resource need to be (re)initialized? * - * @see \phpseclib\Crypt\Twofish::setKey() - * @see \phpseclib\Crypt\Twofish::setIV() + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() * @var bool - * @access private */ - var $enchanged = true; + private $enchanged = true; /** * Does the demcrypt resource need to be (re)initialized? * - * @see \phpseclib\Crypt\Twofish::setKey() - * @see \phpseclib\Crypt\Twofish::setIV() + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() * @var bool - * @access private */ - var $dechanged = true; + private $dechanged = true; /** * mcrypt resource for CFB mode @@ -260,11 +330,10 @@ abstract class Base * @link http://phpseclib.sourceforge.net/cfb-demo.phps * @see self::encrypt() * @see self::decrypt() - * @see self::_setupMcrypt() + * @see self::setupMcrypt() * @var resource - * @access private */ - var $ecb; + private $ecb; /** * Optimizing value while CFB-encrypting @@ -284,9 +353,8 @@ abstract class Base * * @see self::encrypt() * @var int - * @access private */ - var $cfb_init_len = 600; + protected $cfb_init_len = 600; /** * Does internal cipher state need to be (re)initialized? @@ -295,54 +363,60 @@ abstract class Base * @see self::setIV() * @see self::disableContinuousBuffer() * @var bool - * @access private */ - var $changed = true; + protected $changed = true; + + /** + * Does Eval engie need to be (re)initialized? + * + * @see self::setup() + * @var bool + */ + protected $nonIVChanged = true; /** * Padding status * * @see self::enablePadding() * @var bool - * @access private */ - var $padding = true; + private $padding = true; /** * Is the mode one that is paddable? * * @see self::__construct() * @var bool - * @access private */ - var $paddable = false; + private $paddable = false; /** * Holds which crypt engine internaly should be use, * which will be determined automatically on __construct() * * Currently available $engines are: - * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) - * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) + * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) + * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) + * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) + * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) * - * @see self::_setEngine() + * @see self::setEngine() * @see self::encrypt() * @see self::decrypt() * @var int - * @access private */ - var $engine; + protected $engine; /** * Holds the preferred crypt engine * - * @see self::_setEngine() + * @see self::setEngine() * @see self::setPreferredEngine() * @var int - * @access private */ - var $preferredEngine; + private $preferredEngine; /** * The mcrypt specific name of the cipher @@ -351,11 +425,10 @@ abstract class Base * * @link http://www.php.net/mcrypt_module_open * @link http://www.php.net/mcrypt_list_algorithms - * @see self::_setupMcrypt() + * @see self::setupMcrypt() * @var string - * @access private */ - var $cipher_name_mcrypt; + protected $cipher_name_mcrypt; /** * The openssl specific name of the cipher @@ -364,9 +437,8 @@ abstract class Base * * @link http://www.php.net/openssl-get-cipher-methods * @var string - * @access private */ - var $cipher_name_openssl; + protected $cipher_name_openssl; /** * The openssl specific name of the cipher in ECB mode @@ -376,18 +448,16 @@ abstract class Base * * @link http://www.php.net/openssl-get-cipher-methods * @var string - * @access private */ - var $cipher_name_openssl_ecb; + protected $cipher_name_openssl_ecb; /** * The default salt used by setPassword() * * @see self::setPassword() * @var string - * @access private */ - var $password_default_salt = 'phpseclib/salt'; + private $password_default_salt = 'phpseclib/salt'; /** * The name of the performance-optimized callback function @@ -397,148 +467,372 @@ abstract class Base * * @see self::encrypt() * @see self::decrypt() - * @see self::_setupInlineCrypt() - * @see self::$use_inline_crypt + * @see self::setupInlineCrypt() * @var Callback - * @access private */ - var $inline_crypt; - - /** - * Holds whether performance-optimized $inline_crypt() can/should be used. - * - * @see self::encrypt() - * @see self::decrypt() - * @see self::inline_crypt - * @var mixed - * @access private - */ - var $use_inline_crypt = true; + protected $inline_crypt; /** * If OpenSSL can be used in ECB but not in CTR we can emulate CTR * - * @see self::_openssl_ctr_process() + * @see self::openssl_ctr_process() * @var bool - * @access private */ - var $openssl_emulate_ctr = false; + private $openssl_emulate_ctr = false; /** - * Determines what options are passed to openssl_encrypt/decrypt + * Don't truncate / null pad key * - * @see self::isValidEngine() - * @var mixed - * @access private + * @see self::clearBuffers() + * @var bool */ - var $openssl_options; + private $skip_key_adjustment = false; /** * Has the key length explicitly been set or should it be derived from the key, itself? * * @see self::setKeyLength() * @var bool - * @access private */ - var $explicit_key_length = false; + protected $explicit_key_length = false; /** - * Don't truncate / null pad key + * Hash subkey for GHASH * - * @see self::_clearBuffers() - * @var bool - * @access private + * @see self::setupGCM() + * @see self::ghash() + * @var BinaryField\Integer */ - var $skip_key_adjustment = false; + private $h; + + /** + * Additional authenticated data + * + * @var string + */ + protected $aad = ''; + + /** + * Authentication Tag produced after a round of encryption + * + * @var string + */ + protected $newtag = false; + + /** + * Authentication Tag to be verified during decryption + * + * @var string + */ + protected $oldtag = false; + + /** + * GCM Binary Field + * + * @see self::__construct() + * @see self::ghash() + * @var BinaryField + */ + private static $gcmField; + + /** + * Poly1305 Prime Field + * + * @see self::enablePoly1305() + * @see self::poly1305() + * @var PrimeField + */ + private static $poly1305Field; + + /** + * Flag for using regular vs "safe" intval + * + * @see self::initialize_static_variables() + * @var boolean + */ + protected static $use_reg_intval; + + /** + * Poly1305 Key + * + * @see self::setPoly1305Key() + * @see self::poly1305() + * @var string + */ + protected $poly1305Key; + + /** + * Poly1305 Flag + * + * @see self::setPoly1305Key() + * @see self::enablePoly1305() + * @var boolean + */ + protected $usePoly1305 = false; + + /** + * The Original Initialization Vector + * + * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived + * IV's and user-set IV's + * + * @see self::setIV() + * @var string + */ + private $origIV = false; + + /** + * Nonce + * + * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and + * toggling between GCM and other modes could be more complicated if we re-used setIV() + * + * @see self::setNonce() + * @var string + */ + protected $nonce = false; /** * Default Constructor. * - * Determines whether or not the mcrypt extension should be used. - * * $mode could be: * - * - self::MODE_ECB + * - ecb * - * - self::MODE_CBC + * - cbc * - * - self::MODE_CTR + * - ctr * - * - self::MODE_CFB + * - cfb * - * - self::MODE_OFB + * - cfb8 * - * If not explicitly set, self::MODE_CBC will be used. + * - ofb * - * @param int $mode - * @access public + * - ofb8 + * + * - gcm + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided */ - function __construct($mode = self::MODE_CBC) + public function __construct($mode) { + $mode = strtolower($mode); + // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 + $map = self::MODE_MAP; + if (!isset($map[$mode])) { + throw new BadModeException('No valid mode has been specified'); + } + + $mode = self::MODE_MAP[$mode]; + // $mode dependent settings switch ($mode) { case self::MODE_ECB: + case self::MODE_CBC: $this->paddable = true; - $this->mode = self::MODE_ECB; break; case self::MODE_CTR: case self::MODE_CFB: case self::MODE_CFB8: case self::MODE_OFB: + case self::MODE_OFB8: case self::MODE_STREAM: - $this->mode = $mode; + $this->paddable = false; + break; + case self::MODE_GCM: + if ($this->block_size != 16) { + throw new BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); + } + if (!isset(self::$gcmField)) { + self::$gcmField = new BinaryField(128, 7, 2, 1, 0); + } + $this->paddable = false; break; - case self::MODE_CBC: default: - $this->paddable = true; - $this->mode = self::MODE_CBC; + throw new BadModeException('No valid mode has been specified'); } - $this->_setEngine(); + $this->mode = $mode; + + static::initialize_static_variables(); } /** - * Sets the initialization vector. (optional) - * - * SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed - * to be all zero's. - * - * @access public - * @param string $iv - * @internal Can be overwritten by a sub class, but does not have to be + * Initialize static variables */ - function setIV($iv) + protected static function initialize_static_variables() + { + if (!isset(self::$use_reg_intval)) { + switch (true) { + // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster + case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': + case !(is_string(php_uname('m')) && (php_uname('m') & "\xDF\xDF\xDF") == 'ARM'): + case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: + self::$use_reg_intval = true; + break; + case is_string(php_uname('m')) && (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': + switch (true) { + /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: + + https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd + + altho the changelogs make no mention of it, this bug was fixed with this commit: + + https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 + + affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ + case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: + case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: + self::$use_reg_intval = false; + break; + default: + self::$use_reg_intval = true; + } + } + } + } + + /** + * Sets the initialization vector. + * + * setIV() is not required when ecb or gcm modes are being used. + * + * {@internal Can be overwritten by a sub class, but does not have to be} + * + * @param string $iv + * @throws \LengthException if the IV length isn't equal to the block size + * @throws \BadMethodCallException if an IV is provided when one shouldn't be + */ + public function setIV($iv) { if ($this->mode == self::MODE_ECB) { - return; + throw new \BadMethodCallException('This mode does not require an IV.'); } - $this->iv = $iv; + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Use setNonce instead'); + } + + if (!$this->usesIV()) { + throw new \BadMethodCallException('This algorithm does not use an IV.'); + } + + if (strlen($iv) != $this->block_size) { + throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); + } + + $this->iv = $this->origIV = $iv; $this->changed = true; } /** - * Sets the key length. + * Enables Poly1305 mode. * - * Keys with explicitly set lengths need to be treated accordingly + * Once enabled Poly1305 cannot be disabled. * - * @access public - * @param int $length + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode */ - function setKeyLength($length) + public function enablePoly1305() { - $this->explicit_key_length = true; - $this->changed = true; - $this->_setEngine(); + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + + $this->usePoly1305 = true; + } + + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key + * will be made. + * + * @param string $key optional + * @throws \LengthException if the key isn't long enough + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function setPoly1305Key($key = null) + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + + if (!is_string($key) || strlen($key) != 32) { + throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); + } + + if (!isset(self::$poly1305Field)) { + // 2^130-5 + self::$poly1305Field = new PrimeField(new BigInteger('3fffffffffffffffffffffffffffffffb', 16)); + } + + $this->poly1305Key = $key; + $this->usePoly1305 = true; + } + + /** + * Sets the nonce. + * + * setNonce() is only required when gcm is used + * + * @param string $nonce + * @throws \BadMethodCallException if an nonce is provided when one shouldn't be + */ + public function setNonce($nonce) + { + if ($this->mode != self::MODE_GCM) { + throw new \BadMethodCallException('Nonces are only used in GCM mode.'); + } + + $this->nonce = $nonce; + $this->setEngine(); + } + + /** + * Sets additional authenticated data + * + * setAAD() is only used by gcm or in poly1305 mode + * + * @param string $aad + * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized + */ + public function setAAD($aad) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); + } + + $this->aad = $aad; + } + + /** + * Returns whether or not the algorithm uses an IV + * + * @return bool + */ + public function usesIV() + { + return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; + } + + /** + * Returns whether or not the algorithm uses a nonce + * + * @return bool + */ + public function usesNonce() + { + return $this->mode == self::MODE_GCM; } /** * Returns the current key length in bits * - * @access public * @return int */ - function getKeyLength() + public function getKeyLength() { return $this->key_length << 3; } @@ -546,14 +840,40 @@ abstract class Base /** * Returns the current block length in bits * - * @access public * @return int */ - function getBlockLength() + public function getBlockLength() { return $this->block_size << 3; } + /** + * Returns the current block length in bytes + * + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->block_size; + } + + /** + * Sets the key length. + * + * Keys with explicitly set lengths need to be treated accordingly + * + * @param int $length + */ + public function setKeyLength($length) + { + $this->explicit_key_length = $length >> 3; + + if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) { + $this->key = false; + throw new InconsistentSetupException('Key has already been set and is not ' . $this->explicit_key_length . ' bytes long'); + } + } + /** * Sets the key. * @@ -564,20 +884,19 @@ abstract class Base * * If the key is not explicitly set, it'll be assumed to be all null bytes. * - * @access public + * {@internal Could, but not must, extend by the child Crypt_* class} + * * @param string $key - * @internal Could, but not must, extend by the child Crypt_* class */ - function setKey($key) + public function setKey($key) { - if (!$this->explicit_key_length) { - $this->setKeyLength(strlen($key) << 3); - $this->explicit_key_length = false; + if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { + throw new InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); } $this->key = $key; - $this->changed = true; - $this->_setEngine(); + $this->key_length = strlen($key); + $this->setEngine(); } /** @@ -588,46 +907,128 @@ abstract class Base * $hash, $salt, $count, $dkLen * * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php + * {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}: + * $salt, $rounds, $keylen + * + * This is a modified version of bcrypt used by OpenSSH. + * + * {@internal Could, but not must, extend by the child Crypt_* class} * * @see Crypt/Hash.php * @param string $password * @param string $method + * @param int|string ...$func_args + * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length + * @throws \RuntimeException if bcrypt is being used and a salt isn't provided * @return bool - * @access public - * @internal Could, but not must, extend by the child Crypt_* class */ - function setPassword($password, $method = 'pbkdf2') + public function setPassword($password, $method = 'pbkdf2', ...$func_args) { $key = ''; + $method = strtolower($method); switch ($method) { - default: // 'pbkdf2' or 'pbkdf1' - $func_args = func_get_args(); + case 'bcrypt': + if (!isset($func_args[2])) { + throw new \RuntimeException('A salt must be provided for bcrypt to work'); + } + $salt = $func_args[0]; + + $rounds = isset($func_args[1]) ? $func_args[1] : 16; + $keylen = isset($func_args[2]) ? $func_args[2] : $this->key_length; + + $key = Blowfish::bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds); + + $this->setKey(substr($key, 0, $keylen)); + $this->setIV(substr($key, $keylen)); + + return true; + case 'pkcs12': // from https://tools.ietf.org/html/rfc7292#appendix-B.2 + case 'pbkdf1': + case 'pbkdf2': // Hash function - $hash = isset($func_args[2]) ? $func_args[2] : 'sha1'; + $hash = isset($func_args[0]) ? strtolower($func_args[0]) : 'sha1'; + $hashObj = new Hash(); + $hashObj->setHash($hash); // WPA and WPA2 use the SSID as the salt - $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt; + $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; // RFC2898#section-4.2 uses 1,000 iterations by default // WPA and WPA2 use 4,096. - $count = isset($func_args[4]) ? $func_args[4] : 1000; + $count = isset($func_args[2]) ? $func_args[2] : 1000; // Keylength - if (isset($func_args[5])) { - $dkLen = $func_args[5]; + if (isset($func_args[3])) { + if ($func_args[3] <= 0) { + throw new \LengthException('Derived key length cannot be longer 0 or less'); + } + $dkLen = $func_args[3]; } else { - $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length; + $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length; + $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; } switch (true) { + case $method == 'pkcs12': + /* + In this specification, however, all passwords are created from + BMPStrings with a NULL terminator. This means that each character in + the original BMPString is encoded in 2 bytes in big-endian format + (most-significant byte first). There are no Unicode byte order + marks. The 2 bytes produced from the last character in the BMPString + are followed by 2 additional bytes with the value 0x00. + + -- https://tools.ietf.org/html/rfc7292#appendix-B.1 + */ + $password = "\0" . chunk_split($password, 1, "\0") . "\0"; + + /* + This standard specifies 3 different values for the ID byte mentioned + above: + + 1. If ID=1, then the pseudorandom bits being produced are to be used + as key material for performing encryption or decryption. + + 2. If ID=2, then the pseudorandom bits being produced are to be used + as an IV (Initial Value) for encryption or decryption. + + 3. If ID=3, then the pseudorandom bits being produced are to be used + as an integrity key for MACing. + */ + // Construct a string, D (the "diversifier"), by concatenating v/8 + // copies of ID. + $blockLength = $hashObj->getBlockLengthInBytes(); + $d1 = str_repeat(chr(1), $blockLength); + $d2 = str_repeat(chr(2), $blockLength); + $s = ''; + if (strlen($salt)) { + while (strlen($s) < $blockLength) { + $s .= $salt; + } + } + $s = substr($s, 0, $blockLength); + + $p = ''; + if (strlen($password)) { + while (strlen($p) < $blockLength) { + $p .= $password; + } + } + $p = substr($p, 0, $blockLength); + + $i = $s . $p; + + $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); + if ($this->usesIV()) { + $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); + } + + return true; case $method == 'pbkdf1': - $hashObj = new Hash(); - $hashObj->setHash($hash); - if ($dkLen > $hashObj->getLength()) { - user_error('Derived key too long'); - return false; + if ($dkLen > $hashObj->getLengthInBytes()) { + throw new \LengthException('Derived key length cannot be longer than the hash length'); } $t = $password . $salt; for ($i = 0; $i < $count; ++$i) { @@ -636,30 +1037,30 @@ abstract class Base $key = substr($t, 0, $dkLen); $this->setKey(substr($key, 0, $dkLen >> 1)); - $this->setIV(substr($key, $dkLen >> 1)); + if ($this->usesIV()) { + $this->setIV(substr($key, $dkLen >> 1)); + } return true; - // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable - case !function_exists('hash_pbkdf2'): - case !function_exists('hash_algos'): case !in_array($hash, hash_algos()): $i = 1; - $hmac = new Hash(); - $hmac->setHash($hash); - $hmac->setKey($password); + $hashObj->setKey($password); while (strlen($key) < $dkLen) { - $f = $u = $hmac->hash($salt . pack('N', $i++)); + $f = $u = $hashObj->hash($salt . pack('N', $i++)); for ($j = 2; $j <= $count; ++$j) { - $u = $hmac->hash($u); - $f^= $u; + $u = $hashObj->hash($u); + $f ^= $u; } - $key.= $f; + $key .= $f; } $key = substr($key, 0, $dkLen); break; default: $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); } + break; + default: + throw new UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); } $this->setKey($key); @@ -667,6 +1068,59 @@ abstract class Base return true; } + /** + * PKCS#12 KDF Helper Function + * + * As discussed here: + * + * {@link https://tools.ietf.org/html/rfc7292#appendix-B} + * + * @see self::setPassword() + * @param int $n + * @param \phpseclib3\Crypt\Hash $hashObj + * @param string $i + * @param string $d + * @param int $count + * @return string $a + */ + private static function pkcs12helper($n, $hashObj, $i, $d, $count) + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $blockLength = $hashObj->getBlockLength() >> 3; + + $c = ceil($n / $hashObj->getLengthInBytes()); + $a = ''; + for ($j = 1; $j <= $c; $j++) { + $ai = $d . $i; + for ($k = 0; $k < $count; $k++) { + $ai = $hashObj->hash($ai); + } + $b = ''; + while (strlen($b) < $blockLength) { + $b .= $ai; + } + $b = substr($b, 0, $blockLength); + $b = new BigInteger($b, 256); + $newi = ''; + for ($k = 0; $k < strlen($i); $k += $blockLength) { + $temp = substr($i, $k, $blockLength); + $temp = new BigInteger($temp, 256); + $temp->setPrecision($blockLength << 3); + $temp = $temp->add($b); + $temp = $temp->add($one); + $newi .= $temp->toBytes(false); + } + $i = $newi; + $a .= $ai; + } + + return substr($a, 0, $n); + } + /** * Encrypts a message. * @@ -681,40 +1135,62 @@ abstract class Base * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that * length. * + * {@internal Could, but not must, extend by the child Crypt_* class} + * * @see self::decrypt() - * @access public * @param string $plaintext * @return string $ciphertext - * @internal Could, but not must, extend by the child Crypt_* class */ - function encrypt($plaintext) + public function encrypt($plaintext) { if ($this->paddable) { - $plaintext = $this->_pad($plaintext); + $plaintext = $this->pad($plaintext); + } + + $this->setup(); + + if ($this->mode == self::MODE_GCM) { + $oldIV = $this->iv; + Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $ciphertext = $cipher->encrypt($plaintext); + + $s = $this->ghash( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + self::len64($this->aad) . + self::len64($ciphertext) + ); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $this->newtag = $cipher->encrypt($s); + return $ciphertext; + } + + if (isset($this->poly1305Key)) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = false; + $ciphertext = $cipher->encrypt($plaintext); + $this->newtag = $this->poly1305($ciphertext); + return $ciphertext; } if ($this->engine === self::ENGINE_OPENSSL) { - if ($this->changed) { - $this->_clearBuffers(); - $this->changed = false; - } switch ($this->mode) { case self::MODE_STREAM: - return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); case self::MODE_ECB: - $result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options); - return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); case self::MODE_CBC: - $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); - if (!defined('OPENSSL_RAW_DATA')) { - $result = substr($result, 0, -$this->block_size); - } + $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); if ($this->continuousBuffer) { $this->encryptIV = substr($result, -$this->block_size); } return $result; case self::MODE_CTR: - return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); + return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); case self::MODE_CFB: // cfb loosely routines inspired by openssl's: // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} @@ -733,11 +1209,11 @@ abstract class Base $max = $this->block_size - $pos; if ($len >= $max) { $i = $max; - $len-= $max; + $len -= $max; $pos = 0; } else { $i = $len; - $pos+= $len; + $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize @@ -749,22 +1225,22 @@ abstract class Base $overflow = $len % $this->block_size; if ($overflow) { - $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); - $iv = $this->_string_pop($ciphertext, $this->block_size); + $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = Strings::pop($ciphertext, $this->block_size); $size = $len - $overflow; $block = $iv ^ substr($plaintext, -$overflow); $iv = substr_replace($iv, $block, 0, $overflow); - $ciphertext.= $block; + $ciphertext .= $block; $pos = $overflow; } elseif ($len) { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $iv = substr($ciphertext, -$this->block_size); } return $ciphertext; case self::MODE_CFB8: - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV); + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); if ($this->continuousBuffer) { if (($len = strlen($ciphertext)) >= $this->block_size) { $this->encryptIV = substr($ciphertext, -$this->block_size); @@ -773,20 +1249,31 @@ abstract class Base } } return $ciphertext; + case self::MODE_OFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); + $ciphertext .= $plaintext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; case self::MODE_OFB: - return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); + return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); } } if ($this->engine === self::ENGINE_MCRYPT) { - set_error_handler(array($this, 'do_nothing')); - - if ($this->changed) { - $this->_setupMcrypt(); - $this->changed = false; - } + set_error_handler(function () { + }); if ($this->enchanged) { - mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); $this->enchanged = false; } @@ -805,11 +1292,11 @@ abstract class Base $max = $block_size - $pos; if ($len >= $max) { $i = $max; - $len-= $max; + $len -= $max; $pos = 0; } else { $i = $len; - $pos+= $len; + $pos += $len; $len = 0; } $ciphertext = substr($iv, $orig_pos) ^ $plaintext; @@ -822,15 +1309,15 @@ abstract class Base mcrypt_generic_init($this->enmcrypt, $this->key, $iv); $this->enbuffer['enmcrypt_init'] = false; } - $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); + $ciphertext .= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); $iv = substr($ciphertext, -$block_size); - $len%= $block_size; + $len %= $block_size; } else { while ($len >= $block_size) { $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); - $ciphertext.= $iv; - $len-= $block_size; - $i+= $block_size; + $ciphertext .= $iv; + $len -= $block_size; + $i += $block_size; } } } @@ -839,7 +1326,7 @@ abstract class Base $iv = mcrypt_generic($this->ecb, $iv); $block = $iv ^ substr($plaintext, -$len); $iv = substr_replace($iv, $block, 0, $len); - $ciphertext.= $block; + $ciphertext .= $block; $pos = $len; } @@ -851,7 +1338,7 @@ abstract class Base $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); if (!$this->continuousBuffer) { - mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); } restore_error_handler(); @@ -859,13 +1346,9 @@ abstract class Base return $ciphertext; } - if ($this->changed) { - $this->_setup(); - $this->changed = false; - } - if ($this->use_inline_crypt) { + if ($this->engine === self::ENGINE_EVAL) { $inline = $this->inline_crypt; - return $inline('encrypt', $this, $plaintext); + return $inline('encrypt', $plaintext); } $buffer = &$this->enbuffer; @@ -873,17 +1356,17 @@ abstract class Base $ciphertext = ''; switch ($this->mode) { case self::MODE_ECB: - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size)); + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $ciphertext .= $this->encryptBlock(substr($plaintext, $i, $block_size)); } break; case self::MODE_CBC: $xor = $this->encryptIV; - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); - $block = $this->_encryptBlock($block ^ $xor); + $block = $this->encryptBlock($block ^ $xor); $xor = $block; - $ciphertext.= $block; + $ciphertext .= $block; } if ($this->continuousBuffer) { $this->encryptIV = $xor; @@ -892,21 +1375,21 @@ abstract class Base case self::MODE_CTR: $xor = $this->encryptIV; if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'].= $this->_encryptBlock($xor); + $buffer['ciphertext'] .= $this->encryptBlock($xor); + Strings::increment_str($xor); } - $this->_increment_str($xor); - $key = $this->_string_shift($buffer['ciphertext'], $block_size); - $ciphertext.= $block ^ $key; + $key = Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext .= $block ^ $key; } } else { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); - $key = $this->_encryptBlock($xor); - $this->_increment_str($xor); - $ciphertext.= $block ^ $key; + $key = $this->encryptBlock($xor); + Strings::increment_str($xor); + $ciphertext .= $block ^ $key; } } if ($this->continuousBuffer) { @@ -933,11 +1416,11 @@ abstract class Base $max = $block_size - $pos; if ($len >= $max) { $i = $max; - $len-= $max; + $len -= $max; $pos = 0; } else { $i = $len; - $pos+= $len; + $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize @@ -945,16 +1428,16 @@ abstract class Base $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); } while ($len >= $block_size) { - $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size); - $ciphertext.= $iv; - $len-= $block_size; - $i+= $block_size; + $iv = $this->encryptBlock($iv) ^ substr($plaintext, $i, $block_size); + $ciphertext .= $iv; + $len -= $block_size; + $i += $block_size; } if ($len) { - $iv = $this->_encryptBlock($iv); + $iv = $this->encryptBlock($iv); $block = $iv ^ substr($plaintext, $i); $iv = substr_replace($iv, $block, 0, $len); - $ciphertext.= $block; + $ciphertext .= $block; $pos = $len; } break; @@ -964,7 +1447,7 @@ abstract class Base $iv = $this->encryptIV; for ($i = 0; $i < $len; ++$i) { - $ciphertext .= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv)); + $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); $iv = substr($iv, 1) . $c; } @@ -976,22 +1459,37 @@ abstract class Base } } break; + case self::MODE_OFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = $this->encryptBlock($iv); + $ciphertext .= $plaintext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; case self::MODE_OFB: $xor = $this->encryptIV; if (strlen($buffer['xor'])) { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['xor'])) { - $xor = $this->_encryptBlock($xor); - $buffer['xor'].= $xor; + $xor = $this->encryptBlock($xor); + $buffer['xor'] .= $xor; } - $key = $this->_string_shift($buffer['xor'], $block_size); - $ciphertext.= $block ^ $key; + $key = Strings::shift($buffer['xor'], $block_size); + $ciphertext .= $block ^ $key; } } else { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { - $xor = $this->_encryptBlock($xor); - $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor; + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $xor = $this->encryptBlock($xor); + $ciphertext .= substr($plaintext, $i, $block_size) ^ $xor; } $key = $xor; } @@ -1003,7 +1501,7 @@ abstract class Base } break; case self::MODE_STREAM: - $ciphertext = $this->_encryptBlock($plaintext); + $ciphertext = $this->encryptBlock($plaintext); break; } @@ -1016,50 +1514,73 @@ abstract class Base * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until * it is. * + * {@internal Could, but not must, extend by the child Crypt_* class} + * * @see self::encrypt() - * @access public * @param string $ciphertext * @return string $plaintext - * @internal Could, but not must, extend by the child Crypt_* class + * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size */ - function decrypt($ciphertext) + public function decrypt($ciphertext) { - if ($this->paddable) { - // we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}: - // "The data is padded with "\0" to make sure the length of the data is n * blocksize." - $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0)); + if ($this->paddable && strlen($ciphertext) % $this->block_size) { + throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); + } + $this->setup(); + + if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + + if (isset($this->poly1305Key)) { + $newtag = $this->poly1305($ciphertext); + } else { + $oldIV = $this->iv; + Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $plaintext = $cipher->decrypt($ciphertext); + + $s = $this->ghash( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + self::len64($this->aad) . + self::len64($ciphertext) + ); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $newtag = $cipher->encrypt($s); + } + if ($this->oldtag != substr($newtag, 0, strlen($newtag))) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = false; + $plaintext = $cipher->decrypt($ciphertext); + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + return $plaintext; } if ($this->engine === self::ENGINE_OPENSSL) { - if ($this->changed) { - $this->_clearBuffers(); - $this->changed = false; - } switch ($this->mode) { case self::MODE_STREAM: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); break; case self::MODE_ECB: - if (!defined('OPENSSL_RAW_DATA')) { - $ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true); - } - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options); + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); break; case self::MODE_CBC: - if (!defined('OPENSSL_RAW_DATA')) { - $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size); - $ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size); - $offset = 2 * $this->block_size; - } else { - $offset = $this->block_size; - } - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); + $offset = $this->block_size; + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); if ($this->continuousBuffer) { $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); } break; case self::MODE_CTR: - $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); + $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); break; case self::MODE_CFB: // cfb loosely routines inspired by openssl's: @@ -1067,7 +1588,7 @@ abstract class Base $plaintext = ''; if ($this->continuousBuffer) { $iv = &$this->decryptIV; - $pos = &$this->buffer['pos']; + $pos = &$this->debuffer['pos']; } else { $iv = $this->decryptIV; $pos = 0; @@ -1079,11 +1600,11 @@ abstract class Base $max = $this->block_size - $pos; if ($len >= $max) { $i = $max; - $len-= $max; + $len -= $max; $pos = 0; } else { $i = $len; - $pos+= $len; + $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize @@ -1093,21 +1614,21 @@ abstract class Base } $overflow = $len % $this->block_size; if ($overflow) { - $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $plaintext .= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); if ($len - $overflow) { $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); } - $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); - $plaintext.= $iv ^ substr($ciphertext, -$overflow); + $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $plaintext .= $iv ^ substr($ciphertext, -$overflow); $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); $pos = $overflow; } elseif ($len) { - $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv); + $plaintext .= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $iv = substr($ciphertext, -$this->block_size); } break; case self::MODE_CFB8: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV); + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); if ($this->continuousBuffer) { if (($len = strlen($ciphertext)) >= $this->block_size) { $this->decryptIV = substr($ciphertext, -$this->block_size); @@ -1116,22 +1637,34 @@ abstract class Base } } break; + case self::MODE_OFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); + $plaintext .= $ciphertext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + break; case self::MODE_OFB: - $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); + $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); } - return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + return $this->paddable ? $this->unpad($plaintext) : $plaintext; } if ($this->engine === self::ENGINE_MCRYPT) { - set_error_handler(array($this, 'do_nothing')); + set_error_handler(function () { + }); $block_size = $this->block_size; - if ($this->changed) { - $this->_setupMcrypt(); - $this->changed = false; - } if ($this->dechanged) { - mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); $this->dechanged = false; } @@ -1146,11 +1679,11 @@ abstract class Base $max = $block_size - $pos; if ($len >= $max) { $i = $max; - $len-= $max; + $len -= $max; $pos = 0; } else { $i = $len; - $pos+= $len; + $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize @@ -1159,13 +1692,13 @@ abstract class Base } if ($len >= $block_size) { $cb = substr($ciphertext, $i, $len - $len % $block_size); - $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $plaintext .= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; $iv = substr($cb, -$block_size); - $len%= $block_size; + $len %= $block_size; } if ($len) { $iv = mcrypt_generic($this->ecb, $iv); - $plaintext.= $iv ^ substr($ciphertext, -$len); + $plaintext .= $iv ^ substr($ciphertext, -$len); $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); $pos = $len; } @@ -1178,21 +1711,17 @@ abstract class Base $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); if (!$this->continuousBuffer) { - mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); } restore_error_handler(); - return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + return $this->paddable ? $this->unpad($plaintext) : $plaintext; } - if ($this->changed) { - $this->_setup(); - $this->changed = false; - } - if ($this->use_inline_crypt) { + if ($this->engine === self::ENGINE_EVAL) { $inline = $this->inline_crypt; - return $inline('decrypt', $this, $ciphertext); + return $inline('decrypt', $ciphertext); } $block_size = $this->block_size; @@ -1201,15 +1730,15 @@ abstract class Base $plaintext = ''; switch ($this->mode) { case self::MODE_ECB: - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size)); + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $plaintext .= $this->decryptBlock(substr($ciphertext, $i, $block_size)); } break; case self::MODE_CBC: $xor = $this->decryptIV; - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); - $plaintext.= $this->_decryptBlock($block) ^ $xor; + $plaintext .= $this->decryptBlock($block) ^ $xor; $xor = $block; } if ($this->continuousBuffer) { @@ -1219,21 +1748,21 @@ abstract class Base case self::MODE_CTR: $xor = $this->decryptIV; if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'].= $this->_encryptBlock($xor); - $this->_increment_str($xor); + $buffer['ciphertext'] .= $this->encryptBlock($xor); + Strings::increment_str($xor); } - $key = $this->_string_shift($buffer['ciphertext'], $block_size); - $plaintext.= $block ^ $key; + $key = Strings::shift($buffer['ciphertext'], $block_size); + $plaintext .= $block ^ $key; } } else { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); - $key = $this->_encryptBlock($xor); - $this->_increment_str($xor); - $plaintext.= $block ^ $key; + $key = $this->encryptBlock($xor); + Strings::increment_str($xor); + $plaintext .= $block ^ $key; } } if ($this->continuousBuffer) { @@ -1258,11 +1787,11 @@ abstract class Base $max = $block_size - $pos; if ($len >= $max) { $i = $max; - $len-= $max; + $len -= $max; $pos = 0; } else { $i = $len; - $pos+= $len; + $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize @@ -1270,16 +1799,16 @@ abstract class Base $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); } while ($len >= $block_size) { - $iv = $this->_encryptBlock($iv); + $iv = $this->encryptBlock($iv); $cb = substr($ciphertext, $i, $block_size); - $plaintext.= $iv ^ $cb; + $plaintext .= $iv ^ $cb; $iv = $cb; - $len-= $block_size; - $i+= $block_size; + $len -= $block_size; + $i += $block_size; } if ($len) { - $iv = $this->_encryptBlock($iv); - $plaintext.= $iv ^ substr($ciphertext, $i); + $iv = $this->encryptBlock($iv); + $plaintext .= $iv ^ substr($ciphertext, $i); $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); $pos = $len; } @@ -1290,7 +1819,7 @@ abstract class Base $iv = $this->decryptIV; for ($i = 0; $i < $len; ++$i) { - $plaintext .= $ciphertext[$i] ^ $this->_encryptBlock($iv); + $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); $iv = substr($iv, 1) . $ciphertext[$i]; } @@ -1302,22 +1831,37 @@ abstract class Base } } break; + case self::MODE_OFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = $this->encryptBlock($iv); + $plaintext .= $ciphertext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + break; case self::MODE_OFB: $xor = $this->decryptIV; if (strlen($buffer['xor'])) { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); if (strlen($block) > strlen($buffer['xor'])) { - $xor = $this->_encryptBlock($xor); - $buffer['xor'].= $xor; + $xor = $this->encryptBlock($xor); + $buffer['xor'] .= $xor; } - $key = $this->_string_shift($buffer['xor'], $block_size); - $plaintext.= $block ^ $key; + $key = Strings::shift($buffer['xor'], $block_size); + $plaintext .= $block ^ $key; } } else { - for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { - $xor = $this->_encryptBlock($xor); - $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor; + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $xor = $this->encryptBlock($xor); + $plaintext .= substr($ciphertext, $i, $block_size) ^ $xor; } $key = $xor; } @@ -1329,18 +1873,95 @@ abstract class Base } break; case self::MODE_STREAM: - $plaintext = $this->_decryptBlock($ciphertext); + $plaintext = $this->decryptBlock($ciphertext); break; } - return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + /** + * Get the authentication tag + * + * Only used in GCM or Poly1305 mode + * + * @see self::encrypt() + * @param int $length optional + * @return string + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function getTag($length = 16) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + + if ($this->newtag === false) { + throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); + } + + // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it + // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially + // easily brute forced. + // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 + // for more info + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + + return $length == 16 ? + $this->newtag : + substr($this->newtag, 0, $length); + } + + /** + * Sets the authentication tag + * + * Only used in GCM mode + * + * @see self::decrypt() + * @param string $tag + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function setTag($tag) + { + if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + + $length = strlen($tag); + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + $this->oldtag = $tag; + } + + /** + * Get the IV + * + * mcrypt requires an IV even if ECB is used + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $iv + * @return string + */ + protected function getIV($iv) + { + return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv; } /** * OpenSSL CTR Processor * * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream - * for CTR is the same for both encrypting and decrypting this function is re-used by both Base::encrypt() - * and Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this + * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this * function will emulate CTR with ECB when necessary. * * @see self::encrypt() @@ -1349,9 +1970,8 @@ abstract class Base * @param string $encryptIV * @param array $buffer * @return string - * @access private */ - function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer) + private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) { $ciphertext = ''; @@ -1361,24 +1981,21 @@ abstract class Base if ($this->openssl_emulate_ctr) { $xor = $encryptIV; if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { - $result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); - $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result; - $buffer['ciphertext'].= $result; + $buffer['ciphertext'] .= openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); } - $this->_increment_str($xor); - $otp = $this->_string_shift($buffer['ciphertext'], $block_size); - $ciphertext.= $block ^ $otp; + Strings::increment_str($xor); + $otp = Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext .= $block ^ $otp; } } else { - for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); - $otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); - $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp; - $this->_increment_str($xor); - $ciphertext.= $block ^ $otp; + $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + Strings::increment_str($xor); + $ciphertext .= $block ^ $otp; } } if ($this->continuousBuffer) { @@ -1392,7 +2009,7 @@ abstract class Base } if (strlen($buffer['ciphertext'])) { - $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext)); + $ciphertext = $plaintext ^ Strings::shift($buffer['ciphertext'], strlen($plaintext)); $plaintext = substr($plaintext, strlen($ciphertext)); if (!strlen($plaintext)) { @@ -1402,28 +2019,25 @@ abstract class Base $overflow = strlen($plaintext) % $block_size; if ($overflow) { - $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 - $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); - $temp = $this->_string_pop($encrypted, $block_size); - $ciphertext.= $encrypted . ($plaintext2 ^ $temp); + $plaintext2 = Strings::pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 + $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $temp = Strings::pop($encrypted, $block_size); + $ciphertext .= $encrypted . ($plaintext2 ^ $temp); if ($this->continuousBuffer) { $buffer['ciphertext'] = substr($temp, $overflow); $encryptIV = $temp; } } elseif (!strlen($buffer['ciphertext'])) { - $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); - $temp = $this->_string_pop($ciphertext, $block_size); + $ciphertext .= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $temp = Strings::pop($ciphertext, $block_size); if ($this->continuousBuffer) { $encryptIV = $temp; } } if ($this->continuousBuffer) { - if (!defined('OPENSSL_RAW_DATA')) { - $encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options); - } - $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options); + $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); if ($overflow) { - $this->_increment_str($encryptIV); + Strings::increment_str($encryptIV); } } @@ -1434,8 +2048,8 @@ abstract class Base * OpenSSL OFB Processor * * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream - * for OFB is the same for both encrypting and decrypting this function is re-used by both Base::encrypt() - * and Base::decrypt(). + * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). * * @see self::encrypt() * @see self::decrypt() @@ -1443,9 +2057,8 @@ abstract class Base * @param string $encryptIV * @param array $buffer * @return string - * @access private */ - function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer) + private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) { if (strlen($buffer['xor'])) { $ciphertext = $plaintext ^ $buffer['xor']; @@ -1463,17 +2076,17 @@ abstract class Base if (strlen($plaintext)) { if ($overflow) { - $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); - $xor = $this->_string_pop($ciphertext, $block_size); + $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $xor = Strings::pop($ciphertext, $block_size); if ($this->continuousBuffer) { $encryptIV = $xor; } - $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow); + $ciphertext .= Strings::shift($xor, $overflow) ^ substr($plaintext, -$overflow); if ($this->continuousBuffer) { $buffer['xor'] = $xor; } } else { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV); + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); if ($this->continuousBuffer) { $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); } @@ -1488,10 +2101,9 @@ abstract class Base * * May need to be overwritten by classes extending this one in some cases * - * @return int - * @access private + * @return string */ - function _openssl_translate_mode() + protected function openssl_translate_mode() { switch ($this->mode) { case self::MODE_ECB: @@ -1499,6 +2111,7 @@ abstract class Base case self::MODE_CBC: return 'cbc'; case self::MODE_CTR: + case self::MODE_GCM: return 'ctr'; case self::MODE_CFB: return 'cfb'; @@ -1522,9 +2135,8 @@ abstract class Base * transmitted separately) * * @see self::disablePadding() - * @access public */ - function enablePadding() + public function enablePadding() { $this->padding = true; } @@ -1533,9 +2145,8 @@ abstract class Base * Do not pad packets. * * @see self::enablePadding() - * @access public */ - function disablePadding() + public function disablePadding() { $this->padding = false; } @@ -1569,24 +2180,28 @@ abstract class Base * outputs. The reason is due to the fact that the initialization vector's change after every encryption / * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. * - * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\*() object changes after each + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * however, they are also less intuitive and more likely to cause you problems. * + * {@internal Could, but not must, extend by the child Crypt_* class} + * * @see self::disableContinuousBuffer() - * @access public - * @internal Could, but not must, extend by the child Crypt_* class */ - function enableContinuousBuffer() + public function enableContinuousBuffer() { if ($this->mode == self::MODE_ECB) { return; } + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('This mode does not run in continuous mode'); + } + $this->continuousBuffer = true; - $this->_setEngine(); + $this->setEngine(); } /** @@ -1594,11 +2209,11 @@ abstract class Base * * The default behavior. * + * {@internal Could, but not must, extend by the child Crypt_* class} + * * @see self::enableContinuousBuffer() - * @access public - * @internal Could, but not must, extend by the child Crypt_* class */ - function disableContinuousBuffer() + public function disableContinuousBuffer() { if ($this->mode == self::MODE_ECB) { return; @@ -1608,9 +2223,8 @@ abstract class Base } $this->continuousBuffer = false; - $this->changed = true; - $this->_setEngine(); + $this->setEngine(); } /** @@ -1618,33 +2232,19 @@ abstract class Base * * @see self::__construct() * @param int $engine - * @access public * @return bool */ - function isValidEngine($engine) + protected function isValidEngineHelper($engine) { switch ($engine) { case self::ENGINE_OPENSSL: - if ($this->mode == self::MODE_STREAM && $this->continuousBuffer) { - return false; - } $this->openssl_emulate_ctr = false; $result = $this->cipher_name_openssl && - extension_loaded('openssl') && - // PHP 5.3.0 - 5.3.2 did not let you set IV's - version_compare(PHP_VERSION, '5.3.3', '>='); + extension_loaded('openssl'); if (!$result) { return false; } - // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer - // $options openssl_encrypt expected a boolean $raw_data. - if (!defined('OPENSSL_RAW_DATA')) { - $this->openssl_options = true; - } else { - $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; - } - $methods = openssl_get_cipher_methods(); if (in_array($this->cipher_name_openssl, $methods)) { return true; @@ -1660,12 +2260,15 @@ abstract class Base } return false; case self::ENGINE_MCRYPT: - set_error_handler(array($this, 'do_nothing')); + set_error_handler(function () { + }); $result = $this->cipher_name_mcrypt && - extension_loaded('mcrypt') && - in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); + extension_loaded('mcrypt') && + in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); restore_error_handler(); return $result; + case self::ENGINE_EVAL: + return method_exists($this, 'setupInlineCrypt'); case self::ENGINE_INTERNAL: return true; } @@ -1673,66 +2276,96 @@ abstract class Base return false; } + /** + * Test for engine validity + * + * @see self::__construct() + * @param string $engine + * @return bool + */ + public function isValidEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_map('strtolower', self::ENGINE_MAP); + $reverseMap = array_flip($reverseMap); + } + $engine = strtolower($engine); + if (!isset($reverseMap[$engine])) { + return false; + } + + return $this->isValidEngineHelper($reverseMap[$engine]); + } + /** * Sets the preferred crypt engine * * Currently, $engine could be: * - * - \phpseclib\Crypt\Base::ENGINE_OPENSSL [very fast] + * - libsodium[very fast] * - * - \phpseclib\Crypt\Base::ENGINE_MCRYPT [fast] + * - OpenSSL [very fast] * - * - \phpseclib\Crypt\Base::ENGINE_INTERNAL [slow] + * - mcrypt [fast] + * + * - Eval [slow] + * + * - PHP [slowest] * * If the preferred crypt engine is not available the fastest available one will be used * * @see self::__construct() - * @param int $engine - * @access public + * @param string $engine */ - function setPreferredEngine($engine) + public function setPreferredEngine($engine) { - switch ($engine) { - //case self::ENGINE_OPENSSL; - case self::ENGINE_MCRYPT: - case self::ENGINE_INTERNAL: - $this->preferredEngine = $engine; - break; - default: - $this->preferredEngine = self::ENGINE_OPENSSL; + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_map('strtolower', self::ENGINE_MAP); + $reverseMap = array_flip($reverseMap); } + $engine = is_string($engine) ? strtolower($engine) : ''; + $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; - $this->_setEngine(); + $this->setEngine(); } /** * Returns the engine currently being utilized * - * @see self::_setEngine() - * @access public + * @see self::setEngine() */ - function getEngine() + public function getEngine() { - return $this->engine; + return self::ENGINE_MAP[$this->engine]; } /** * Sets the engine as appropriate * * @see self::__construct() - * @access private */ - function _setEngine() + protected function setEngine() { $this->engine = null; - $candidateEngines = array( - $this->preferredEngine, + $candidateEngines = [ + self::ENGINE_LIBSODIUM, + self::ENGINE_OPENSSL_GCM, self::ENGINE_OPENSSL, - self::ENGINE_MCRYPT - ); + self::ENGINE_MCRYPT, + self::ENGINE_EVAL + ]; + if (isset($this->preferredEngine)) { + $temp = [$this->preferredEngine]; + $candidateEngines = array_merge( + $temp, + array_diff($candidateEngines, $temp) + ); + } foreach ($candidateEngines as $engine) { - if ($this->isValidEngine($engine)) { + if ($this->isValidEngineHelper($engine)) { $this->engine = $engine; break; } @@ -1742,7 +2375,8 @@ abstract class Base } if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { - set_error_handler(array($this, 'do_nothing')); + set_error_handler(function () { + }); // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, // (re)open them with the module named in $this->cipher_name_mcrypt mcrypt_module_close($this->enmcrypt); @@ -1757,42 +2391,39 @@ abstract class Base restore_error_handler(); } - $this->changed = true; + $this->changed = $this->nonIVChanged = true; } /** * Encrypts a block * - * Note: Must be extended by the child \phpseclib\Crypt\* class + * Note: Must be extended by the child \phpseclib3\Crypt\* class * - * @access private * @param string $in * @return string */ - abstract function _encryptBlock($in); + abstract protected function encryptBlock($in); /** * Decrypts a block * - * Note: Must be extended by the child \phpseclib\Crypt\* class + * Note: Must be extended by the child \phpseclib3\Crypt\* class * - * @access private * @param string $in * @return string */ - abstract function _decryptBlock($in); + abstract protected function decryptBlock($in); /** * Setup the key (expansion) * * Only used if $engine == self::ENGINE_INTERNAL * - * Note: Must extend by the child \phpseclib\Crypt\* class + * Note: Must extend by the child \phpseclib3\Crypt\* class * - * @see self::_setup() - * @access private + * @see self::setup() */ - abstract function _setupKey(); + abstract protected function setupKey(); /** * Setup the self::ENGINE_INTERNAL $engine @@ -1811,76 +2442,100 @@ abstract class Base * * - First run of encrypt() / decrypt() with no init-settings * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * * @see self::setKey() * @see self::setIV() * @see self::disableContinuousBuffer() - * @access private - * @internal _setup() is always called before en/decryption. - * @internal Could, but not must, extend by the child Crypt_* class */ - function _setup() + protected function setup() { - $this->_clearBuffers(); - $this->_setupKey(); - - if ($this->use_inline_crypt) { - $this->_setupInlineCrypt(); + if (!$this->changed) { + return; } - } - /** - * Setup the self::ENGINE_MCRYPT $engine - * - * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers - * Used (only) if $engine = self::ENGINE_MCRYPT - * - * _setupMcrypt() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setIV() - * - * - disableContinuousBuffer() - * - * - First run of encrypt() / decrypt() - * - * @see self::setKey() - * @see self::setIV() - * @see self::disableContinuousBuffer() - * @access private - * @internal Could, but not must, extend by the child Crypt_* class - */ - function _setupMcrypt() - { - $this->_clearBuffers(); - $this->enchanged = $this->dechanged = true; + $this->changed = false; - if (!isset($this->enmcrypt)) { - static $mcrypt_modes = array( - self::MODE_CTR => 'ctr', - self::MODE_ECB => MCRYPT_MODE_ECB, - self::MODE_CBC => MCRYPT_MODE_CBC, - self::MODE_CFB => 'ncfb', - self::MODE_CFB8 => MCRYPT_MODE_CFB, - self::MODE_OFB => MCRYPT_MODE_NOFB, - self::MODE_STREAM => MCRYPT_MODE_STREAM, - ); + if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } - $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true]; + //$this->newtag = $this->oldtag = false; - // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() - // to workaround mcrypt's broken ncfb implementation in buffered mode - // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} - if ($this->mode == self::MODE_CFB) { - $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + if ($this->usesNonce()) { + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); } - } // else should mcrypt_generic_deinit be called? - - if ($this->mode == self::MODE_CFB) { - mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + if ($this->mode == self::MODE_GCM && !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + $this->setupGCM(); + } + } else { + $this->iv = $this->origIV; } + + if ($this->iv === false && !in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { + if ($this->mode != self::MODE_GCM || !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + throw new InsufficientSetupException('No IV has been defined'); + } + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + $this->encryptIV = $this->decryptIV = $this->iv; + + switch ($this->engine) { + case self::ENGINE_MCRYPT: + $this->enchanged = $this->dechanged = true; + + set_error_handler(function () { + }); + + if (!isset($this->enmcrypt)) { + static $mcrypt_modes = [ + self::MODE_CTR => 'ctr', + self::MODE_ECB => MCRYPT_MODE_ECB, + self::MODE_CBC => MCRYPT_MODE_CBC, + self::MODE_CFB => 'ncfb', + self::MODE_CFB8 => MCRYPT_MODE_CFB, + self::MODE_OFB => MCRYPT_MODE_NOFB, + self::MODE_OFB8 => MCRYPT_MODE_OFB, + self::MODE_STREAM => MCRYPT_MODE_STREAM, + ]; + + $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + + // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() + // to workaround mcrypt's broken ncfb implementation in buffered mode + // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + if ($this->mode == self::MODE_CFB) { + $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + } + } // else should mcrypt_generic_deinit be called? + + if ($this->mode == self::MODE_CFB) { + mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + } + + restore_error_handler(); + + break; + case self::ENGINE_INTERNAL: + $this->setupKey(); + break; + case self::ENGINE_EVAL: + if ($this->nonIVChanged) { + $this->setupKey(); + $this->setupInlineCrypt(); + } + } + + $this->nonIVChanged = false; } /** @@ -1893,12 +2548,12 @@ abstract class Base * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless * and padding will, hence forth, be enabled. * - * @see self::_unpad() + * @see self::unpad() * @param string $text - * @access private + * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size * @return string */ - function _pad($text) + protected function pad($text) { $length = strlen($text); @@ -1906,8 +2561,7 @@ abstract class Base if ($length % $this->block_size == 0) { return $text; } else { - user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})"); - $this->padding = true; + throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); } } @@ -1922,12 +2576,12 @@ abstract class Base * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong * and false will be returned. * - * @see self::_pad() + * @see self::pad() * @param string $text - * @access private + * @throws \LengthException if the ciphertext's length is not a multiple of the block size * @return string */ - function _unpad($text) + protected function unpad($text) { if (!$this->padding) { return $text; @@ -1936,106 +2590,12 @@ abstract class Base $length = ord($text[strlen($text) - 1]); if (!$length || $length > $this->block_size) { - return false; + throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); } return substr($text, 0, -$length); } - /** - * Clears internal buffers - * - * Clearing/resetting the internal buffers is done everytime - * after disableContinuousBuffer() or on cipher $engine (re)init - * ie after setKey() or setIV() - * - * @access public - * @internal Could, but not must, extend by the child Crypt_* class - */ - function _clearBuffers() - { - $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true); - - // mcrypt's handling of invalid's $iv: - // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size); - $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0"); - - if (!$this->skip_key_adjustment) { - $this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0"); - } - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @access private - * @return string - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } - - /** - * String Pop - * - * Inspired by array_pop - * - * @param string $string - * @param int $index - * @access private - * @return string - */ - function _string_pop(&$string, $index = 1) - { - $substr = substr($string, -$index); - $string = substr($string, 0, -$index); - return $substr; - } - - /** - * Increment the current string - * - * @see self::decrypt() - * @see self::encrypt() - * @param string $var - * @access private - */ - function _increment_str(&$var) - { - for ($i = 4; $i <= strlen($var); $i+= 4) { - $temp = substr($var, -$i, 4); - switch ($temp) { - case "\xFF\xFF\xFF\xFF": - $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); - break; - case "\x7F\xFF\xFF\xFF": - $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); - return; - default: - $temp = unpack('Nnum', $temp); - $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); - return; - } - } - - $remainder = strlen($var) % 4; - - if ($remainder == 0) { - return; - } - - $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); - $temp = substr(pack('N', $temp['num'] + 1), -$remainder); - $var = substr_replace($var, $temp, 0, $remainder); - } - /** * Setup the performance-optimized function for de/encrypt() * @@ -2046,16 +2606,14 @@ abstract class Base * * _setupInlineCrypt() would be called only if: * - * - $engine == self::ENGINE_INTERNAL and - * - * - $use_inline_crypt === true + * - $this->engine === self::ENGINE_EVAL * * - each time on _setup(), after(!) _setupKey() * * * This ensures that _setupInlineCrypt() has always a * full ready2go initializated internal cipher $engine state - * where, for example, the keys allready expanded, + * where, for example, the keys already expanded, * keys/block_size calculated and such. * * It is, each time if called, the responsibility of _setupInlineCrypt(): @@ -2081,31 +2639,21 @@ abstract class Base * - short (as good as possible) * * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. - * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib\Crypt\* class. + * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. * - The following variable names are reserved: * - $_* (all variable names prefixed with an underscore) * - $self (object reference to it self. Do not use $this, but $self instead) * - $in (the content of $in has to en/decrypt by the generated code) * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only * + * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} * - * @see self::_setup() - * @see self::_createInlineCryptFunction() + * @see self::setup() + * @see self::createInlineCryptFunction() * @see self::encrypt() * @see self::decrypt() - * @access private - * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt() */ - function _setupInlineCrypt() - { - // If, for any reason, an extending \phpseclib\Crypt\Base() \phpseclib\Crypt\* class - // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false - // ie in the class var declaration of $use_inline_crypt in general for the \phpseclib\Crypt\* class, - // in the constructor at object instance-time - // or, if it's runtime-specific, at runtime - - $this->use_inline_crypt = false; - } + //protected function setupInlineCrypt(); /** * Creates the performance-optimized function for en/decrypt() @@ -2197,28 +2745,27 @@ abstract class Base * +----------------------------------------------------------------------------------------------+ * * - * See also the \phpseclib\Crypt\*::_setupInlineCrypt()'s for + * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for * productive inline $cipher_code's how they works. * * Structure of: * - * $cipher_code = array( + * $cipher_code = [ * 'init_crypt' => (string) '', // optional * 'init_encrypt' => (string) '', // optional * 'init_decrypt' => (string) '', // optional * 'encrypt_block' => (string) '', // required * 'decrypt_block' => (string) '' // required - * ); + * ]; * * - * @see self::_setupInlineCrypt() + * @see self::setupInlineCrypt() * @see self::encrypt() * @see self::decrypt() * @param array $cipher_code - * @access private * @return string (the name of the created callback function) */ - function _createInlineCryptFunction($cipher_code) + protected function createInlineCryptFunction($cipher_code) { $block_size = $this->block_size; @@ -2239,9 +2786,9 @@ abstract class Base $_ciphertext = ""; $_plaintext_len = strlen($_text); - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $in = substr($_text, $_i, '.$block_size.'); - '.$encrypt_block.' + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . '); + ' . $encrypt_block . ' $_ciphertext.= $in; } @@ -2250,49 +2797,49 @@ abstract class Base $decrypt = $init_decrypt . ' $_plaintext = ""; - $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); + $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); $_ciphertext_len = strlen($_text); - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $in = substr($_text, $_i, '.$block_size.'); - '.$decrypt_block.' + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . '); + ' . $decrypt_block . ' $_plaintext.= $in; } - return $self->_unpad($_plaintext); + return $this->unpad($_plaintext); '; break; case self::MODE_CTR: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_plaintext_len = strlen($_text); - $_xor = $self->encryptIV; - $_buffer = &$self->enbuffer; + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; if (strlen($_buffer["ciphertext"])) { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["ciphertext"])) { $in = $_xor; - '.$encrypt_block.' - $self->_increment_str($_xor); + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_buffer["ciphertext"].= $in; } - $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.'); + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); $_ciphertext.= $_block ^ $_key; } } else { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); $in = $_xor; - '.$encrypt_block.' - $self->_increment_str($_xor); + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_key = $in; $_ciphertext.= $_block ^ $_key; } } - if ($self->continuousBuffer) { - $self->encryptIV = $_xor; - if ($_start = $_plaintext_len % '.$block_size.') { + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % ' . $block_size . ') { $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; } } @@ -2303,34 +2850,34 @@ abstract class Base $decrypt = $init_encrypt . ' $_plaintext = ""; $_ciphertext_len = strlen($_text); - $_xor = $self->decryptIV; - $_buffer = &$self->debuffer; + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; if (strlen($_buffer["ciphertext"])) { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["ciphertext"])) { $in = $_xor; - '.$encrypt_block.' - $self->_increment_str($_xor); + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_buffer["ciphertext"].= $in; } - $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.'); + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); $_plaintext.= $_block ^ $_key; } } else { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); $in = $_xor; - '.$encrypt_block.' - $self->_increment_str($_xor); + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_key = $in; $_plaintext.= $_block ^ $_key; } } - if ($self->continuousBuffer) { - $self->decryptIV = $_xor; - if ($_start = $_ciphertext_len % '.$block_size.') { + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % ' . $block_size . ') { $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; } } @@ -2341,20 +2888,20 @@ abstract class Base case self::MODE_CFB: $encrypt = $init_encrypt . ' $_ciphertext = ""; - $_buffer = &$self->enbuffer; + $_buffer = &$this->enbuffer; - if ($self->continuousBuffer) { - $_iv = &$self->encryptIV; + if ($this->continuousBuffer) { + $_iv = &$this->encryptIV; $_pos = &$_buffer["pos"]; } else { - $_iv = $self->encryptIV; + $_iv = $this->encryptIV; $_pos = 0; } $_len = strlen($_text); $_i = 0; if ($_pos) { $_orig_pos = $_pos; - $_max = '.$block_size.' - $_pos; + $_max = ' . $block_size . ' - $_pos; if ($_len >= $_max) { $_i = $_max; $_len-= $_max; @@ -2367,17 +2914,17 @@ abstract class Base $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); } - while ($_len >= '.$block_size.') { + while ($_len >= ' . $block_size . ') { $in = $_iv; - '.$encrypt_block.'; - $_iv = $in ^ substr($_text, $_i, '.$block_size.'); + ' . $encrypt_block . '; + $_iv = $in ^ substr($_text, $_i, ' . $block_size . '); $_ciphertext.= $_iv; - $_len-= '.$block_size.'; - $_i+= '.$block_size.'; + $_len-= ' . $block_size . '; + $_i+= ' . $block_size . '; } if ($_len) { $in = $_iv; - '.$encrypt_block.' + ' . $encrypt_block . ' $_iv = $in; $_block = $_iv ^ substr($_text, $_i); $_iv = substr_replace($_iv, $_block, 0, $_len); @@ -2389,20 +2936,20 @@ abstract class Base $decrypt = $init_encrypt . ' $_plaintext = ""; - $_buffer = &$self->debuffer; + $_buffer = &$this->debuffer; - if ($self->continuousBuffer) { - $_iv = &$self->decryptIV; + if ($this->continuousBuffer) { + $_iv = &$this->decryptIV; $_pos = &$_buffer["pos"]; } else { - $_iv = $self->decryptIV; + $_iv = $this->decryptIV; $_pos = 0; } $_len = strlen($_text); $_i = 0; if ($_pos) { $_orig_pos = $_pos; - $_max = '.$block_size.' - $_pos; + $_max = ' . $block_size . ' - $_pos; if ($_len >= $_max) { $_i = $_max; $_len-= $_max; @@ -2415,19 +2962,19 @@ abstract class Base $_plaintext = substr($_iv, $_orig_pos) ^ $_text; $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); } - while ($_len >= '.$block_size.') { + while ($_len >= ' . $block_size . ') { $in = $_iv; - '.$encrypt_block.' + ' . $encrypt_block . ' $_iv = $in; - $cb = substr($_text, $_i, '.$block_size.'); + $cb = substr($_text, $_i, ' . $block_size . '); $_plaintext.= $_iv ^ $cb; $_iv = $cb; - $_len-= '.$block_size.'; - $_i+= '.$block_size.'; + $_len-= ' . $block_size . '; + $_i+= ' . $block_size . '; } if ($_len) { $in = $_iv; - '.$encrypt_block.' + ' . $encrypt_block . ' $_iv = $in; $_plaintext.= $_iv ^ substr($_text, $_i); $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); @@ -2441,20 +2988,20 @@ abstract class Base $encrypt = $init_encrypt . ' $_ciphertext = ""; $_len = strlen($_text); - $_iv = $self->encryptIV; + $_iv = $this->encryptIV; for ($_i = 0; $_i < $_len; ++$_i) { $in = $_iv; - '.$encrypt_block.' + ' . $encrypt_block . ' $_ciphertext .= ($_c = $_text[$_i] ^ $in); $_iv = substr($_iv, 1) . $_c; } - if ($self->continuousBuffer) { - if ($_len >= '.$block_size.') { - $self->encryptIV = substr($_ciphertext, -'.$block_size.'); + if ($this->continuousBuffer) { + if ($_len >= ' . $block_size . ') { + $this->encryptIV = substr($_ciphertext, -' . $block_size . '); } else { - $self->encryptIV = substr($self->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len); + $this->encryptIV = substr($this->encryptIV, $_len - ' . $block_size . ') . substr($_ciphertext, -$_len); } } @@ -2463,23 +3010,61 @@ abstract class Base $decrypt = $init_encrypt . ' $_plaintext = ""; $_len = strlen($_text); - $_iv = $self->decryptIV; + $_iv = $this->decryptIV; for ($_i = 0; $_i < $_len; ++$_i) { $in = $_iv; - '.$encrypt_block.' + ' . $encrypt_block . ' $_plaintext .= $_text[$_i] ^ $in; $_iv = substr($_iv, 1) . $_text[$_i]; } - if ($self->continuousBuffer) { - if ($_len >= '.$block_size.') { - $self->decryptIV = substr($_text, -'.$block_size.'); + if ($this->continuousBuffer) { + if ($_len >= ' . $block_size . ') { + $this->decryptIV = substr($_text, -' . $block_size . '); } else { - $self->decryptIV = substr($self->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len); + $this->decryptIV = substr($this->decryptIV, $_len - ' . $block_size . ') . substr($_text, -$_len); } } + return $_plaintext; + '; + break; + case self::MODE_OFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_ciphertext.= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $in[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $_iv; + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_plaintext.= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $in[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; + } + return $_plaintext; '; break; @@ -2487,33 +3072,33 @@ abstract class Base $encrypt = $init_encrypt . ' $_ciphertext = ""; $_plaintext_len = strlen($_text); - $_xor = $self->encryptIV; - $_buffer = &$self->enbuffer; + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; if (strlen($_buffer["xor"])) { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["xor"])) { $in = $_xor; - '.$encrypt_block.' + ' . $encrypt_block . ' $_xor = $in; $_buffer["xor"].= $_xor; } - $_key = $self->_string_shift($_buffer["xor"], '.$block_size.'); + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); $_ciphertext.= $_block ^ $_key; } } else { - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $in = $_xor; - '.$encrypt_block.' + ' . $encrypt_block . ' $_xor = $in; - $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor; + $_ciphertext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; } $_key = $_xor; } - if ($self->continuousBuffer) { - $self->encryptIV = $_xor; - if ($_start = $_plaintext_len % '.$block_size.') { + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % ' . $block_size . ') { $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; } } @@ -2523,33 +3108,33 @@ abstract class Base $decrypt = $init_encrypt . ' $_plaintext = ""; $_ciphertext_len = strlen($_text); - $_xor = $self->decryptIV; - $_buffer = &$self->debuffer; + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; if (strlen($_buffer["xor"])) { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $_block = substr($_text, $_i, '.$block_size.'); + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["xor"])) { $in = $_xor; - '.$encrypt_block.' + ' . $encrypt_block . ' $_xor = $in; $_buffer["xor"].= $_xor; } - $_key = $self->_string_shift($_buffer["xor"], '.$block_size.'); + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); $_plaintext.= $_block ^ $_key; } } else { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $in = $_xor; - '.$encrypt_block.' + ' . $encrypt_block . ' $_xor = $in; - $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor; + $_plaintext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; } $_key = $_xor; } - if ($self->continuousBuffer) { - $self->decryptIV = $_xor; - if ($_start = $_ciphertext_len % '.$block_size.') { + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % ' . $block_size . ') { $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; } } @@ -2559,12 +3144,12 @@ abstract class Base case self::MODE_STREAM: $encrypt = $init_encrypt . ' $_ciphertext = ""; - '.$encrypt_block.' + ' . $encrypt_block . ' return $_ciphertext; '; $decrypt = $init_decrypt . ' $_plaintext = ""; - '.$decrypt_block.' + ' . $decrypt_block . ' return $_plaintext; '; break; @@ -2574,16 +3159,16 @@ abstract class Base $_ciphertext = ""; $_plaintext_len = strlen($_text); - $in = $self->encryptIV; + $in = $this->encryptIV; - for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') { - $in = substr($_text, $_i, '.$block_size.') ^ $in; - '.$encrypt_block.' + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . ') ^ $in; + ' . $encrypt_block . ' $_ciphertext.= $in; } - if ($self->continuousBuffer) { - $self->encryptIV = $in; + if ($this->continuousBuffer) { + $this->encryptIV = $in; } return $_ciphertext; @@ -2591,86 +3176,33 @@ abstract class Base $decrypt = $init_decrypt . ' $_plaintext = ""; - $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0)); + $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); $_ciphertext_len = strlen($_text); - $_iv = $self->decryptIV; + $_iv = $this->decryptIV; - for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') { - $in = $_block = substr($_text, $_i, '.$block_size.'); - '.$decrypt_block.' + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = $_block = substr($_text, $_i, ' . $block_size . '); + ' . $decrypt_block . ' $_plaintext.= $in ^ $_iv; $_iv = $_block; } - if ($self->continuousBuffer) { - $self->decryptIV = $_iv; + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; } - return $self->_unpad($_plaintext); + return $this->unpad($_plaintext); '; break; } - // Create the $inline function and return its name as string. Ready to run! - eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };'); - return $func; - } + // Before discrediting this, please read the following: + // @see https://github.com/phpseclib/phpseclib/issues/1293 + // @see https://github.com/phpseclib/phpseclib/pull/1143 + eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); - /** - * Holds the lambda_functions table (classwide) - * - * Each name of the lambda function, created from - * _setupInlineCrypt() && _createInlineCryptFunction() - * is stored, classwide (!), here for reusing. - * - * The string-based index of $function is a classwide - * unique value representing, at least, the $mode of - * operation (or more... depends of the optimizing level) - * for which $mode the lambda function was created. - * - * @access private - * @return array &$functions - */ - function &_getLambdaFunctions() - { - static $functions = array(); - return $functions; - } - - /** - * Generates a digest from $bytes - * - * @see self::_setupInlineCrypt() - * @access private - * @param string $bytes - * @return string - */ - function _hashInlineCryptFunction($bytes) - { - if (!isset(self::$WHIRLPOOL_AVAILABLE)) { - self::$WHIRLPOOL_AVAILABLE = extension_loaded('hash') && in_array('whirlpool', hash_algos()); - } - - $result = ''; - $hash = $bytes; - - switch (true) { - case self::$WHIRLPOOL_AVAILABLE: - foreach (str_split($bytes, 64) as $t) { - $hash = hash('whirlpool', $hash, true); - $result .= $t ^ $hash; - } - return $result . hash('whirlpool', $hash, true); - default: - $len = strlen($bytes); - for ($i = 0; $i < $len; $i+=20) { - $t = substr($bytes, $i, 20); - $hash = pack('H*', sha1($hash)); - $result .= $t ^ $hash; - } - return $result . pack('H*', sha1($hash)); - } + return \Closure::bind($func, $this, static::class); } /** @@ -2678,18 +3210,19 @@ abstract class Base * * On ARM CPUs converting floats to ints doesn't always work * - * @access private * @param string $x * @return int */ - function safe_intval($x) + protected static function safe_intval($x) { - switch (true) { - case is_int($x): - // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" - case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - return $x; + if (is_int($x)) { + return $x; } + + if (self::$use_reg_intval) { + return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? intval($x) : $x; + } + return (fmod($x, 0x80000000) & 0x7FFFFFFF) | ((fmod(floor($x / 0x80000000), 2) & 1) << 31); } @@ -2697,28 +3230,167 @@ abstract class Base /** * eval()'able string for in-line float to int * - * @access private * @return string */ - function safe_intval_inline() + protected static function safe_intval_inline() { - switch (true) { - case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: - case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - return '%s'; - break; - default: - $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; - return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + if (self::$use_reg_intval) { + return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? 'intval(%s)' : '%s'; + } + + $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; + return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + } + + /** + * Sets up GCM parameters + * + * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 + * for more info + * + */ + private function setupGCM() + { + // don't keep on re-calculating $this->h + if (!$this->h || $this->hKey != $this->key) { + $cipher = new static('ecb'); + $cipher->setKey($this->key); + $cipher->disablePadding(); + + $this->h = self::$gcmField->newInteger( + Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")) + ); + $this->hKey = $this->key; + } + + if (strlen($this->nonce) == 12) { + $this->iv = $this->nonce . "\0\0\0\1"; + } else { + $this->iv = $this->ghash( + self::nullPad128($this->nonce) . str_repeat("\0", 8) . self::len64($this->nonce) + ); } } /** - * Dummy error handler to suppress mcrypt errors + * Performs GHASH operation * - * @access private + * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 + * for more info + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $x + * @return string */ - function do_nothing() + private function ghash($x) { + $h = $this->h; + $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; + $x = str_split($x, 16); + $n = 0; + // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer + // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little + // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. + // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. + + // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it + // might be slightly more performant + //$x = Strings::switchEndianness($x); + foreach ($x as $xn) { + $xn = Strings::switchEndianness($xn); + $t = $y[$n] ^ $xn; + $temp = self::$gcmField->newInteger($t); + $y[++$n] = $temp->multiply($h)->toBytes(); + $y[$n] = substr($y[$n], 1); + } + $y[$n] = Strings::switchEndianness($y[$n]); + return $y[$n]; + } + + /** + * Returns the bit length of a string in a packed format + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @param string $str + * @return string + */ + private static function len64($str) + { + return "\0\0\0\0" . pack('N', 8 * strlen($str)); + } + + /** + * NULL pads a string to be a multiple of 128 + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @param string $str + * @return string + */ + protected static function nullPad128($str) + { + $len = strlen($str); + return $str . str_repeat("\0", 16 * ceil($len / 16) - $len); + } + + /** + * Calculates Poly1305 MAC + * + * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation + * it takes 1.2s. + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $text + * @return string + */ + protected function poly1305($text) + { + $s = $this->poly1305Key; // strlen($this->poly1305Key) == 32 + $r = Strings::shift($s, 16); + $r = strrev($r); + $r &= "\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xff"; + $s = strrev($s); + + $r = self::$poly1305Field->newInteger(new BigInteger($r, 256)); + $s = self::$poly1305Field->newInteger(new BigInteger($s, 256)); + $a = self::$poly1305Field->newInteger(new BigInteger()); + + $blocks = str_split($text, 16); + foreach ($blocks as $block) { + $n = strrev($block . chr(1)); + $n = self::$poly1305Field->newInteger(new BigInteger($n, 256)); + $a = $a->add($n); + $a = $a->multiply($r); + } + $r = $a->toBigInteger()->add($s->toBigInteger()); + $mask = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; + return strrev($r->toBytes()) & $mask; + } + + /** + * Return the mode + * + * You can do $obj instanceof AES or whatever to get the cipher but you can't do that to get the mode + * + * @return string + */ + public function getMode() + { + return array_flip(self::MODE_MAP)[$this->mode]; + } + + /** + * Is the continuous buffer enabled? + * + * @return boolean + */ + public function continuousBufferEnabled() + { + return $this->continuousBuffer; } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php new file mode 100644 index 000000000..9ca8926d3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php @@ -0,0 +1,57 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Traits; + +use phpseclib3\Crypt\Hash; + +/** + * Fingerprint Trait for Private Keys + * + * @author Jim Wigginton + */ +trait Fingerprint +{ + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + * @return mixed + */ + public function getFingerprint($algorithm = 'md5') + { + $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); + if ($type === false) { + return false; + } + $key = $this->toString('OpenSSH', ['binary' => true]); + if ($key === false) { + return false; + } + switch ($algorithm) { + case 'sha256': + $hash = new Hash('sha256'); + $base = base64_encode($hash->hash($key)); + return substr($base, 0, strlen($base) - 1); + case 'md5': + return substr(chunk_split(md5($key), 2, ':'), 0, -1); + default: + return false; + } + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php new file mode 100644 index 000000000..0ac274e8d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php @@ -0,0 +1,46 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Traits; + +/** + * Password Protected Trait for Private Keys + * + * @author Jim Wigginton + */ +trait PasswordProtected +{ + /** + * Password + * + * @var string|bool + */ + private $password = false; + + /** + * Sets the password + * + * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. + * Or rather, pass in $password such that empty($password) && !is_string($password) is true. + * + * @see self::createKey() + * @see self::load() + * @param string|bool $password + */ + public function withPassword($password = false) + { + $new = clone $this; + $new->password = $password; + return $new; + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php similarity index 80% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php index 9a8225fb5..3b0383000 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php @@ -18,7 +18,7 @@ * setKey('abcdefgh'); * @@ -32,120 +32,119 @@ * ?> * * - * @category Crypt - * @package DES * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; /** * Pure-PHP implementation of DES. * - * @package DES * @author Jim Wigginton - * @access public */ -class DES extends Base +class DES extends BlockCipher { - /**#@+ - * @access private - * @see \phpseclib\Crypt\DES::_setupKey() - * @see \phpseclib\Crypt\DES::_processBlock() - */ /** * Contains $keys[self::ENCRYPT] + * + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\DES::processBlock() */ const ENCRYPT = 0; /** * Contains $keys[self::DECRYPT] + * + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\DES::processBlock() */ const DECRYPT = 1; - /**#@-*/ /** * Block Length of the cipher * - * @see \phpseclib\Crypt\Base::block_size + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size * @var int - * @access private */ - var $block_size = 8; + protected $block_size = 8; /** * Key Length (in bytes) * - * @see \phpseclib\Crypt\Base::setKeyLength() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() * @var int - * @access private */ - var $key_length = 8; + protected $key_length = 8; /** * The mcrypt specific name of the cipher * - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt * @var string - * @access private */ - var $cipher_name_mcrypt = 'des'; + protected $cipher_name_mcrypt = 'des'; /** * The OpenSSL names of the cipher / modes * - * @see \phpseclib\Crypt\Base::openssl_mode_names + * @see \phpseclib3\Crypt\Common\SymmetricKey::openssl_mode_names * @var array - * @access private */ - var $openssl_mode_names = array( + protected $openssl_mode_names = [ self::MODE_ECB => 'des-ecb', self::MODE_CBC => 'des-cbc', self::MODE_CFB => 'des-cfb', self::MODE_OFB => 'des-ofb' // self::MODE_CTR is undefined for DES - ); + ]; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib\Crypt\Base::cfb_init_len + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len * @var int - * @access private */ - var $cfb_init_len = 500; + protected $cfb_init_len = 500; /** * Switch for DES/3DES encryption * * Used only if $engine == self::ENGINE_INTERNAL * - * @see self::_setupKey() - * @see self::_processBlock() + * @see self::setupKey() + * @see self::processBlock() * @var int - * @access private */ - var $des_rounds = 1; + protected $des_rounds = 1; /** * max possible size of $key * * @see self::setKey() * @var string - * @access private */ - var $key_length_max = 8; + protected $key_length_max = 8; /** * The Key Schedule * - * @see self::_setupKey() + * @see self::setupKey() * @var array - * @access private */ - var $keys; + private $keys; + + /** + * Key Cache "key" + * + * @see self::setupKey() + * @var array + */ + private $kl; /** * Shuffle table. @@ -154,12 +153,11 @@ class DES extends Base * with each byte containing all bits in the same state as the * corresponding bit in the index value. * - * @see self::_processBlock() - * @see self::_setupKey() + * @see self::processBlock() + * @see self::setupKey() * @var array - * @access private */ - var $shuffle = array( + protected static $shuffle = [ "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", @@ -288,7 +286,7 @@ class DES extends Base "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - ); + ]; /** * IP mapping helper table. @@ -296,9 +294,8 @@ class DES extends Base * Indexing this table with each source byte performs the initial bit permutation. * * @var array - * @access private */ - var $ipmap = array( + protected static $ipmap = [ 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, @@ -331,16 +328,15 @@ class DES extends Base 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF - ); + ]; /** * Inverse IP mapping helper table. * Indexing this table with a byte value reverses the bit order. * * @var array - * @access private */ - var $invipmap = array( + protected static $invipmap = [ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, @@ -373,7 +369,7 @@ class DES extends Base 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF - ); + ]; /** * Pre-permuted S-box1 @@ -382,9 +378,8 @@ class DES extends Base * P table: concatenation can then be replaced by exclusive ORs. * * @var array - * @access private */ - var $sbox1 = array( + protected static $sbox1 = [ 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, 0x00000200, 0x00808200, 0x00808202, 0x00000200, @@ -401,15 +396,14 @@ class DES extends Base 0x00800002, 0x00000202, 0x00008202, 0x00808200, 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002 - ); + ]; /** * Pre-permuted S-box2 * * @var array - * @access private */ - var $sbox2 = array( + protected static $sbox2 = [ 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, 0x40000010, 0x40084010, 0x40084000, 0x40000000, @@ -426,15 +420,14 @@ class DES extends Base 0x00080010, 0x40004010, 0x40000010, 0x00080010, 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000 - ); + ]; /** * Pre-permuted S-box3 * * @var array - * @access private */ - var $sbox3 = array( + protected static $sbox3 = [ 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, 0x00010004, 0x04000004, 0x04000004, 0x00010000, @@ -451,15 +444,14 @@ class DES extends Base 0x00000004, 0x00010104, 0x00010100, 0x04000004, 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100 - ); + ]; /** * Pre-permuted S-box4 * * @var array - * @access private */ - var $sbox4 = array( + protected static $sbox4 = [ 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, 0x00000000, 0x00401000, 0x00401000, 0x80401040, @@ -476,15 +468,14 @@ class DES extends Base 0x80400000, 0x80001000, 0x00401040, 0x80400040, 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040 - ); + ]; /** * Pre-permuted S-box5 * * @var array - * @access private */ - var $sbox5 = array( + protected static $sbox5 = [ 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, 0x20040080, 0x00040000, 0x01000080, 0x20040080, @@ -501,15 +492,14 @@ class DES extends Base 0x01040000, 0x00000000, 0x20040000, 0x21000000, 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080 - ); + ]; /** * Pre-permuted S-box6 * * @var array - * @access private */ - var $sbox6 = array( + protected static $sbox6 = [ 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, 0x10002000, 0x00202008, 0x00200000, 0x10000008, @@ -526,15 +516,14 @@ class DES extends Base 0x00000008, 0x00002000, 0x10200000, 0x00202008, 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008 - ); + ]; /** * Pre-permuted S-box7 * * @var array - * @access private */ - var $sbox7 = array( + protected static $sbox7 = [ 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, 0x02100401, 0x00100000, 0x00000000, 0x02000001, @@ -551,15 +540,14 @@ class DES extends Base 0x00100400, 0x00000000, 0x00000001, 0x02100401, 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001 - ); + ]; /** * Pre-permuted S-box8 * * @var array - * @access private */ - var $sbox8 = array( + protected static $sbox8 = [ 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, 0x00020020, 0x08020000, 0x08020820, 0x00020800, @@ -576,51 +564,64 @@ class DES extends Base 0x08020000, 0x08000800, 0x08000820, 0x00000000, 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800 - ); + ]; + + /** + * Default Constructor. + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * - * @see \phpseclib\Crypt\Base::isValidEngine() + * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * @param int $engine - * @access public * @return bool */ - function isValidEngine($engine) + protected function isValidEngineHelper($engine) { if ($this->key_length_max == 8) { if ($engine == self::ENGINE_OPENSSL) { + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } $this->cipher_name_openssl_ecb = 'des-ecb'; - $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); + $this->cipher_name_openssl = 'des-' . $this->openssl_translate_mode(); } } - return parent::isValidEngine($engine); + return parent::isValidEngineHelper($engine); } /** * Sets the key. * - * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we - * only use the first eight, if $key has more then eight characters in it, and pad $key with the - * null byte if it is less then eight characters long. + * Keys must be 64-bits long or 8 bytes long. * * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * - * If the key is not explicitly set, it'll be assumed to be all zero's. - * - * @see \phpseclib\Crypt\Base::setKey() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() * @param string $key */ - function setKey($key) + public function setKey($key) { - // We check/cut here only up to max length of the key. - // Key padding to the proper length will be done in _setupKey() - if (strlen($key) > $this->key_length_max) { - $key = substr($key, 0, $this->key_length_max); + if (!($this instanceof TripleDES) && strlen($key) != 8) { + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); } // Sets the key @@ -630,31 +631,29 @@ class DES extends Base /** * Encrypts a block * - * @see \phpseclib\Crypt\Base::_encryptBlock() - * @see \phpseclib\Crypt\Base::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see self::encrypt() - * @access private * @param string $in * @return string */ - function _encryptBlock($in) + protected function encryptBlock($in) { - return $this->_processBlock($in, self::ENCRYPT); + return $this->processBlock($in, self::ENCRYPT); } /** * Decrypts a block * - * @see \phpseclib\Crypt\Base::_decryptBlock() - * @see \phpseclib\Crypt\Base::decrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() * @see self::decrypt() - * @access private * @param string $in * @return string */ - function _decryptBlock($in) + protected function decryptBlock($in) { - return $this->_processBlock($in, self::DECRYPT); + return $this->processBlock($in, self::DECRYPT); } /** @@ -664,29 +663,28 @@ class DES extends Base * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general * idea of what this function does. * - * @see self::_encryptBlock() - * @see self::_decryptBlock() - * @access private + * @see self::encryptBlock() + * @see self::decryptBlock() * @param string $block * @param int $mode * @return string */ - function _processBlock($block, $mode) + private function processBlock($block, $mode) { static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; if (!$sbox1) { - $sbox1 = array_map("intval", $this->sbox1); - $sbox2 = array_map("intval", $this->sbox2); - $sbox3 = array_map("intval", $this->sbox3); - $sbox4 = array_map("intval", $this->sbox4); - $sbox5 = array_map("intval", $this->sbox5); - $sbox6 = array_map("intval", $this->sbox6); - $sbox7 = array_map("intval", $this->sbox7); - $sbox8 = array_map("intval", $this->sbox8); + $sbox1 = array_map('intval', self::$sbox1); + $sbox2 = array_map('intval', self::$sbox2); + $sbox3 = array_map('intval', self::$sbox3); + $sbox4 = array_map('intval', self::$sbox4); + $sbox5 = array_map('intval', self::$sbox5); + $sbox6 = array_map('intval', self::$sbox6); + $sbox7 = array_map('intval', self::$sbox7); + $sbox8 = array_map('intval', self::$sbox8); /* Merge $shuffle with $[inv]ipmap */ for ($i = 0; $i < 256; ++$i) { - $shuffleip[] = $this->shuffle[$this->ipmap[$i]]; - $shuffleinvip[] = $this->shuffle[$this->invipmap[$i]]; + $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; + $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; } } @@ -695,7 +693,7 @@ class DES extends Base // Do the initial IP permutation. $t = unpack('Nl/Nr', $block); - list($l, $r) = array($t['l'], $t['r']); + list($l, $r) = [$t['l'], $t['r']]; $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | @@ -707,7 +705,7 @@ class DES extends Base // Extract L0 and R0. $t = unpack('Nl/Nr', $block); - list($l, $r) = array($t['l'], $t['r']); + list($l, $r) = [$t['l'], $t['r']]; for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { // Perform the 16 steps. @@ -749,22 +747,21 @@ class DES extends Base /** * Creates the key schedule * - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() */ - function _setupKey() + protected function setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) { // already expanded return; } - $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds); + $this->kl = ['key' => $this->key, 'des_rounds' => $this->des_rounds]; - static $shifts = array( // number of key bits shifted per round + static $shifts = [ // number of key bits shifted per round 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 - ); + ]; - static $pc1map = array( + static $pc1map = [ 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C, 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E, 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C, @@ -797,16 +794,16 @@ class DES extends Base 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE, 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC, 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE - ); + ]; // Mapping tables for the PC-2 transformation. - static $pc2mapc1 = array( + static $pc2mapc1 = [ 0x00000000, 0x00000400, 0x00200000, 0x00200400, 0x00000001, 0x00000401, 0x00200001, 0x00200401, 0x02000000, 0x02000400, 0x02200000, 0x02200400, 0x02000001, 0x02000401, 0x02200001, 0x02200401 - ); - static $pc2mapc2 = array( + ]; + static $pc2mapc2 = [ 0x00000000, 0x00000800, 0x08000000, 0x08000800, 0x00010000, 0x00010800, 0x08010000, 0x08010800, 0x00000000, 0x00000800, 0x08000000, 0x08000800, @@ -871,8 +868,8 @@ class DES extends Base 0x01050110, 0x01050910, 0x09050110, 0x09050910, 0x01040110, 0x01040910, 0x09040110, 0x09040910, 0x01050110, 0x01050910, 0x09050110, 0x09050910 - ); - static $pc2mapc3 = array( + ]; + static $pc2mapc3 = [ 0x00000000, 0x00000004, 0x00001000, 0x00001004, 0x00000000, 0x00000004, 0x00001000, 0x00001004, 0x10000000, 0x10000004, 0x10001000, 0x10001004, @@ -937,8 +934,8 @@ class DES extends Base 0x20080022, 0x20080026, 0x20081022, 0x20081026, 0x30080022, 0x30080026, 0x30081022, 0x30081026, 0x30080022, 0x30080026, 0x30081022, 0x30081026 - ); - static $pc2mapc4 = array( + ]; + static $pc2mapc4 = [ 0x00000000, 0x00100000, 0x00000008, 0x00100008, 0x00000200, 0x00100200, 0x00000208, 0x00100208, 0x00000000, 0x00100000, 0x00000008, 0x00100008, @@ -1003,14 +1000,14 @@ class DES extends Base 0x04022200, 0x04122200, 0x04022208, 0x04122208, 0x04022000, 0x04122000, 0x04022008, 0x04122008, 0x04022200, 0x04122200, 0x04022208, 0x04122208 - ); - static $pc2mapd1 = array( + ]; + static $pc2mapd1 = [ 0x00000000, 0x00000001, 0x08000000, 0x08000001, 0x00200000, 0x00200001, 0x08200000, 0x08200001, 0x00000002, 0x00000003, 0x08000002, 0x08000003, 0x00200002, 0x00200003, 0x08200002, 0x08200003 - ); - static $pc2mapd2 = array( + ]; + static $pc2mapd2 = [ 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x04000000, 0x04100000, 0x04000800, 0x04100800, @@ -1075,8 +1072,8 @@ class DES extends Base 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04 - ); - static $pc2mapd3 = array( + ]; + static $pc2mapd3 = [ 0x00000000, 0x00010000, 0x02000000, 0x02010000, 0x00000020, 0x00010020, 0x02000020, 0x02010020, 0x00040000, 0x00050000, 0x02040000, 0x02050000, @@ -1141,8 +1138,8 @@ class DES extends Base 0x20002030, 0x20012030, 0x22002030, 0x22012030, 0x20042010, 0x20052010, 0x22042010, 0x22052010, 0x20042030, 0x20052030, 0x22042030, 0x22052030 - ); - static $pc2mapd4 = array( + ]; + static $pc2mapd4 = [ 0x00000000, 0x00000400, 0x01000000, 0x01000400, 0x00000000, 0x00000400, 0x01000000, 0x01000400, 0x00000100, 0x00000500, 0x01000100, 0x01000500, @@ -1207,33 +1204,33 @@ class DES extends Base 0x10081008, 0x10081408, 0x11081008, 0x11081408, 0x10081108, 0x10081508, 0x11081108, 0x11081508, 0x10081108, 0x10081508, 0x11081108, 0x11081508 - ); + ]; - $keys = array(); + $keys = []; for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { // pad the key and remove extra characters as appropriate. $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0"); // Perform the PC/1 transformation and compute C and D. $t = unpack('Nl/Nr', $key); - list($l, $r) = array($t['l'], $t['r']); - $key = ($this->shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | - ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | - ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | - ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | - ($this->shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | - ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | - ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | - ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); + list($l, $r) = [$t['l'], $t['r']]; + $key = (self::$shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | + (self::$shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | + (self::$shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | + (self::$shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | + (self::$shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | + (self::$shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | + (self::$shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | + (self::$shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); $key = unpack('Nc/Nd', $key); $c = ( $key['c'] >> 4) & 0x0FFFFFFF; $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); - $keys[$des_round] = array( - self::ENCRYPT => array(), + $keys[$des_round] = [ + self::ENCRYPT => [], self::DECRYPT => array_fill(0, 32, 0) - ); - for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) { + ]; + for ($i = 0, $ki = 31; $i < 16; ++$i, $ki -= 2) { $c <<= $shifts[$i]; $c = ($c | ($c >> 28)) & 0x0FFFFFFF; $d <<= $shifts[$i]; @@ -1246,9 +1243,9 @@ class DES extends Base $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF]; // Reorder: odd bytes/even bytes. Push the result in key schedule. - $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) | + $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) | (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); - $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) | + $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) | (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); $keys[$des_round][self::ENCRYPT][ ] = $val1; $keys[$des_round][self::DECRYPT][$ki - 1] = $val1; @@ -1259,7 +1256,7 @@ class DES extends Base switch ($this->des_rounds) { case 3: // 3DES keys - $this->keys = array( + $this->keys = [ self::ENCRYPT => array_merge( $keys[0][self::ENCRYPT], $keys[1][self::DECRYPT], @@ -1270,174 +1267,126 @@ class DES extends Base $keys[1][self::ENCRYPT], $keys[0][self::DECRYPT] ) - ); + ]; break; // case 1: // DES keys default: - $this->keys = array( + $this->keys = [ self::ENCRYPT => $keys[0][self::ENCRYPT], self::DECRYPT => $keys[0][self::DECRYPT] - ); + ]; } } /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib\Crypt\Base::_setupInlineCrypt() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() */ - function _setupInlineCrypt() + protected function setupInlineCrypt() { - $lambda_functions =& self::_getLambdaFunctions(); - // Engine configuration for: // - DES ($des_rounds == 1) or // - 3DES ($des_rounds == 3) $des_rounds = $this->des_rounds; - // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. - // (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit) - // (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit) - // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one - $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); - - // Generation of a unique hash for our generated code - $code_hash = "Crypt_DES, $des_rounds, {$this->mode}"; - if ($gen_hi_opt_code) { - // For hi-optimized code, we create for each combination of - // $mode, $des_rounds and $this->key its own encrypt/decrypt function. - // After max 10 hi-optimized functions, we create generic - // (still very fast.. but not ultra) functions for each $mode/$des_rounds - // Currently 2 * 5 generic functions will be then max. possible. - $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); - } - - // Is there a re-usable $lambda_functions in there? If not, we have to create it. - if (!isset($lambda_functions[$code_hash])) { - // Init code for both, encrypt and decrypt. - $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; - if (!$sbox1) { - $sbox1 = array_map("intval", $self->sbox1); - $sbox2 = array_map("intval", $self->sbox2); - $sbox3 = array_map("intval", $self->sbox3); - $sbox4 = array_map("intval", $self->sbox4); - $sbox5 = array_map("intval", $self->sbox5); - $sbox6 = array_map("intval", $self->sbox6); - $sbox7 = array_map("intval", $self->sbox7); - $sbox8 = array_map("intval", $self->sbox8);' - /* Merge $shuffle with $[inv]ipmap */ . ' - for ($i = 0; $i < 256; ++$i) { - $shuffleip[] = $self->shuffle[$self->ipmap[$i]]; - $shuffleinvip[] = $self->shuffle[$self->invipmap[$i]]; - } + $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; + if (!$sbox1) { + $sbox1 = array_map("intval", self::$sbox1); + $sbox2 = array_map("intval", self::$sbox2); + $sbox3 = array_map("intval", self::$sbox3); + $sbox4 = array_map("intval", self::$sbox4); + $sbox5 = array_map("intval", self::$sbox5); + $sbox6 = array_map("intval", self::$sbox6); + $sbox7 = array_map("intval", self::$sbox7); + $sbox8 = array_map("intval", self::$sbox8);' + /* Merge $shuffle with $[inv]ipmap */ . ' + for ($i = 0; $i < 256; ++$i) { + $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; + $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; } + } + '; + + $k = [ + self::ENCRYPT => $this->keys[self::ENCRYPT], + self::DECRYPT => $this->keys[self::DECRYPT] + ]; + $init_encrypt = ''; + $init_decrypt = ''; + + // Creating code for en- and decryption. + $crypt_block = []; + foreach ([self::ENCRYPT, self::DECRYPT] as $c) { + /* Do the initial IP permutation. */ + $crypt_block[$c] = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + $in = unpack("N*", + ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") + ); + ' . /* Extract L0 and R0 */ ' + $l = $in[1]; + $r = $in[2]; '; - switch (true) { - case $gen_hi_opt_code: - // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers. - // No futher initialisation of the $keys schedule is necessary. - // That is the extra performance boost. - $k = array( - self::ENCRYPT => $this->keys[self::ENCRYPT], - self::DECRYPT => $this->keys[self::DECRYPT] - ); - $init_encrypt = ''; - $init_decrypt = ''; - break; - default: - // In generic optimized code mode, we have to use, as the best compromise [currently], - // our key schedule as $ke/$kd arrays. (with hardcoded indexes...) - $k = array( - self::ENCRYPT => array(), - self::DECRYPT => array() - ); - for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) { - $k[self::ENCRYPT][$i] = '$ke[' . $i . ']'; - $k[self::DECRYPT][$i] = '$kd[' . $i . ']'; - } - $init_encrypt = '$ke = $self->keys[$self::ENCRYPT];'; - $init_decrypt = '$kd = $self->keys[$self::DECRYPT];'; - break; - } + $l = '$l'; + $r = '$r'; - // Creating code for en- and decryption. - $crypt_block = array(); - foreach (array(self::ENCRYPT, self::DECRYPT) as $c) { - /* Do the initial IP permutation. */ - $crypt_block[$c] = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - $in = unpack("N*", - ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") - ); - ' . /* Extract L0 and R0 */ ' - $l = $in[1]; - $r = $in[2]; - '; + // Perform DES or 3DES. + for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { + // Perform the 16 steps. + for ($i = 0; $i < 16; ++$i) { + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + $crypt_block[$c] .= ' + $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; + $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . + /* S-box indexing. */ + $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; + '; + // end of "the Feistel (F) function" - $l = '$l'; - $r = '$r'; - - // Perform DES or 3DES. - for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { - // Perform the 16 steps. - for ($i = 0; $i < 16; ++$i) { - // start of "the Feistel (F) function" - see the following URL: - // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png - // Merge key schedule. - $crypt_block[$c].= ' - $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; - $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . - /* S-box indexing. */ - $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ - $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ - $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ - $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; - '; - // end of "the Feistel (F) function" - - // swap L & R - list($l, $r) = array($r, $l); - } - list($l, $r) = array($r, $l); + // swap L & R + list($l, $r) = [$r, $l]; } - - // Perform the inverse IP permutation. - $crypt_block[$c].= '$in = - ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); - '; + list($l, $r) = [$r, $l]; } - // Creates the inline-crypt function - $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( - array( - 'init_crypt' => $init_crypt, - 'init_encrypt' => $init_encrypt, - 'init_decrypt' => $init_decrypt, - 'encrypt_block' => $crypt_block[self::ENCRYPT], - 'decrypt_block' => $crypt_block[self::DECRYPT] - ) - ); + // Perform the inverse IP permutation. + $crypt_block[$c] .= '$in = + ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + '; } - // Set the inline-crypt function as callback in: $this->inline_crypt - $this->inline_crypt = $lambda_functions[$code_hash]; + // Creates the inline-crypt function + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $crypt_block[self::ENCRYPT], + 'decrypt_block' => $crypt_block[self::DECRYPT] + ] + ); } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php new file mode 100644 index 000000000..e1deaf086 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php @@ -0,0 +1,405 @@ + + * + * + * + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\DH\Parameters; +use phpseclib3\Crypt\DH\PrivateKey; +use phpseclib3\Crypt\DH\PublicKey; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP (EC)DH implementation + * + * @author Jim Wigginton + */ +abstract class DH extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'DH'; + + /** + * DH prime + * + * @var \phpseclib3\Math\BigInteger + */ + protected $prime; + + /** + * DH Base + * + * Prime divisor of p-1 + * + * @var \phpseclib3\Math\BigInteger + */ + protected $base; + + /** + * Public Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicKey; + + /** + * Create DH parameters + * + * This method is a bit polymorphic. It can take any of the following: + * - two BigInteger's (prime and base) + * - an integer representing the size of the prime in bits (the base is assumed to be 2) + * - a string (eg. diffie-hellman-group14-sha1) + * + * @return Parameters + */ + public static function createParameters(...$args) + { + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); + } + + $params = new Parameters(); + if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { + //if (!$args[0]->isPrime()) { + // throw new \InvalidArgumentException('The first parameter should be a prime number'); + //} + $params->prime = $args[0]; + $params->base = $args[1]; + return $params; + } elseif (count($args) == 1 && is_numeric($args[0])) { + $params->prime = BigInteger::randomPrime($args[0]); + $params->base = new BigInteger(2); + return $params; + } elseif (count($args) != 1 || !is_string($args[0])) { + throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); + } + switch ($args[0]) { + // see http://tools.ietf.org/html/rfc2409#section-6.2 and + // http://tools.ietf.org/html/rfc2412, appendex E + case 'diffie-hellman-group1-sha1': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; + break; + // see http://tools.ietf.org/html/rfc3526#section-3 + case 'diffie-hellman-group14-sha1': // 2048-bit MODP Group + case 'diffie-hellman-group14-sha256': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-4 + case 'diffie-hellman-group15-sha512': // 3072-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-5 + case 'diffie-hellman-group16-sha512': // 4096-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-6 + case 'diffie-hellman-group17-sha512': // 6144-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . + 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . + 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . + 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . + '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . + 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . + '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-7 + case 'diffie-hellman-group18-sha512': // 8192-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . + 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . + 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . + 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . + '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . + 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . + '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4' . + '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED' . + '2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652D' . + 'E3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B' . + '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6' . + '6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851D' . + 'F9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92' . + '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA' . + '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; + break; + default: + throw new \InvalidArgumentException('Invalid named prime provided'); + } + + $params->prime = new BigInteger($prime, 16); + $params->base = new BigInteger(2); + + return $params; + } + + /** + * Create public / private key pair. + * + * The rationale for the second parameter is described in http://tools.ietf.org/html/rfc4419#section-6.2 : + * + * "To increase the speed of the key exchange, both client and server may + * reduce the size of their private exponents. It should be at least + * twice as long as the key material that is generated from the shared + * secret. For more details, see the paper by van Oorschot and Wiener + * [VAN-OORSCHOT]." + * + * $length is in bits + * + * @param Parameters $params + * @param int $length optional + * @return DH\PrivateKey + */ + public static function createKey(Parameters $params, $length = 0) + { + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + $one = new BigInteger(1); + if ($length) { + $max = $one->bitwise_leftShift($length); + $max = $max->subtract($one); + } else { + $max = $params->prime->subtract($one); + } + + $key = new PrivateKey(); + $key->prime = $params->prime; + $key->base = $params->base; + $key->privateKey = BigInteger::randomRange($one, $max); + $key->publicKey = $key->base->powMod($key->privateKey, $key->prime); + return $key; + } + + /** + * Compute Shared Secret + * + * @param PrivateKey|EC $private + * @param PublicKey|BigInteger|string $public + * @return mixed + */ + public static function computeSecret($private, $public) + { + if ($private instanceof PrivateKey) { // DH\PrivateKey + switch (true) { + case $public instanceof PublicKey: + if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { + throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); + } + return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); + case is_string($public): + $public = new BigInteger($public, -256); + // fall-through + case $public instanceof BigInteger: + return $public->powMod($private->privateKey, $private->prime)->toBytes(true); + default: + throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); + } + } + + if ($private instanceof EC\PrivateKey) { + switch (true) { + case $public instanceof EC\PublicKey: + $public = $public->getEncodedCoordinates(); + // fall-through + case is_string($public): + $point = $private->multiply($public); + switch ($private->getCurve()) { + case 'Curve25519': + case 'Curve448': + $secret = $point; + break; + default: + // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned + $secret = substr($point, 1, (strlen($point) - 1) >> 1); + } + /* + if (($secret[0] & "\x80") === "\x80") { + $secret = "\0$secret"; + } + */ + return $secret; + default: + throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); + } + } + } + + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return AsymmetricKey + */ + public static function load($key, $password = false) + { + try { + return EC::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + return parent::load($key, $password); + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + if (!isset($components['privateKey']) && !isset($components['publicKey'])) { + $new = new Parameters(); + } else { + $new = isset($components['privateKey']) ? + new PrivateKey() : + new PublicKey(); + } + + $new->prime = $components['prime']; + $new->base = $components['base']; + + if (isset($components['privateKey'])) { + $new->privateKey = $components['privateKey']; + } + if (isset($components['publicKey'])) { + $new->publicKey = $components['publicKey']; + } + + return $new; + } + + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + throw new UnsupportedOperationException('DH does not use a hash algorithm'); + } + + /** + * Returns the hash algorithm currently being used + * + */ + public function getHash() + { + throw new UnsupportedOperationException('DH does not use a hash algorithm'); + } + + /** + * Returns the parameters + * + * A public / private key is only returned if the currently loaded "key" contains an x or y + * value. + * + * @see self::getPublicKey() + * @return mixed + */ + public function getParameters() + { + $type = DH::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + $key = $type::saveParameters($this->prime, $this->base); + return DH::load($key, 'PKCS1'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..65a0a5dbc --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php @@ -0,0 +1,77 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * "PKCS1" Formatted DH Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + return $components; + } + + /** + * Convert EC parameters to the appropriate format + * + * @return string + */ + public static function saveParameters(BigInteger $prime, BigInteger $base, array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + + return "-----BEGIN DH PARAMETERS-----\r\n" . + chunk_split(base64_encode($params), 64) . + "-----END DH PARAMETERS-----\r\n"; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..c330a3c76 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php @@ -0,0 +1,132 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted DH Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'dhKeyAgreement'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.3.1'; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + $decoded = ASN1::decodeBER($key[$type]); + switch (true) { + case !isset($decoded): + case !isset($decoded[0]['content']): + case !$decoded[0]['content'] instanceof BigInteger: + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components[$type] = $decoded[0]['content']; + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Math\BigInteger $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]); + return self::wrapPublicKey($key, $params); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php new file mode 100644 index 000000000..c0ded84cd --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php @@ -0,0 +1,36 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\DH; + +/** + * DH Parameters + * + * @author Jim Wigginton + */ +final class Parameters extends DH +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->prime, $this->base, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php new file mode 100644 index 000000000..737781f87 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php @@ -0,0 +1,75 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DH; + +/** + * DH Private Key + * + * @author Jim Wigginton + */ +final class PrivateKey extends DH +{ + use Common\Traits\PasswordProtected; + + /** + * Private Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $privateKey; + + /** + * Public Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicKey; + + /** + * Returns the public key + * + * @return DH\PublicKey + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + + $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); + + return DH::loadFormat('PKCS8', $key); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + + return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php new file mode 100644 index 000000000..87726a5a3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php @@ -0,0 +1,49 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DH; + +/** + * DH Public Key + * + * @author Jim Wigginton + */ +final class PublicKey extends DH +{ + use Common\Traits\Fingerprint; + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); + } + + /** + * Returns the public key as a BigInteger + * + * @return \phpseclib3\Math\BigInteger + */ + public function toBigInteger() + { + return $this->publicKey; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php new file mode 100644 index 000000000..0123c66c5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php @@ -0,0 +1,337 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\DSA\Parameters; +use phpseclib3\Crypt\DSA\PrivateKey; +use phpseclib3\Crypt\DSA\PublicKey; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP FIPS 186-4 compliant implementation of DSA. + * + * @author Jim Wigginton + */ +abstract class DSA extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'DSA'; + + /** + * DSA Prime P + * + * @var \phpseclib3\Math\BigInteger + */ + protected $p; + + /** + * DSA Group Order q + * + * Prime divisor of p-1 + * + * @var \phpseclib3\Math\BigInteger + */ + protected $q; + + /** + * DSA Group Generator G + * + * @var \phpseclib3\Math\BigInteger + */ + protected $g; + + /** + * DSA public key value y + * + * @var \phpseclib3\Math\BigInteger + */ + protected $y; + + /** + * Signature Format + * + * @var string + */ + protected $sigFormat; + + /** + * Signature Format (Short) + * + * @var string + */ + protected $shortFormat; + + /** + * Create DSA parameters + * + * @param int $L + * @param int $N + * @return \phpseclib3\Crypt\DSA|bool + */ + public static function createParameters($L = 2048, $N = 224) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); + } + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + switch (true) { + case $N == 160: + /* + in FIPS 186-1 and 186-2 N was fixed at 160 whereas K had an upper bound of 1024. + RFC 4253 (SSH Transport Layer Protocol) references FIPS 186-2 and as such most + SSH DSA implementations only support keys with an N of 160. + puttygen let's you set the size of L (but not the size of N) and uses 2048 as the + default L value. that's not really compliant with any of the FIPS standards, however, + for the purposes of maintaining compatibility with puttygen, we'll support it + */ + //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160: + // FIPS 186-3 changed this as follows: + //case $L == 1024 && $N == 160: + case $L == 2048 && $N == 224: + case $L == 2048 && $N == 256: + case $L == 3072 && $N == 256: + break; + default: + throw new \InvalidArgumentException('Invalid values for N and L'); + } + + $two = new BigInteger(2); + + $q = BigInteger::randomPrime($N); + $divisor = $q->multiply($two); + + do { + $x = BigInteger::random($L); + list(, $c) = $x->divide($divisor); + $p = $x->subtract($c->subtract(self::$one)); + } while ($p->getLength() != $L || !$p->isPrime()); + + $p_1 = $p->subtract(self::$one); + list($e) = $p_1->divide($q); + + // quoting http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=50 , + // "h could be obtained from a random number generator or from a counter that + // changes after each use". PuTTY (sshdssg.c) starts h off at 1 and increments + // it on each loop. wikipedia says "commonly h = 2 is used" so we'll just do that + $h = clone $two; + while (true) { + $g = $h->powMod($e, $p); + if (!$g->equals(self::$one)) { + break; + } + $h = $h->add(self::$one); + } + + $dsa = new Parameters(); + $dsa->p = $p; + $dsa->q = $q; + $dsa->g = $g; + + return $dsa; + } + + /** + * Create public / private key pair. + * + * This method is a bit polymorphic. It can take a DSA/Parameters object, L / N as two distinct parameters or + * no parameters (at which point L and N will be generated with this method) + * + * Returns the private key, from which the publickey can be extracted + * + * @param int[] ...$args + * @return DSA\PrivateKey + */ + public static function createKey(...$args) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) { + $params = self::createParameters($args[0], $args[1]); + } elseif (count($args) == 1 && $args[0] instanceof Parameters) { + $params = $args[0]; + } elseif (!count($args)) { + $params = self::createParameters(); + } else { + throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.'); + } + + $private = new PrivateKey(); + $private->p = $params->p; + $private->q = $params->q; + $private->g = $params->g; + + $private->x = BigInteger::randomRange(self::$one, $private->q->subtract(self::$one)); + $private->y = $private->g->powMod($private->x, $private->p); + + //$public = clone $private; + //unset($public->x); + + return $private + ->withHash($params->hash->getHash()) + ->withSignatureFormat($params->shortFormat); + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (!isset($components['x']) && !isset($components['y'])) { + $new = new Parameters(); + } elseif (isset($components['x'])) { + $new = new PrivateKey(); + $new->x = $components['x']; + } else { + $new = new PublicKey(); + } + + $new->p = $components['p']; + $new->q = $components['q']; + $new->g = $components['g']; + + if (isset($components['y'])) { + $new->y = $components['y']; + } + + return $new; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); + $this->shortFormat = 'ASN1'; + + parent::__construct(); + } + + /** + * Returns the key size + * + * More specifically, this L (the length of DSA Prime P) and N (the length of DSA Group Order q) + * + * @return array + */ + public function getLength() + { + return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()]; + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? + 'OpenSSL' : 'PHP'; + } + + /** + * Returns the parameters + * + * A public / private key is only returned if the currently loaded "key" contains an x or y + * value. + * + * @see self::getPublicKey() + * @return mixed + */ + public function getParameters() + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + $key = $type::saveParameters($this->p, $this->q, $this->g); + return DSA::load($key, 'PKCS1') + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @param string $format + */ + public function withSignatureFormat($format) + { + $new = clone $this; + $new->shortFormat = $format; + $new->sigFormat = self::validatePlugin('Signature', $format); + return $new; + } + + /** + * Returns the signature format currently being used + * + */ + public function getSignatureFormat() + { + return $this->shortFormat; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..cc204fa94 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,118 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSH Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends Progenitor +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-dss']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + + list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']); + + return compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + + list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']); + + $comment = $parsed['comment']; + + return compact('p', 'q', 'g', 'y', 'comment'); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + // from : + // string "ssh-dss" + // mpint p + // mpint q + // mpint g + // mpint y + $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $DSAPublicKey; + } + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment; + + return $DSAPublicKey; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]); + $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..52a049928 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php @@ -0,0 +1,143 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#1 Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); + if (is_array($key)) { + return $key; + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAPrivateKey::MAP); + if (is_array($key)) { + return $key; + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); + if (is_array($key)) { + return $key; + } + + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + /** + * Convert DSA parameters to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @return string + */ + public static function saveParameters(BigInteger $p, BigInteger $q, BigInteger $g) + { + $key = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + + $key = ASN1::encodeDER($key, Maps\DSAParams::MAP); + + return "-----BEGIN DSA PARAMETERS-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END DSA PARAMETERS-----\r\n"; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $key = [ + 'version' => 0, + 'p' => $p, + 'q' => $q, + 'g' => $g, + 'y' => $y, + 'x' => $x + ]; + + $key = ASN1::encodeDER($key, Maps\DSAPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'DSA', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); + + return self::wrapPublicKey($key, 'DSA'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..004881e8c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php @@ -0,0 +1,146 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'id-dsa'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.10040.4.1'; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + $decoded = ASN1::decodeBER($key[$type]); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $var = $type == 'privateKey' ? 'x' : 'y'; + $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); + if (!$components[$var] instanceof BigInteger) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (isset($key['meta'])) { + $components['meta'] = $key['meta']; + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $params = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($x, Maps\DSAPublicKey::MAP); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) + { + $params = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); + return self::wrapPublicKey($key, $params); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..177bfdd4f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php @@ -0,0 +1,109 @@ + 160 kinda useless, hence this handlers not supporting such keys. + * + * PHP version 5 + * + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * PuTTY Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends Progenitor +{ + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH'; + + /** + * Algorithm Identifier + * + * @var array + */ + protected static $types = ['ssh-dss']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + extract($components); + unset($components['public'], $components['private']); + + list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public); + list($x) = Strings::unpackSSH2('i', $private); + + return compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + $public = Strings::packSSH2('iiii', $p, $q, $g, $y); + $private = Strings::packSSH2('i', $x); + + return self::wrapPrivateKey($public, $private, 'ssh-dss', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dss'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php new file mode 100644 index 000000000..201aa6f95 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php @@ -0,0 +1,85 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; + +/** + * Raw DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @param array $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); + } + + switch (true) { + case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): + case !$key['p'] instanceof BigInteger: + case !$key['q'] instanceof BigInteger: + case !$key['g'] instanceof BigInteger: + case !isset($key['x']) && !isset($key['y']): + case isset($key['x']) && !$key['x'] instanceof BigInteger: + case isset($key['y']) && !$key['y'] instanceof BigInteger: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; + + return array_intersect_key($key, $options); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '') + { + return compact('p', 'q', 'g', 'y', 'x'); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + return compact('p', 'q', 'g', 'y'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php new file mode 100644 index 000000000..fc3636771 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php @@ -0,0 +1,132 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger; + +/** + * XML Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (!class_exists('DOMDocument')) { + throw new BadConfigurationException('The dom extension is not setup correctly on this system'); + } + + $use_errors = libxml_use_internal_errors(true); + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); + if (!$temp->length) { + continue; + } + $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'p': // a prime modulus meeting the [DSS] requirements + // Parameters P, Q, and G can be public and common to a group of users. They might be known + // from application context. As such, they are optional but P and Q must either both appear + // or both be absent + $components['p'] = $value; + break; + case 'q': // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 + $components['q'] = $value; + break; + case 'g': // an integer with certain properties with respect to P and Q + $components['g'] = $value; + break; + case 'y': // G**X mod P (where X is part of the private key and not made public) + $components['y'] = $value; + // the remaining options do not do anything + case 'j': // (P - 1) / Q + // Parameter J is available for inclusion solely for efficiency as it is calculatable from + // P and Q + case 'seed': // a DSA prime generation seed + // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm + // specified in [DSS]. As such, they are optional but must either both be present or both + // be absent + case 'pgencounter': // a DSA prime generation counter + } + } + + libxml_use_internal_errors($use_errors); + + if (!isset($components['y'])) { + throw new \UnexpectedValueException('Key is missing y component'); + } + + switch (true) { + case !isset($components['p']): + case !isset($components['q']): + case !isset($components['g']): + return ['y' => $components['y']]; + } + + return $components; + } + + /** + * Convert a public key to the appropriate format + * + * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + return "\r\n" . + '

' . Strings::base64_encode($p->toBytes()) . "

\r\n" . + ' ' . Strings::base64_encode($q->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($g->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($y->toBytes()) . "\r\n" . + '
'; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php new file mode 100644 index 000000000..df52beed4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php @@ -0,0 +1,62 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\File\ASN1 as Encoder; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @param string $sig + * @return array|bool + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $decoded = Encoder::decodeBER($sig); + if (empty($decoded)) { + return false; + } + $components = Encoder::asn1map($decoded[0], Maps\DssSigValue::MAP); + + return $components; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return Encoder::encodeDER(compact('r', 's'), Maps\DssSigValue::MAP); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php new file mode 100644 index 000000000..2657a2a87 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php @@ -0,0 +1,25 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; + +/** + * Raw DSA Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw extends Progenitor +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php new file mode 100644 index 000000000..dbfceabba --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php @@ -0,0 +1,74 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; + +/** + * SSH2 Signature Handler + * + * @author Jim Wigginton + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $result = Strings::unpackSSH2('ss', $sig); + if ($result === false) { + return false; + } + list($type, $blob) = $result; + if ($type != 'ssh-dss' || strlen($blob) != 40) { + return false; + } + + return [ + 'r' => new BigInteger(substr($blob, 0, 20), 256), + 's' => new BigInteger(substr($blob, 20), 256) + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + if ($r->getLength() > 160 || $s->getLength() > 160) { + return false; + } + return Strings::packSSH2( + 'ss', + 'ssh-dss', + str_pad($r->toBytes(), 20, "\0", STR_PAD_LEFT) . + str_pad($s->toBytes(), 20, "\0", STR_PAD_LEFT) + ); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php new file mode 100644 index 000000000..84d16ba68 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php @@ -0,0 +1,36 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\DSA; + +/** + * DSA Parameters + * + * @author Jim Wigginton + */ +final class Parameters extends DSA +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->p, $this->q, $this->g, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php new file mode 100644 index 000000000..74d3e69e3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php @@ -0,0 +1,152 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Math\BigInteger; + +/** + * DSA Private Key + * + * @author Jim Wigginton + */ +final class PrivateKey extends DSA implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * DSA secret exponent x + * + * @var \phpseclib3\Math\BigInteger + */ + protected $x; + + /** + * Returns the public key + * + * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key + * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. + * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this + * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g + * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified + * by getting a DSA PKCS8 public key: + * + * "openssl dsa -in private.dsa -pubout -outform PEM" + * + * ie. just swap out rsa with dsa in the rsa command above. + * + * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA + * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature + * without the parameters and the PKCS1 DSA public key format does not include the parameters. + * + * @see self::getPrivateKey() + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + + $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); + + return DSA::loadFormat('PKCS8', $key) + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return mixed + */ + public function sign($message) + { + $format = $this->sigFormat; + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $signature = ''; + $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); + + if ($result) { + if ($this->shortFormat == 'ASN1') { + return $signature; + } + + extract(ASN1Signature::load($signature)); + + return $format::save($r, $s); + } + } + + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + + while (true) { + $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($this->q); + $temp = $h->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + if (!$s->equals(self::$zero)) { + break; + } + } + + // the following is an RFC6979 compliant implementation of deterministic DSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + + return $format::save($r, $s); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + + return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php new file mode 100644 index 000000000..c14ffbdf5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php @@ -0,0 +1,86 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; + +/** + * DSA Public Key + * + * @author Jim Wigginton + */ +final class PublicKey extends DSA implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Verify a signature + * + * @see self::verify() + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + $format = $this->sigFormat; + + $params = $format::load($signature); + if ($params === false || count($params) != 2) { + return false; + } + extract($params); + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; + + $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); + + if ($result != -1) { + return (bool) $result; + } + } + + $q_1 = $this->q->subtract(self::$one); + if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { + return false; + } + + $w = $s->modInverse($this->q); + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + list(, $u1) = $h->multiply($w)->divide($this->q); + list(, $u2) = $r->multiply($w)->divide($this->q); + $v1 = $this->g->powMod($u1, $this->p); + $v2 = $this->y->powMod($u2, $this->p); + list(, $v) = $v1->multiply($v2)->divide($this->p); + list(, $v) = $v->divide($this->q); + + return $v->equals($r); + } + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php new file mode 100644 index 000000000..10b38254a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php @@ -0,0 +1,480 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Ed448; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\EC\Parameters; +use phpseclib3\Crypt\EC\PrivateKey; +use phpseclib3\Crypt\EC\PublicKey; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps\ECParameters; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP implementation of EC. + * + * @author Jim Wigginton + */ +abstract class EC extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'EC'; + + /** + * Public Key QA + * + * @var object[] + */ + protected $QA; + + /** + * Curve + * + * @var \phpseclib3\Crypt\EC\BaseCurves\Base + */ + protected $curve; + + /** + * Signature Format + * + * @var string + */ + protected $format; + + /** + * Signature Format (Short) + * + * @var string + */ + protected $shortFormat; + + /** + * Curve Name + * + * @var string + */ + private $curveName; + + /** + * Curve Order + * + * Used for deterministic ECDSA + * + * @var \phpseclib3\Math\BigInteger + */ + protected $q; + + /** + * Alias for the private key + * + * Used for deterministic ECDSA. AsymmetricKey expects $x. I don't like x because + * with x you have x * the base point yielding an (x, y)-coordinate that is the + * public key. But the x is different depending on which side of the equal sign + * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. + * + * @var \phpseclib3\Math\BigInteger + */ + protected $x; + + /** + * Context + * + * @var string + */ + protected $context; + + /** + * Signature Format + * + * @var string + */ + protected $sigFormat; + + /** + * Create public / private key pair. + * + * @param string $curve + * @return \phpseclib3\Crypt\EC\PrivateKey + */ + public static function createKey($curve) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + $curve = strtolower($curve); + if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) { + $kp = sodium_crypto_sign_keypair(); + + $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp)); + //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp)); + + $privatekey->curveName = 'Ed25519'; + //$publickey->curveName = $curve; + + return $privatekey; + } + + $privatekey = new PrivateKey(); + + $curveName = $curve; + if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) { + $curveName = ucfirst($curveName); + } elseif (substr($curveName, 0, 10) == 'brainpoolp') { + $curveName = 'brainpoolP' . substr($curveName, 10); + } + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; + + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported'); + } + + $reflect = new \ReflectionClass($curve); + $curveName = $reflect->isFinal() ? + $reflect->getParentClass()->getShortName() : + $reflect->getShortName(); + + $curve = new $curve(); + if ($curve instanceof TwistedEdwardsCurve) { + $arr = $curve->extractSecret(Random::string($curve instanceof Ed448 ? 57 : 32)); + $privatekey->dA = $dA = $arr['dA']; + $privatekey->secret = $arr['secret']; + } else { + $privatekey->dA = $dA = $curve->createRandomMultiplier(); + } + if ($curve instanceof Curve25519 && self::$engines['libsodium']) { + //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000'); + //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r); + $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes()); + $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))]; + } else { + $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA); + } + $privatekey->curve = $curve; + + //$publickey = clone $privatekey; + //unset($publickey->dA); + //unset($publickey->x); + + $privatekey->curveName = $curveName; + //$publickey->curveName = $curveName; + + if ($privatekey->curve instanceof TwistedEdwardsCurve) { + return $privatekey->withHash($curve::HASH); + } + + return $privatekey; + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (!isset($components['dA']) && !isset($components['QA'])) { + $new = new Parameters(); + $new->curve = $components['curve']; + return $new; + } + + $new = isset($components['dA']) ? + new PrivateKey() : + new PublicKey(); + $new->curve = $components['curve']; + $new->QA = $components['QA']; + + if (isset($components['dA'])) { + $new->dA = $components['dA']; + $new->secret = $components['secret']; + } + + if ($new->curve instanceof TwistedEdwardsCurve) { + return $new->withHash($components['curve']::HASH); + } + + return $new; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); + $this->shortFormat = 'ASN1'; + + parent::__construct(); + } + + /** + * Returns the curve + * + * Returns a string if it's a named curve, an array if not + * + * @return string|array + */ + public function getCurve() + { + if ($this->curveName) { + return $this->curveName; + } + + if ($this->curve instanceof MontgomeryCurve) { + $this->curveName = $this->curve instanceof Curve25519 ? 'Curve25519' : 'Curve448'; + return $this->curveName; + } + + if ($this->curve instanceof TwistedEdwardsCurve) { + $this->curveName = $this->curve instanceof Ed25519 ? 'Ed25519' : 'Ed448'; + return $this->curveName; + } + + $params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]); + $decoded = ASN1::extractBER($params); + $decoded = ASN1::decodeBER($decoded); + $decoded = ASN1::asn1map($decoded[0], ECParameters::MAP); + if (isset($decoded['namedCurve'])) { + $this->curveName = $decoded['namedCurve']; + return $decoded['namedCurve']; + } + + if (!$namedCurves) { + PKCS1::useSpecifiedCurve(); + } + + return $decoded; + } + + /** + * Returns the key size + * + * Quoting https://tools.ietf.org/html/rfc5656#section-2, + * + * "The size of a set of elliptic curve domain parameters on a prime + * curve is defined as the number of bits in the binary representation + * of the field order, commonly denoted by p. Size on a + * characteristic-2 curve is defined as the number of bits in the binary + * representation of the field, commonly denoted by m. A set of + * elliptic curve domain parameters defines a group of order n generated + * by a base point P" + * + * @return int + */ + public function getLength() + { + return $this->curve->getLength(); + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ? + 'libsodium' : 'PHP'; + } + + return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? + 'OpenSSL' : 'PHP'; + } + + /** + * Returns the public key coordinates as a string + * + * Used by ECDH + * + * @return string + */ + public function getEncodedCoordinates() + { + if ($this->curve instanceof MontgomeryCurve) { + return strrev($this->QA[0]->toBytes(true)); + } + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve->encodePoint($this->QA); + } + return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true); + } + + /** + * Returns the parameters + * + * @see self::getPublicKey() + * @param string $type optional + * @return mixed + */ + public function getParameters($type = 'PKCS1') + { + $type = self::validatePlugin('Keys', $type, 'saveParameters'); + + $key = $type::saveParameters($this->curve); + + return EC::load($key, 'PKCS1') + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @param string $format + */ + public function withSignatureFormat($format) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $new = clone $this; + $new->shortFormat = $format; + $new->sigFormat = self::validatePlugin('Signature', $format); + return $new; + } + + /** + * Returns the signature format currently being used + * + */ + public function getSignatureFormat() + { + return $this->shortFormat; + } + + /** + * Sets the context + * + * Used by Ed25519 / Ed448. + * + * @see self::sign() + * @see self::verify() + * @param string $context optional + */ + public function withContext($context = null) + { + if (!$this->curve instanceof TwistedEdwardsCurve) { + throw new UnsupportedCurveException('Only Ed25519 and Ed448 support contexts'); + } + + $new = clone $this; + if (!isset($context)) { + $new->context = null; + return $new; + } + if (!is_string($context)) { + throw new \InvalidArgumentException('setContext expects a string'); + } + if (strlen($context) > 255) { + throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); + } + $new->context = $context; + return $new; + } + + /** + * Returns the signature format currently being used + * + */ + public function getContext() + { + return $this->context; + } + + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + if ($this->curve instanceof Ed25519 && $hash != 'sha512') { + throw new UnsupportedAlgorithmException('Ed25519 only supports sha512 as a hash'); + } + if ($this->curve instanceof Ed448 && $hash != 'shake256-912') { + throw new UnsupportedAlgorithmException('Ed448 only supports shake256 with a length of 114 bytes'); + } + + return parent::withHash($hash); + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + if ($this->curve instanceof MontgomeryCurve) { + return ''; + } + + return parent::__toString(); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php new file mode 100644 index 000000000..dbc914be6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php @@ -0,0 +1,218 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; + +/** + * Base + * + * @author Jim Wigginton + */ +abstract class Base +{ + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Finite Field Integer factory + * + * @var \phpseclib3\Math\FiniteField\Integer + */ + protected $factory; + + /** + * Returns a random integer + * + * @return object + */ + public function randomInteger() + { + return $this->factory->randomInteger(); + } + + /** + * Converts a BigInteger to a \phpseclib3\Math\FiniteField\Integer integer + * + * @return object + */ + public function convertInteger(BigInteger $x) + { + return $this->factory->newInteger($x); + } + + /** + * Returns the length, in bytes, of the modulo + * + * @return integer + */ + public function getLengthInBytes() + { + return $this->factory->getLengthInBytes(); + } + + /** + * Returns the length, in bits, of the modulo + * + * @return integer + */ + public function getLength() + { + return $this->factory->getLength(); + } + + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + $alreadyInternal = isset($p[2]); + $r = $alreadyInternal ? + [[], $p] : + [[], $this->convertToInternal($p)]; + + $d = $d->toBits(); + for ($i = 0; $i < strlen($d); $i++) { + $d_i = (int) $d[$i]; + $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); + $r[$d_i] = $this->doublePoint($r[$d_i]); + } + + return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); + } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return BigInteger::randomRange($one, $this->order->subtract($one)); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + static $zero; + if (!isset($zero)) { + $zero = new BigInteger(); + } + + if (!isset($this->order)) { + throw new \RuntimeException('setOrder needs to be called before this method'); + } + if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { + throw new \RangeException('x must be between 1 and the order of the curve'); + } + } + + /** + * Sets the Order + */ + public function setOrder(BigInteger $order) + { + $this->order = $order; + } + + /** + * Returns the Order + * + * @return \phpseclib3\Math\BigInteger + */ + public function getOrder() + { + return $this->order; + } + + /** + * Use a custom defined modular reduction function + * + * @return object + */ + public function setReduction(callable $func) + { + $this->factory->setReduction($func); + } + + /** + * Returns the affine point + * + * @return object[] + */ + public function convertToAffine(array $p) + { + return $p; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return object[] + */ + public function convertToInternal(array $p) + { + return $p; + } + + /** + * Negates a point + * + * @return object[] + */ + public function negatePoint(array $p) + { + $temp = [ + $p[0], + $p[1]->negate() + ]; + if (isset($p[2])) { + $temp[] = $p[2]; + } + return $temp; + } + + /** + * Multiply and Add Points + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $p1 = $this->convertToInternal($points[0]); + $p2 = $this->convertToInternal($points[1]); + $p1 = $this->multiplyPoint($p1, $scalars[0]); + $p2 = $this->multiplyPoint($p2, $scalars[1]); + $r = $this->addPoint($p1, $p2); + return $this->convertToAffine($r); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php new file mode 100644 index 000000000..4fc6c70c0 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php @@ -0,0 +1,373 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\BinaryField\Integer as BinaryInteger; + +/** + * Curves over y^2 + x*y = x^3 + a*x^2 + b + * + * @author Jim Wigginton + */ +class Binary extends Base +{ + /** + * Binary Field Integer factory + * + * @var \phpseclib3\Math\BinaryField + */ + protected $factory; + + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(...$modulo) + { + $this->modulo = $modulo; + $this->factory = new BinaryField(...$modulo); + + $this->one = $this->factory->newInteger("\1"); + } + + /** + * Set coefficients a and b + * + * @param string $a + * @param string $b + */ + public function setCoefficients($a, $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger(pack('H*', $a)); + $this->b = $this->factory->newInteger(pack('H*', $b)); + } + + /** + * Set x and y coordinates for the base point + * + * @param string|BinaryInteger $x + * @param string|BinaryInteger $y + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !is_string($x) && !$x instanceof BinaryInteger: + throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); + case !is_string($y) && !$y instanceof BinaryInteger: + throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, + is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $o1 = $z1->multiply($z1); + $b = $x2->multiply($o1); + + if ($z2->equals($this->one)) { + $d = $y2->multiply($o1)->multiply($z1); + $e = $x1->add($b); + $f = $y1->add($d); + $z3 = $e->multiply($z1); + $h = $f->multiply($x2)->add($z3->multiply($y2)); + $i = $f->add($z3); + $g = $z3->multiply($z3); + $p1 = $this->a->multiply($g); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($h)); + + return [$x3, $y3, $z3]; + } + + $o2 = $z2->multiply($z2); + $a = $x1->multiply($o2); + $c = $y1->multiply($o2)->multiply($z2); + $d = $y2->multiply($o1)->multiply($z1); + $e = $a->add($b); + $f = $c->add($d); + $g = $e->multiply($z1); + $h = $f->multiply($x2)->add($g->multiply($y2)); + $z3 = $g->multiply($z2); + $i = $f->add($z3); + $p1 = $this->a->multiply($z3->multiply($z3)); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); + + return [$x3, $y3, $z3]; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + + list($x1, $y1, $z1) = $p; + + $a = $x1->multiply($x1); + $b = $a->multiply($a); + + if ($z1->equals($this->one)) { + $x3 = $b->add($this->b); + $z3 = clone $x1; + $p1 = $a->add($y1)->add($z3)->multiply($this->b); + $p2 = $a->add($y1)->multiply($b); + $y3 = $p1->add($p2); + + return [$x3, $y3, $z3]; + } + + $c = $z1->multiply($z1); + $d = $c->multiply($c); + $x3 = $b->add($this->b->multiply($d->multiply($d))); + $z3 = $x1->multiply($c); + $p1 = $b->multiply($z3); + $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); + $y3 = $p1->add($p2); + + return [$x3, $y3, $z3]; + } + + /** + * Returns the X coordinate and the derived Y coordinate + * + * Not supported because it is covered by patents. + * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , + * + * "Due to patent issues the compressed option is disabled by default for binary curves + * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at + * compile time." + * + * @return array + */ + public function derivePoint($m) + { + throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $lhs = $lhs->add($x->multiply($y)); + $x2 = $x->multiply($x); + $x3 = $x2->multiply($x); + $rhs = $x3->add($this->a->multiply($x2))->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [ + $x->multiply($z2), + $y->multiply($z2)->multiply($z) + ]; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p['fresh'] = true; + return $p; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php new file mode 100644 index 000000000..d8492ebc2 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php @@ -0,0 +1,335 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; + +/** + * Curves over y^2 = x^3 + b + * + * @author Jim Wigginton + */ +class KoblitzPrime extends Prime +{ + /** + * Basis + * + * @var list + */ + protected $basis; + + /** + * Beta + * + * @var PrimeField\Integer + */ + protected $beta; + + // don't overwrite setCoefficients() with one that only accepts one parameter so that + // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking + // purposes). + + /** + * Multiply and Add Points + * + * Uses a efficiently computable endomorphism to achieve a slight speedup + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/short.js#L219 + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + static $zero, $one, $two; + if (!isset($two)) { + $two = new BigInteger(2); + $one = new BigInteger(1); + } + + if (!isset($this->beta)) { + // get roots + $inv = $this->one->divide($this->two)->negate(); + $s = $this->three->negate()->squareRoot()->multiply($inv); + $betas = [ + $inv->add($s), + $inv->subtract($s) + ]; + $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; + //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; + } + + if (!isset($this->basis)) { + $factory = new PrimeField($this->order); + $tempOne = $factory->newInteger($one); + $tempTwo = $factory->newInteger($two); + $tempThree = $factory->newInteger(new BigInteger(3)); + + $inv = $tempOne->divide($tempTwo)->negate(); + $s = $tempThree->negate()->squareRoot()->multiply($inv); + + $lambdas = [ + $inv->add($s), + $inv->subtract($s) + ]; + + $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; + $rhs = $this->p[0]->multiply($this->beta); + $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; + + $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); + ///* + foreach ($this->basis as $basis) { + echo strtoupper($basis['a']->toHex(true)) . "\n"; + echo strtoupper($basis['b']->toHex(true)) . "\n\n"; + } + exit; + //*/ + } + + $npoints = $nscalars = []; + for ($i = 0; $i < count($points); $i++) { + $p = $points[$i]; + $k = $scalars[$i]->toBigInteger(); + + // begin split + list($v1, $v2) = $this->basis; + + $c1 = $v2['b']->multiply($k); + list($c1, $r) = $c1->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c1 = $c1->add($one); + } + + $c2 = $v1['b']->negate()->multiply($k); + list($c2, $r) = $c2->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c2 = $c2->add($one); + } + + $p1 = $c1->multiply($v1['a']); + $p2 = $c2->multiply($v2['a']); + $q1 = $c1->multiply($v1['b']); + $q2 = $c2->multiply($v2['b']); + + $k1 = $k->subtract($p1)->subtract($p2); + $k2 = $q1->add($q2)->negate(); + // end split + + $beta = [ + $p[0]->multiply($this->beta), + $p[1], + clone $this->one + ]; + + if (isset($p['naf'])) { + $beta['naf'] = array_map(function ($p) { + return [ + $p[0]->multiply($this->beta), + $p[1], + clone $this->one + ]; + }, $p['naf']); + $beta['nafwidth'] = $p['nafwidth']; + } + + if ($k1->isNegative()) { + $k1 = $k1->negate(); + $p = $this->negatePoint($p); + } + + if ($k2->isNegative()) { + $k2 = $k2->negate(); + $beta = $this->negatePoint($beta); + } + + $pos = 2 * $i; + $npoints[$pos] = $p; + $nscalars[$pos] = $this->factory->newInteger($k1); + + $pos++; + $npoints[$pos] = $beta; + $nscalars[$pos] = $this->factory->newInteger($k2); + } + + return parent::multiplyAddPoints($npoints, $nscalars); + } + + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0]); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + + /** + * Doubles a jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x1, $y1, $z1) = $p; + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $b->multiply($b); + $d = $x1->add($b); + $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); + $e = $this->three->multiply($a); + $f = $e->multiply($e); + $x3 = $f->subtract($this->two->multiply($d)); + $y3 = $e->multiply($d->subtract($x3))->subtract( + $this->eight->multiply($c) + ); + $z3 = $this->two->multiply($y1)->multiply($z1); + return [$x3, $y3, $z3]; + } + + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x1, $y1) = $p; + $xx = $x1->multiply($x1); + $yy = $y1->multiply($y1); + $yyyy = $yy->multiply($yy); + $s = $x1->add($yy); + $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); + $m = $this->three->multiply($xx); + $t = $m->multiply($m)->subtract($this->two->multiply($s)); + $x3 = $t; + $y3 = $s->subtract($t); + $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); + $z3 = $this->two->multiply($y1); + return [$x3, $y3, $z3]; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($x)->multiply($x); + $rhs = $temp->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Calculates the parameters needed from the Euclidean algorithm as discussed at + * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 + * + * @param BigInteger $u + * @param BigInteger $v + * @return BigInteger[] + */ + protected static function extendedGCD(BigInteger $u, BigInteger $v) + { + $one = new BigInteger(1); + $zero = new BigInteger(); + + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + + $stop = $v->bitwise_rightShift($v->getLength() >> 1); + + $a1 = clone $zero; + $b1 = clone $zero; + $a2 = clone $zero; + $b2 = clone $zero; + + $postGreatestIndex = 0; + + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + + if ($v->compare($stop) > 0) { + $a0 = $v; + $b0 = $c; + } else { + $postGreatestIndex++; + } + + if ($postGreatestIndex == 1) { + $a1 = $v; + $b1 = $c->negate(); + } + + if ($postGreatestIndex == 2) { + $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); + $lhs = $v->multiply($v)->add($b->multiply($b)); + if ($lhs->compare($rhs) <= 0) { + $a2 = $a0; + $b2 = $b0->negate(); + } else { + $a2 = $v; + $b2 = $c->negate(); + } + + break; + } + } + + return [ + ['a' => $a1, 'b' => $b1], + ['a' => $a2, 'b' => $b2] + ]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php new file mode 100644 index 000000000..e3fa50b33 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php @@ -0,0 +1,279 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + a*x + x + * + * @author Jim Wigginton + */ +class Montgomery extends Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeField + */ + protected $factory; + + /** + * Cofficient for x + * + * @var object + */ + protected $a; + + /** + * Constant used for point doubling + * + * @var object + */ + protected $a24; + + /** + * The Number Zero + * + * @var object + */ + protected $zero; + + /** + * The Number One + * + * @var object + */ + protected $one; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->zero = $this->factory->newInteger(new BigInteger()); + $this->one = $this->factory->newInteger(new BigInteger(1)); + } + + /** + * Set coefficients a + */ + public function setCoefficients(BigInteger $a) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $two = $this->factory->newInteger(new BigInteger(2)); + $four = $this->factory->newInteger(new BigInteger(4)); + $this->a24 = $this->a->subtract($two)->divide($four); + } + + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Doubles and adds a point on a curve + * + * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 + * + * @return FiniteField[][] + */ + private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + return []; + } + + if (!isset($p[1])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); + } + + list($x2, $z2) = $p; + list($x3, $z3) = $q; + + $a = $x2->add($z2); + $aa = $a->multiply($a); + $b = $x2->subtract($z2); + $bb = $b->multiply($b); + $e = $aa->subtract($bb); + $c = $x3->add($z3); + $d = $x3->subtract($z3); + $da = $d->multiply($a); + $cb = $c->multiply($b); + $temp = $da->add($cb); + $x5 = $temp->multiply($temp); + $temp = $da->subtract($cb); + $z5 = $x1->multiply($temp->multiply($temp)); + $x4 = $aa->multiply($bb); + $temp = static::class == Curve25519::class ? $bb : $aa; + $z4 = $e->multiply($temp->add($this->a24->multiply($e))); + + return [ + [$x4, $z4], + [$x5, $z5] + ]; + } + + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + $p1 = [$this->one, $this->zero]; + $alreadyInternal = isset($x[1]); + $p2 = $this->convertToInternal($p); + $x = $p[0]; + + $b = $d->toBits(); + $b = str_pad($b, 256, '0', STR_PAD_LEFT); + for ($i = 0; $i < strlen($b); $i++) { + $b_i = (int) $b[$i]; + if ($b_i) { + list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); + } else { + list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); + } + } + + return $alreadyInternal ? $p1 : $this->convertToAffine($p1); + } + + /** + * Converts an affine point to an XZ coordinate + * + * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html + * + * XZ coordinates represent x y as X Z satsfying the following equations: + * + * x=X/Z + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one]; + } + + if (isset($p[1])) { + return $p; + } + + $p[1] = clone $this->one; + + return $p; + } + + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[1])) { + return $p; + } + list($x, $z) = $p; + return [$x->divide($z)]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php new file mode 100644 index 000000000..6250dfb0f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php @@ -0,0 +1,785 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + a*x + b + * + * @author Jim Wigginton + */ +class Prime extends Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeFields + */ + protected $factory; + + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + + /** + * The number three over the specified finite field + * + * @var object + */ + protected $three; + + /** + * The number four over the specified finite field + * + * @var object + */ + protected $four; + + /** + * The number eight over the specified finite field + * + * @var object + */ + protected $eight; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->two = $this->factory->newInteger(new BigInteger(2)); + $this->three = $this->factory->newInteger(new BigInteger(3)); + // used by jacobian coordinates + $this->one = $this->factory->newInteger(new BigInteger(1)); + $this->four = $this->factory->newInteger(new BigInteger(4)); + $this->eight = $this->factory->newInteger(new BigInteger(8)); + } + + /** + * Set coefficients a and b + */ + public function setCoefficients(BigInteger $a, BigInteger $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->b = $this->factory->newInteger($b); + } + + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Adds two "fresh" jacobian form on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedXY(array $p, array $q) + { + list($u1, $s1) = $p; + list($u2, $s2) = $q; + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3) + )->subtract( + $s1->multiply($h3) + ); + return [$x3, $y3, $h]; + } + + /** + * Adds one "fresh" jacobian form on the curve + * + * The second parameter should be the "fresh" one + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedX(array $p, array $q) + { + list($u1, $s1, $z1) = $p; + list($x2, $y2) = $q; + + $z12 = $z1->multiply($z1); + + $u2 = $x2->multiply($z12); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3) + )->subtract( + $s1->multiply($h3) + ); + $z3 = $h->multiply($z1); + return [$x3, $y3, $z3]; + } + + /** + * Adds two jacobian coordinates on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPoint(array $p, array $q) + { + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $z12 = $z1->multiply($z1); + $z22 = $z2->multiply($z2); + + $u1 = $x1->multiply($z22); + $u2 = $x2->multiply($z12); + $s1 = $y1->multiply($z22->multiply($z2)); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3) + )->subtract( + $s1->multiply($h3) + ); + $z3 = $h->multiply($z1)->multiply($z2); + return [$x3, $y3, $z3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + // use jacobian coordinates + if (isset($p[2]) && isset($q[2])) { + if (isset($p['fresh']) && isset($q['fresh'])) { + return $this->jacobianAddPointMixedXY($p, $q); + } + if (isset($p['fresh'])) { + return $this->jacobianAddPointMixedX($q, $p); + } + if (isset($q['fresh'])) { + return $this->jacobianAddPointMixedX($p, $q); + } + return $this->jacobianAddPoint($p, $q); + } + + if (isset($p[2]) || isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + if (!$p[1]->equals($q[1])) { + return []; + } else { // eg. doublePoint + list($numerator, $denominator) = $this->doublePointHelper($p); + } + } else { + $numerator = $q[1]->subtract($p[1]); + $denominator = $q[0]->subtract($p[0]); + } + $slope = $numerator->divide($denominator); + $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + + return [$x, $y]; + } + + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + + /** + * Doubles a jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x, $y, $z) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $z2 = $z->multiply($z); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m2 = $this->a->multiply($z2->multiply($z2)); + $m = $m1->add($m2); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract( + $this->eight->multiply($y2->multiply($y2)) + ); + $z1 = $this->two->multiply($y)->multiply($z); + return [$x1, $y1, $z1]; + } + + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m = $m1->add($this->a); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract( + $this->eight->multiply($y2->multiply($y2)) + ); + $z1 = $this->two->multiply($y); + return [$x1, $y1, $z1]; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + // use jacobian coordinates + if (isset($p[2])) { + if (isset($p['fresh'])) { + return $this->jacobianDoublePointMixed($p); + } + return $this->jacobianDoublePoint($p); + } + + list($numerator, $denominator) = $this->doublePointHelper($p); + + $slope = $numerator->divide($denominator); + + $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + + return [$x, $y]; + } + + /** + * Returns the X coordinate and the derived Y coordinate + * + * @return array + */ + public function derivePoint($m) + { + $y = ord(Strings::shift($m)); + $x = new BigInteger($m, 256); + $xp = $this->convertInteger($x); + switch ($y) { + case 2: + $ypn = false; + break; + case 3: + $ypn = true; + break; + default: + throw new \RuntimeException('Coordinate not in recognized format'); + } + $temp = $xp->multiply($this->a); + $temp = $xp->multiply($xp)->multiply($xp)->add($temp); + $temp = $temp->add($this->b); + $b = $temp->squareRoot(); + if (!$b) { + throw new \RuntimeException('Unable to derive Y coordinate'); + } + $bn = $b->isOdd(); + $yp = $ypn == $bn ? $b : $b->negate(); + return [$xp, $yp]; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($this->a); + $temp = $x->multiply($x)->multiply($x)->add($temp); + $rhs = $temp->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + + /** + * Multiply and Add Points + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L125 + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $length = count($points); + + foreach ($points as &$point) { + $point = $this->convertToInternal($point); + } + + $wnd = [$this->getNAFPoints($points[0], 7)]; + $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; + for ($i = 1; $i < $length; $i++) { + $wnd[] = $this->getNAFPoints($points[$i], 1); + $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; + } + + $naf = []; + + // comb all window NAFs + + $max = 0; + for ($i = $length - 1; $i >= 1; $i -= 2) { + $a = $i - 1; + $b = $i; + if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { + $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); + $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); + $max = max(count($naf[$a]), count($naf[$b]), $max); + continue; + } + + $comb = [ + $points[$a], // 1 + null, // 3 + null, // 5 + $points[$b] // 7 + ]; + + $comb[1] = $this->addPoint($points[$a], $points[$b]); + $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); + + $index = [ + -3, /* -1 -1 */ + -1, /* -1 0 */ + -5, /* -1 1 */ + -7, /* 0 -1 */ + 0, /* 0 -1 */ + 7, /* 0 1 */ + 5, /* 1 -1 */ + 1, /* 1 0 */ + 3 /* 1 1 */ + ]; + + $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); + + $max = max(count($jsf[0]), $max); + if ($max > 0) { + $naf[$a] = array_fill(0, $max, 0); + $naf[$b] = array_fill(0, $max, 0); + } else { + $naf[$a] = []; + $naf[$b] = []; + } + + for ($j = 0; $j < $max; $j++) { + $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; + $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; + + $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; + $naf[$b][$j] = 0; + $wnd[$a] = $comb; + } + } + + $acc = []; + $temp = [0, 0, 0, 0]; + for ($i = $max; $i >= 0; $i--) { + $k = 0; + while ($i >= 0) { + $zero = true; + for ($j = 0; $j < $length; $j++) { + $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; + if ($temp[$j] != 0) { + $zero = false; + } + } + if (!$zero) { + break; + } + $k++; + $i--; + } + + if ($i >= 0) { + $k++; + } + while ($k--) { + $acc = $this->doublePoint($acc); + } + + if ($i < 0) { + break; + } + + for ($j = 0; $j < $length; $j++) { + $z = $temp[$j]; + $p = null; + if ($z == 0) { + continue; + } + $p = $z > 0 ? + $wnd[$j][($z - 1) >> 1] : + $this->negatePoint($wnd[$j][(-$z - 1) >> 1]); + $acc = $this->addPoint($acc, $p); + } + } + + return $this->convertToAffine($acc); + } + + /** + * Precomputes NAF points + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L351 + * + * @return int[] + */ + private function getNAFPoints(array $point, $wnd) + { + if (isset($point['naf'])) { + return $point['naf']; + } + + $res = [$point]; + $max = (1 << $wnd) - 1; + $dbl = $max == 1 ? null : $this->doublePoint($point); + for ($i = 1; $i < $max; $i++) { + $res[] = $this->addPoint($res[$i - 1], $dbl); + } + + $point['naf'] = $res; + + /* + $str = ''; + foreach ($res as $re) { + $re[0] = bin2hex($re[0]->toBytes()); + $re[1] = bin2hex($re[1]->toBytes()); + $str.= " ['$re[0]', '$re[1]'],\r\n"; + } + file_put_contents('temp.txt', $str); + exit; + */ + + return $res; + } + + /** + * Precomputes points in Joint Sparse Form + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/utils.js#L96 + * + * @return int[] + */ + private static function getJSFPoints(Integer $k1, Integer $k2) + { + static $three; + if (!isset($three)) { + $three = new BigInteger(3); + } + + $jsf = [[], []]; + $k1 = $k1->toBigInteger(); + $k2 = $k2->toBigInteger(); + $d1 = 0; + $d2 = 0; + + while ($k1->compare(new BigInteger(-$d1)) > 0 || $k2->compare(new BigInteger(-$d2)) > 0) { + // first phase + $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); + $m14 += $d1; + $m14 &= 3; + + $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); + $m24 += $d2; + $m24 &= 3; + + if ($m14 == 3) { + $m14 = -1; + } + if ($m24 == 3) { + $m24 = -1; + } + + $u1 = 0; + if ($m14 & 1) { // if $m14 is odd + $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); + $m8 += $d1; + $m8 &= 7; + $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; + } + $jsf[0][] = $u1; + + $u2 = 0; + if ($m24 & 1) { // if $m24 is odd + $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); + $m8 += $d2; + $m8 &= 7; + $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; + } + $jsf[1][] = $u2; + + // second phase + if (2 * $d1 == $u1 + 1) { + $d1 = 1 - $d1; + } + if (2 * $d2 == $u2 + 1) { + $d2 = 1 - $d2; + } + $k1 = $k1->bitwise_rightShift(1); + $k2 = $k2->bitwise_rightShift(1); + } + + return $jsf; + } + + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [ + $x->multiply($z2), + $y->multiply($z2)->multiply($z) + ]; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p['fresh'] = true; + return $p; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php new file mode 100644 index 000000000..2521a4c0e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php @@ -0,0 +1,215 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 + * + * @author Jim Wigginton + */ +class TwistedEdwards extends Base +{ + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * Cofficient for x^2 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^2*y^2 + * + * @var object + */ + protected $d; + + /** + * Base Point + * + * @var object[] + */ + protected $p; + + /** + * The number zero over the specified finite field + * + * @var object + */ + protected $zero; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->zero = $this->factory->newInteger(new BigInteger(0)); + $this->one = $this->factory->newInteger(new BigInteger(1)); + $this->two = $this->factory->newInteger(new BigInteger(2)); + } + + /** + * Set coefficients a and b + */ + public function setCoefficients(BigInteger $a, BigInteger $d) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->d = $this->factory->newInteger($d); + } + + /** + * Set x and y coordinates for the base point + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getD() + { + return $this->d; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + return [ + $x->multiply($z), + $y->multiply($z) + ]; + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + + $lhs = $this->a->multiply($x2)->add($y2); + $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); + + return $lhs->equals($rhs); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php new file mode 100644 index 000000000..0f3f4d827 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php @@ -0,0 +1,81 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use phpseclib3\Math\BigInteger; + +class Curve25519 extends Montgomery +{ + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->a24 = $this->factory->newInteger(new BigInteger('121666')); + $this->p = [$this->factory->newInteger(new BigInteger(9))]; + // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed + $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + + /* + $this->setCoefficients( + new BigInteger('486662'), // a + ); + $this->setBasePoint( + new BigInteger(9), + new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') + ); + */ + } + + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + + $d = $d->toBytes(); + $d &= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; + $d = strrev($d); + $d |= "\x40"; + $d = new BigInteger($d, -256); + + return parent::multiplyPoint($p, $d); + } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return BigInteger::random(256); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + if ($x->getLength() > 256 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 256 bytes in length'); + } + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php new file mode 100644 index 000000000..f4a442315 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php @@ -0,0 +1,92 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use phpseclib3\Math\BigInteger; + +class Curve448 extends Montgomery +{ + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + 16 + )); + $this->a24 = $this->factory->newInteger(new BigInteger('39081')); + $this->p = [$this->factory->newInteger(new BigInteger(5))]; + // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d + $this->setOrder(new BigInteger( + '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', + 16 + )); + + /* + $this->setCoefficients( + new BigInteger('156326'), // a + ); + $this->setBasePoint( + new BigInteger(5), + new BigInteger( + '355293926785568175264127502063783334808976399387714271831880898' . + '435169088786967410002932673765864550910142774147268105838985595290' . + '606362') + ); + */ + } + + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + + $d = $d->toBytes(); + $d[0] = $d[0] & "\xFC"; + $d = strrev($d); + $d |= "\x80"; + $d = new BigInteger($d, 256); + + return parent::multiplyPoint($p, $d); + } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return BigInteger::random(446); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + if ($x->getLength() > 448 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 446 bytes in length'); + } + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php new file mode 100644 index 000000000..9d3de684f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php @@ -0,0 +1,333 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Math\BigInteger; + +class Ed25519 extends TwistedEdwards +{ + const HASH = 'sha512'; + /* + Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: + + 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b + bits, and EdDSA signatures have exactly 2*b bits. b is + recommended to be a multiple of 8, so public key and signature + lengths are an integral number of octets. + + SIZE corresponds to b + */ + const SIZE = 32; + + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->setCoefficients( + // -1 + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), // a + // -121665/121666 + new BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) // d + ); + $this->setBasePoint( + new BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), + new BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16) + ); + $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 + /* + $this->setReduction(function($x) { + $parts = $x->bitwise_split(255); + $className = $this->className; + + if (count($parts) > 2) { + list(, $r) = $x->divide($className::$modulo); + return $r; + } + + $zero = new BigInteger(); + $c = new BigInteger(19); + + switch (count($parts)) { + case 2: + list($qi, $ri) = $parts; + break; + case 1: + $qi = $zero; + list($ri) = $parts; + break; + case 0: + return $zero; + } + $r = $ri; + + while ($qi->compare($zero) > 0) { + $temp = $qi->multiply($c)->bitwise_split(255); + if (count($temp) == 2) { + list($qi, $ri) = $temp; + } else { + $qi = $zero; + list($ri) = $temp; + } + $r = $r->add($ri); + } + + while ($r->compare($className::$modulo) > 0) { + $r = $r->subtract($className::$modulo); + } + return $r; + }); + */ + } + + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->add($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + /* we don't do $x2->squareRoot() because, quoting from + https://tools.ietf.org/html/rfc8032#section-5.1.1: + + "For point decoding or "decompression", square roots modulo p are + needed. They can be computed using the Tonelli-Shanks algorithm or + the special case for p = 5 (mod 8). To find a square root of a, + first compute the candidate root x = a^((p+3)/8) (mod p)." + */ + $exp = $this->getModulo()->add(new BigInteger(3)); + $exp = $exp->bitwise_rightShift(3); + $x = $x2->pow($exp); + + // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + $temp = $this->getModulo()->subtract(new BigInteger(1)); + $temp = $temp->bitwise_rightShift(2); + $temp = $this->two->pow($temp); + $x = $x->multiply($temp); + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + + return [$x, $y]; + } + + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 + * + * Used by the various key handlers + * + * @param string $str + * @return array + */ + public function extractSecret($str) + { + if (strlen($str) != 32) { + throw new \LengthException('Private Key should be 32-bytes long'); + } + // 1. Hash the 32-byte private key using SHA-512, storing the digest in + // a 64-octet large buffer, denoted h. Only the lower 32 bytes are + // used for generating the public key. + $hash = new Hash('sha512'); + $h = $hash->hash($str); + $h = substr($h, 0, 32); + // 2. Prune the buffer: The lowest three bits of the first octet are + // cleared, the highest bit of the last octet is cleared, and the + // second highest bit of the last octet is set. + $h[0] = $h[0] & chr(0xF8); + $h = strrev($h); + $h[0] = ($h[0] & chr(0x3F)) | chr(0x40); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new BigInteger($h, 256); + + return [ + 'dA' => $dA, + 'secret' => $str + ]; + } + + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = $y->toBytes(); + $y[0] = $y[0] & chr(0x7F); + if ($x->isOdd()) { + $y[0] = $y[0] | chr(0x80); + } + $y = strrev($y); + + return $y; + } + + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(Random::string(32))['dA']; + } + + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; + } + + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p[3] = $p[0]->multiply($p[1]); + + return $p; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // from https://tools.ietf.org/html/rfc8032#page-12 + + list($x1, $y1, $z1, $t1) = $p; + + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $this->two->multiply($z1)->multiply($z1); + $h = $a->add($b); + $temp = $x1->add($y1); + $e = $h->subtract($temp->multiply($temp)); + $g = $a->subtract($b); + $f = $c->add($g); + + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3, $t3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // from https://tools.ietf.org/html/rfc8032#page-12 + + list($x1, $y1, $z1, $t1) = $p; + list($x2, $y2, $z2, $t2) = $q; + + $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); + $b = $y1->add($x1)->multiply($y2->add($x2)); + $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); + $d = $z1->multiply($this->two)->multiply($z2); + $e = $b->subtract($a); + $f = $d->subtract($c); + $g = $d->add($c); + $h = $b->add($a); + + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3, $t3]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php new file mode 100644 index 000000000..5451f909f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php @@ -0,0 +1,273 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Math\BigInteger; + +class Ed448 extends TwistedEdwards +{ + const HASH = 'shake256-912'; + const SIZE = 57; + + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + 16 + )); + $this->setCoefficients( + new BigInteger(1), + // -39081 + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) + ); + $this->setBasePoint( + new BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . + 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), + new BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . + '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16) + ); + $this->setOrder(new BigInteger( + '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', + 16 + )); + } + + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->subtract($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + $exp = $this->getModulo()->add(new BigInteger(1)); + $exp = $exp->bitwise_rightShift(2); + $x = $x2->pow($exp); + + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + + return [$x, $y]; + } + + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 + * + * Used by the various key handlers + * + * @param string $str + * @return array + */ + public function extractSecret($str) + { + if (strlen($str) != 57) { + throw new \LengthException('Private Key should be 57-bytes long'); + } + // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the + // digest in a 114-octet large buffer, denoted h. Only the lower 57 + // bytes are used for generating the public key. + $hash = new Hash('shake256-912'); + $h = $hash->hash($str); + $h = substr($h, 0, 57); + // 2. Prune the buffer: The two least significant bits of the first + // octet are cleared, all eight bits the last octet are cleared, and + // the highest bit of the second to last octet is set. + $h[0] = $h[0] & chr(0xFC); + $h = strrev($h); + $h[0] = "\0"; + $h[1] = $h[1] | chr(0x80); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new BigInteger($h, 256); + + return [ + 'dA' => $dA, + 'secret' => $str + ]; + + $dA->secret = $str; + return $dA; + } + + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = "\0" . $y->toBytes(); + if ($x->isOdd()) { + $y[0] = $y[0] | chr(0x80); + } + $y = strrev($y); + + return $y; + } + + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(Random::string(57))['dA']; + } + + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one]; + } + + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + + return $p; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // from https://tools.ietf.org/html/rfc8032#page-18 + + list($x1, $y1, $z1) = $p; + + $b = $x1->add($y1); + $b = $b->multiply($b); + $c = $x1->multiply($x1); + $d = $y1->multiply($y1); + $e = $c->add($d); + $h = $z1->multiply($z1); + $j = $e->subtract($this->two->multiply($h)); + + $x3 = $b->subtract($e)->multiply($j); + $y3 = $c->subtract($d)->multiply($e); + $z3 = $e->multiply($j); + + return [$x3, $y3, $z3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // from https://tools.ietf.org/html/rfc8032#page-17 + + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $a = $z1->multiply($z2); + $b = $a->multiply($a); + $c = $x1->multiply($x2); + $d = $y1->multiply($y2); + $e = $this->d->multiply($c)->multiply($d); + $f = $b->subtract($e); + $g = $b->add($e); + $h = $x1->add($y1)->multiply($x2->add($y2)); + + $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); + $y3 = $a->multiply($g)->multiply($d->subtract($c)); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php new file mode 100644 index 000000000..7bc2272a1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP160r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), + new BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16) + ); + $this->setBasePoint( + new BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), + new BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16) + ); + $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php new file mode 100644 index 000000000..ebfb29aeb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php @@ -0,0 +1,47 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP160t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), // eg. -3 + new BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) + ); + $this->setBasePoint( + new BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), + new BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16) + ); + $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php new file mode 100644 index 000000000..6ec848bc9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP192r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), + new BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16) + ); + $this->setBasePoint( + new BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), + new BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16) + ); + $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php new file mode 100644 index 000000000..e6a86bbd3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP192t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), // eg. -3 + new BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) + ); + $this->setBasePoint( + new BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), + new BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16) + ); + $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php new file mode 100644 index 000000000..3d7d8726a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP224r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), + new BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16) + ); + $this->setBasePoint( + new BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), + new BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16) + ); + $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php new file mode 100644 index 000000000..3d4f9289c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP224t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), // eg. -3 + new BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) + ); + $this->setBasePoint( + new BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), + new BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16) + ); + $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php new file mode 100644 index 000000000..5780da763 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP256r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), + new BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16) + ); + $this->setBasePoint( + new BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), + new BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16) + ); + $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php new file mode 100644 index 000000000..724d8b8f1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP256t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), // eg. -3 + new BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) + ); + $this->setBasePoint( + new BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), + new BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16) + ); + $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php new file mode 100644 index 000000000..182e62270 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP320r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . + '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . + '92F375A97D860EB4', 16), + new BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . + '6F5EB4AC8FB1F1A6', 16) + ); + $this->setBasePoint( + new BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . + '10AF8D0D39E20611', 16), + new BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . + 'D35245D1692E8EE1', 16) + ); + $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . + '82EC7EE8658E98691555B44C59311', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php new file mode 100644 index 000000000..d5a620d8b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP320t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . + '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . + 'FCD412B1F1B32E24', 16), // eg. -3 + new BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . + 'B5B4FEF422340353', 16) + ); + $this->setBasePoint( + new BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . + '3357F624A21BED52', 16), + new BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . + '1B9BC0455FB0D2C3', 16) + ); + $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . + '82EC7EE8658E98691555B44C59311', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php new file mode 100644 index 000000000..a20b4b446 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP384r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . + '1874700133107EC53', + 16 + )); + $this->setCoefficients( + new BigInteger( + '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . + 'AD4EB04A8C7DD22CE2826', + 16 + ), + new BigInteger( + '4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . + 'C9943AB78696FA504C11', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . + '646AAEF87B2E247D4AF1E', + 16 + ), + new BigInteger( + '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . + '1811142820341263C5315', + 16 + ) + ); + $this->setOrder(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . + '03B883202E9046565', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php new file mode 100644 index 000000000..366660e68 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP384t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . + '1874700133107EC53', + 16 + )); + $this->setCoefficients( + new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . + 'D1A71874700133107EC50', + 16 + ), // eg. -3 + new BigInteger( + '7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . + '8805CED70355A33B471EE', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . + 'A5F54D8D0AA2F418808CC', + 16 + ), + new BigInteger( + '25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . + '2B2912675BF5B9E582928', + 16 + ) + ); + $this->setOrder(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . + '03B883202E9046565', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php new file mode 100644 index 000000000..5efe5e1ac --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP512r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', + 16 + )); + $this->setCoefficients( + new BigInteger( + '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . + '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', + 16 + ), + new BigInteger( + '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . + '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . + '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', + 16 + ), + new BigInteger( + '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . + 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . + '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php new file mode 100644 index 000000000..745863a63 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP512t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', + 16 + )); + $this->setCoefficients( + new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', + 16 + ), // eg. -3 + new BigInteger( + '7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . + '76540F6450085F2DAE145C22553B465763689180EA2571867423E', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . + 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', + 16 + ), + new BigInteger( + '5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . + 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . + '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php new file mode 100644 index 000000000..bae12b06f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistb233 extends sect233r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php new file mode 100644 index 000000000..a46153d3c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistb409 extends sect409r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php new file mode 100644 index 000000000..8b2637617 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk163 extends sect163k1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php new file mode 100644 index 000000000..69e141382 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk233 extends sect233k1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php new file mode 100644 index 000000000..9e95f10e7 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk283 extends sect283k1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php new file mode 100644 index 000000000..06bd9af76 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk409 extends sect409k1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php new file mode 100644 index 000000000..ddead3cff --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp192 extends secp192r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php new file mode 100644 index 000000000..746571b4d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp224 extends secp224r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php new file mode 100644 index 000000000..a26c0f992 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp256 extends secp256r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php new file mode 100644 index 000000000..1f20c02d1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp384 extends secp384r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php new file mode 100644 index 000000000..86fa05084 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp521 extends secp521r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php new file mode 100644 index 000000000..7908b38b9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistt571 extends sect571k1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php new file mode 100644 index 000000000..e9c13cd8c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class prime192v1 extends secp192r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php new file mode 100644 index 000000000..e3e341f26 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime192v2 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16) + ); + $this->setBasePoint( + new BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), + new BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php new file mode 100644 index 000000000..1e97992dc --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime192v3 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16) + ); + $this->setBasePoint( + new BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), + new BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php new file mode 100644 index 000000000..084be9d7c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16) + ); + $this->setBasePoint( + new BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), + new BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php new file mode 100644 index 000000000..21941b834 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v2 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16) + ); + $this->setBasePoint( + new BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), + new BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php new file mode 100644 index 000000000..78c50f069 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v3 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16) + ); + $this->setBasePoint( + new BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), + new BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php new file mode 100644 index 000000000..c72b22e8a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class prime256v1 extends secp256r1 +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php new file mode 100644 index 000000000..d1d3194b2 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp112r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients( + new BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), + new BigInteger('659EF8BA043916EEDE8911702B22', 16) + ); + $this->setBasePoint( + new BigInteger('09487239995A5EE76B55F9C2F098', 16), + new BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16) + ); + $this->setOrder(new BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php new file mode 100644 index 000000000..da44e7fd8 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php @@ -0,0 +1,35 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp112r2 extends Prime +{ + public function __construct() + { + // same modulo as secp112r1 + $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients( + new BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), + new BigInteger('51DEF1815DB5ED74FCC34C85D709', 16) + ); + $this->setBasePoint( + new BigInteger('4BA30AB5E892B4E1649DD0928643', 16), + new BigInteger('ADCD46F5882E3747DEF36E956E97', 16) + ); + $this->setOrder(new BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php new file mode 100644 index 000000000..34456bc07 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp128r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), + new BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16) + ); + $this->setBasePoint( + new BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), + new BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php new file mode 100644 index 000000000..e102c3409 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php @@ -0,0 +1,35 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp128r2 extends Prime +{ + public function __construct() + { + // same as secp128r1 + $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), + new BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16) + ); + $this->setBasePoint( + new BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), + new BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16) + ); + $this->setOrder(new BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php new file mode 100644 index 000000000..c6a33344a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php @@ -0,0 +1,46 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp160k1 extends KoblitzPrime +{ + public function __construct() + { + // same as secp160r2 + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients( + new BigInteger('0000000000000000000000000000000000000000', 16), + new BigInteger('0000000000000000000000000000000000000007', 16) + ); + $this->setBasePoint( + new BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), + new BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('0096341F1138933BC2F505', -16), + 'b' => new BigInteger('FF6E9D0418C67BB8D5F562', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01BDCB3A09AAAABEAFF4A8', -16), + 'b' => new BigInteger('04D12329FF0EF498EA67', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php new file mode 100644 index 000000000..af4687749 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp160r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), + new BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16) + ); + $this->setBasePoint( + new BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), + new BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php new file mode 100644 index 000000000..9bd23d23c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php @@ -0,0 +1,35 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp160r2 extends Prime +{ + public function __construct() + { + // same as secp160k1 + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), + new BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16) + ); + $this->setBasePoint( + new BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), + new BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php new file mode 100644 index 000000000..79ff2e097 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php @@ -0,0 +1,45 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp192k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); + $this->setCoefficients( + new BigInteger('000000000000000000000000000000000000000000000000', 16), + new BigInteger('000000000000000000000000000000000000000000000003', 16) + ); + $this->setBasePoint( + new BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), + new BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), + 'b' => new BigInteger('8EE96418CCF4CFC7124FDA0F', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01D90D03E8F096B9948B20F0A9', -16), + 'b' => new BigInteger('42E49819ABBA9474E1083F6B', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php new file mode 100644 index 000000000..83ab1c706 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php @@ -0,0 +1,78 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp192r1 extends Prime +{ + public function __construct() + { + $modulo = new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); + $this->setModulo($modulo); + + // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 + /* in theory this should be faster than regular modular reductions save for one small issue. + to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. + to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. + in short, converting to / from base-2**8 is pretty expensive and that expense is + enough to offset whatever else might be gained by a simplified reduction algorithm. + now, if PHP supported unsigned integers things might be different. no bit-shifting + would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger + uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit + or a 64-bit OS. + */ + /* + $m_length = $this->getLengthInBytes(); + $this->setReduction(function($c) use ($m_length) { + $cBytes = $c->toBytes(); + $className = $this->className; + + if (strlen($cBytes) > 2 * $m_length) { + list(, $r) = $c->divide($className::$modulo); + return $r; + } + + $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); + $c = array_reverse(str_split($c, 8)); + + $null = "\0\0\0\0\0\0\0\0"; + $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); + $s2 = new BigInteger($null . $c[3] . $c[3], 256); + $s3 = new BigInteger($c[4] . $c[4] . $null, 256); + $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); + + $r = $s1->add($s2)->add($s3)->add($s4); + while ($r->compare($className::$modulo) >= 0) { + $r = $r->subtract($className::$modulo); + } + + return $r; + }); + */ + + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16) + ); + $this->setBasePoint( + new BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), + new BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php new file mode 100644 index 000000000..79a5c5417 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php @@ -0,0 +1,45 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp224k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); + $this->setCoefficients( + new BigInteger('00000000000000000000000000000000000000000000000000000000', 16), + new BigInteger('00000000000000000000000000000000000000000000000000000005', 16) + ); + $this->setBasePoint( + new BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), + new BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16) + ); + $this->setOrder(new BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), + 'b' => new BigInteger('94730F82B358A3776A826298FA6F', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), + 'b' => new BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php new file mode 100644 index 000000000..a9e474a3c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp224r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), + new BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16) + ); + $this->setBasePoint( + new BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), + new BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php new file mode 100644 index 000000000..462e7a1ca --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php @@ -0,0 +1,49 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +//use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +//class secp256k1 extends Prime +class secp256k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); + $this->setCoefficients( + new BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), + new BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); + $this->setBasePoint( + new BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), + new BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16) + ); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), + 'b' => new BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), + 'b' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php new file mode 100644 index 000000000..9003373cf --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp256r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), + new BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16) + ); + $this->setBasePoint( + new BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), + new BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php new file mode 100644 index 000000000..98764a341 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php @@ -0,0 +1,52 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp384r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', + 16 + )); + $this->setCoefficients( + new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', + 16 + ), + new BigInteger( + 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', + 16 + ), + new BigInteger( + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php new file mode 100644 index 000000000..b89a4ea74 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php @@ -0,0 +1,46 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp521r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFF', 16)); + $this->setCoefficients( + new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFC', 16), + new BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . + '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . + '3F00', 16) + ); + $this->setBasePoint( + new BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . + '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . + 'BD66', 16), + new BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . + '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . + '6650', 16) + ); + $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . + '6409', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php new file mode 100644 index 000000000..77ec7603a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect113r1 extends Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients( + '003088250CA6E7C7FE649CE85820F7', + '00E8BEE4D3E2260744188BE0E9C723' + ); + $this->setBasePoint( + '009D73616F35F4AB1407D73562C10F', + '00A52830277958EE84D1315ED31886' + ); + $this->setOrder(new BigInteger('0100000000000000D9CCEC8A39E56F', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php new file mode 100644 index 000000000..2185d60e3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect113r2 extends Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients( + '00689918DBEC7E5A0DD6DFC0AA55C7', + '0095E9A9EC9B297BD4BF36E059184F' + ); + $this->setBasePoint( + '01A57A6A7B26CA5EF52FCDB8164797', + '00B3ADC94ED1FE674C06E695BABA1D' + ); + $this->setOrder(new BigInteger('010000000000000108789B2496AF93', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php new file mode 100644 index 000000000..1365cb601 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect131r1 extends Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients( + '07A11B09A76B562144418FF3FF8C2570B8', + '0217C05610884B63B9C6C7291678F9D341' + ); + $this->setBasePoint( + '0081BAF91FDF9833C40F9C181343638399', + '078C6E7EA38C001F73C8134B1B4EF9E150' + ); + $this->setOrder(new BigInteger('0400000000000000023123953A9464B54D', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php new file mode 100644 index 000000000..93c11b2a3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect131r2 extends Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients( + '03E5A88919D7CAFCBF415F07C2176573B2', + '04B8266A46C55657AC734CE38F018F2192' + ); + $this->setBasePoint( + '0356DCD8F2F95031AD652D23951BB366A8', + '0648F06D867940A5366D9E265DE9EB240F' + ); + $this->setOrder(new BigInteger('0400000000000000016954A233049BA98F', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php new file mode 100644 index 000000000..3c8574bb3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163k1 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000001', + '000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', + '0289070FB05D38FF58321F2E800536D538CCDAA3D9' + ); + $this->setOrder(new BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php new file mode 100644 index 000000000..26afd87e4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163r1 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', + '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9' + ); + $this->setBasePoint( + '0369979697AB43897789566789567F787A7876A654', + '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883' + ); + $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php new file mode 100644 index 000000000..38f94661c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163r2 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000001', + '020A601907B8C953CA1481EB10512F78744A3205FD' + ); + $this->setBasePoint( + '03F0EBA16286A2D57EA0991168D4994637E8343E36', + '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1' + ); + $this->setOrder(new BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php new file mode 100644 index 000000000..951f261eb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect193r1 extends Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients( + '0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', + '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814' + ); + $this->setBasePoint( + '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', + '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05' + ); + $this->setOrder(new BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php new file mode 100644 index 000000000..e3ff47ac7 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect193r2 extends Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients( + '0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', + '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE' + ); + $this->setBasePoint( + '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', + '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C' + ); + $this->setOrder(new BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php new file mode 100644 index 000000000..eea3f7ad5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect233k1 extends Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', + '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3' + ); + $this->setOrder(new BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php new file mode 100644 index 000000000..68219f0ea --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect233r1 extends Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000001', + '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD' + ); + $this->setBasePoint( + '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', + '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052' + ); + $this->setOrder(new BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php new file mode 100644 index 000000000..0e6994ba3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect239k1 extends Binary +{ + public function __construct() + { + $this->setModulo(239, 158, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', + '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA' + ); + $this->setOrder(new BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php new file mode 100644 index 000000000..279c24aac --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect283k1 extends Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', + '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259' + ); + $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php new file mode 100644 index 000000000..e44a60765 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect283r1 extends Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000001', + '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5' + ); + $this->setBasePoint( + '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', + '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4' + ); + $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php new file mode 100644 index 000000000..1fe329d8c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php @@ -0,0 +1,38 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect409k1 extends Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients( + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', + '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B' + ); + $this->setOrder(new BigInteger( + '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . + '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php new file mode 100644 index 000000000..3e209ef8f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php @@ -0,0 +1,38 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect409r1 extends Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients( + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', + '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F' + ); + $this->setBasePoint( + '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', + '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706' + ); + $this->setOrder(new BigInteger( + '010000000000000000000000000000000000000000000000000001E2' . + 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php new file mode 100644 index 000000000..3c54eabdb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect571k1 extends Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . + '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', + '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . + 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3' + ); + $this->setOrder(new BigInteger( + '020000000000000000000000000000000000000000000000000000000000000000000000' . + '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php new file mode 100644 index 000000000..172c1af9c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect571r1 extends Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000001', + '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . + '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A' + ); + $this->setBasePoint( + '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . + 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', + '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . + 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B' + ); + $this->setOrder(new BigInteger( + '03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', + 16 + )); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php new file mode 100644 index 000000000..63402b4a8 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php @@ -0,0 +1,549 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; +use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * Generic EC Key Parsing Helper functions + * + * @author Jim Wigginton + */ +trait Common +{ + /** + * Curve OIDs + * + * @var array + */ + private static $curveOIDs = []; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Use Named Curves + * + * @var bool + */ + private static $useNamedCurves = true; + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (empty(self::$curveOIDs)) { + // the sec* curves are from the standards for efficient cryptography group + // sect* curves are curves over binary finite fields + // secp* curves are curves over prime finite fields + // sec*r* curves are regular curves; sec*k* curves are koblitz curves + // brainpool*r* curves are regular prime finite field curves + // brainpool*t* curves are twisted versions of the brainpool*r* curves + self::$curveOIDs = [ + 'prime192v1' => '1.2.840.10045.3.1.1', // J.5.1, example 1 (aka secp192r1) + 'prime192v2' => '1.2.840.10045.3.1.2', // J.5.1, example 2 + 'prime192v3' => '1.2.840.10045.3.1.3', // J.5.1, example 3 + 'prime239v1' => '1.2.840.10045.3.1.4', // J.5.2, example 1 + 'prime239v2' => '1.2.840.10045.3.1.5', // J.5.2, example 2 + 'prime239v3' => '1.2.840.10045.3.1.6', // J.5.2, example 3 + 'prime256v1' => '1.2.840.10045.3.1.7', // J.5.3, example 1 (aka secp256r1) + + // https://tools.ietf.org/html/rfc5656#section-10 + 'nistp256' => '1.2.840.10045.3.1.7', // aka secp256r1 + 'nistp384' => '1.3.132.0.34', // aka secp384r1 + 'nistp521' => '1.3.132.0.35', // aka secp521r1 + + 'nistk163' => '1.3.132.0.1', // aka sect163k1 + 'nistp192' => '1.2.840.10045.3.1.1', // aka secp192r1 + 'nistp224' => '1.3.132.0.33', // aka secp224r1 + 'nistk233' => '1.3.132.0.26', // aka sect233k1 + 'nistb233' => '1.3.132.0.27', // aka sect233r1 + 'nistk283' => '1.3.132.0.16', // aka sect283k1 + 'nistk409' => '1.3.132.0.36', // aka sect409k1 + 'nistb409' => '1.3.132.0.37', // aka sect409r1 + 'nistt571' => '1.3.132.0.38', // aka sect571k1 + + // from https://tools.ietf.org/html/rfc5915 + 'secp192r1' => '1.2.840.10045.3.1.1', // aka prime192v1 + 'sect163k1' => '1.3.132.0.1', + 'sect163r2' => '1.3.132.0.15', + 'secp224r1' => '1.3.132.0.33', + 'sect233k1' => '1.3.132.0.26', + 'sect233r1' => '1.3.132.0.27', + 'secp256r1' => '1.2.840.10045.3.1.7', // aka prime256v1 + 'sect283k1' => '1.3.132.0.16', + 'sect283r1' => '1.3.132.0.17', + 'secp384r1' => '1.3.132.0.34', + 'sect409k1' => '1.3.132.0.36', + 'sect409r1' => '1.3.132.0.37', + 'secp521r1' => '1.3.132.0.35', + 'sect571k1' => '1.3.132.0.38', + 'sect571r1' => '1.3.132.0.39', + // from http://www.secg.org/SEC2-Ver-1.0.pdf + 'secp112r1' => '1.3.132.0.6', + 'secp112r2' => '1.3.132.0.7', + 'secp128r1' => '1.3.132.0.28', + 'secp128r2' => '1.3.132.0.29', + 'secp160k1' => '1.3.132.0.9', + 'secp160r1' => '1.3.132.0.8', + 'secp160r2' => '1.3.132.0.30', + 'secp192k1' => '1.3.132.0.31', + 'secp224k1' => '1.3.132.0.32', + 'secp256k1' => '1.3.132.0.10', + + 'sect113r1' => '1.3.132.0.4', + 'sect113r2' => '1.3.132.0.5', + 'sect131r1' => '1.3.132.0.22', + 'sect131r2' => '1.3.132.0.23', + 'sect163r1' => '1.3.132.0.2', + 'sect193r1' => '1.3.132.0.24', + 'sect193r2' => '1.3.132.0.25', + 'sect239k1' => '1.3.132.0.3', + + // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 + /* + 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 + 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 + 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 + 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 + 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 + 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 + 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 + 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 + 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 + 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 + 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 + 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 + 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 + 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 + 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 + 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 + 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 + 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 + 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 + 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 + */ + + // http://www.ecc-brainpool.org/download/Domain-parameters.pdf + // https://tools.ietf.org/html/rfc5639 + 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', + 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', + 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', + 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', + 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', + 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', + 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', + 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', + 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', + 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', + 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', + 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', + 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', + 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14' + ]; + ASN1::loadOIDs([ + 'prime-field' => '1.2.840.10045.1.1', + 'characteristic-two-field' => '1.2.840.10045.1.2', + 'characteristic-two-basis' => '1.2.840.10045.1.2.3', + // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" + 'gnBasis' => '1.2.840.10045.1.2.3.1', // NULL + 'tpBasis' => '1.2.840.10045.1.2.3.2', // Trinomial + 'ppBasis' => '1.2.840.10045.1.2.3.3' // Pentanomial + ] + self::$curveOIDs); + } + } + + /** + * Explicitly set the curve + * + * If the key contains an implicit curve phpseclib needs the curve + * to be explicitly provided + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + */ + public static function setImplicitCurve(BaseCurve $curve) + { + self::$implicitCurve = $curve; + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param array $params + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + protected static function loadCurveByParam(array $params) + { + if (count($params) > 1) { + throw new \RuntimeException('No parameters are present'); + } + if (isset($params['namedCurve'])) { + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); + } + return new $curve(); + } + if (isset($params['implicitCurve'])) { + if (!isset(self::$implicitCurve)) { + throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); + } + return self::$implicitCurve; + } + if (isset($params['specifiedCurve'])) { + $data = $params['specifiedCurve']; + switch ($data['fieldID']['fieldType']) { + case 'prime-field': + $curve = new PrimeCurve(); + $curve->setModulo($data['fieldID']['parameters']); + $curve->setCoefficients( + new BigInteger($data['curve']['a'], 256), + new BigInteger($data['curve']['b'], 256) + ); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + case 'characteristic-two-field': + $curve = new BinaryCurve(); + $params = ASN1::decodeBER($data['fieldID']['parameters']); + $params = ASN1::asn1map($params[0], Maps\Characteristic_two::MAP); + $modulo = [(int) $params['m']->toString()]; + switch ($params['basis']) { + case 'tpBasis': + $modulo[] = (int) $params['parameters']->toString(); + break; + case 'ppBasis': + $temp = ASN1::decodeBER($params['parameters']); + $temp = ASN1::asn1map($temp[0], Maps\Pentanomial::MAP); + $modulo[] = (int) $temp['k3']->toString(); + $modulo[] = (int) $temp['k2']->toString(); + $modulo[] = (int) $temp['k1']->toString(); + } + $modulo[] = 0; + $curve->setModulo(...$modulo); + $len = ceil($modulo[0] / 8); + $curve->setCoefficients( + Strings::bin2hex($data['curve']['a']), + Strings::bin2hex($data['curve']['b']) + ); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + default: + throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); + } + } + throw new \RuntimeException('No valid parameters are present'); + } + + /** + * Extract points from a string + * + * Supports both compressed and uncompressed points + * + * @param string $str + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + public static function extractPoint($str, BaseCurve $curve) + { + if ($curve instanceof TwistedEdwardsCurve) { + // first step of point deciding as discussed at the following URL's: + // https://tools.ietf.org/html/rfc8032#section-5.1.3 + // https://tools.ietf.org/html/rfc8032#section-5.2.3 + $y = $str; + $y = strrev($y); + $sign = (bool) (ord($y[0]) & 0x80); + $y[0] = $y[0] & chr(0x7F); + $y = new BigInteger($y, 256); + if ($y->compare($curve->getModulo()) >= 0) { + throw new \RuntimeException('The Y coordinate should not be >= the modulo'); + } + $point = $curve->recoverX($y, $sign); + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + + // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, + // currently, bit strings wanting a non-zero amount of bits trimmed are not supported + if (($val = Strings::shift($str)) != "\0") { + throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Strings::bin2hex($val)); + } + if ($str == "\0") { + return []; + } + + $keylen = strlen($str); + $order = $curve->getLengthInBytes(); + // point compression is being used + if ($keylen == $order + 1) { + return $curve->derivePoint($str); + } + + // point compression is not being used + if ($keylen == 2 * $order + 1) { + preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); + list(, $w, $x, $y) = $matches; + if ($w != "\4") { + throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Strings::bin2hex($val)); + } + $point = [ + $curve->convertInteger(new BigInteger($x, 256)), + $curve->convertInteger(new BigInteger($y, 256)) + ]; + + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + + return $point; + } + + throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); + } + + /** + * Encode Parameters + * + * @todo Maybe at some point this could be moved to __toString() for each of the curves? + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param bool $returnArray optional + * @param array $options optional + * @return string|false + */ + private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = []) + { + $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; + + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + if ($useNamedCurves) { + if (isset(self::$curveOIDs[$name])) { + if ($reflect->isFinal()) { + $reflect = $reflect->getParentClass(); + $name = $reflect->getShortName(); + } + return $returnArray ? + ['namedCurve' => $name] : + ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP); + } + foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $testName = $file->getBasename('.php'); + $class = 'phpseclib3\Crypt\EC\Curves\\' . $testName; + $reflect = new \ReflectionClass($class); + if ($reflect->isFinal()) { + continue; + } + $candidate = new $class(); + switch ($name) { + case 'Prime': + if (!$candidate instanceof PrimeCurve) { + break; + } + if (!$candidate->getModulo()->equals($curve->getModulo())) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + + return $returnArray ? + ['namedCurve' => $testName] : + ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); + case 'Binary': + if (!$candidate instanceof BinaryCurve) { + break; + } + if ($candidate->getModulo() != $curve->getModulo()) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + + return $returnArray ? + ['namedCurve' => $testName] : + ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); + } + } + } + + $order = $curve->getOrder(); + // we could try to calculate the order thusly: + // https://crypto.stackexchange.com/a/27914/4520 + // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm + if (!$order) { + throw new \RuntimeException('Specified Curves need the order to be specified'); + } + $point = $curve->getBasePoint(); + $x = $point[0]->toBytes(); + $y = $point[1]->toBytes(); + + if ($curve instanceof PrimeCurve) { + /* + * valid versions are: + * + * ecdpVer1: + * - neither the curve or the base point are generated verifiably randomly. + * ecdpVer2: + * - curve and base point are generated verifiably at random and curve.seed is present + * ecdpVer3: + * - base point is generated verifiably at random but curve is not. curve.seed is present + */ + // other (optional) parameters can be calculated using the methods discused at + // https://crypto.stackexchange.com/q/28947/4520 + $data = [ + 'version' => 'ecdpVer1', + 'fieldID' => [ + 'fieldType' => 'prime-field', + 'parameters' => $curve->getModulo() + ], + 'curve' => [ + 'a' => $curve->getA()->toBytes(), + 'b' => $curve->getB()->toBytes() + ], + 'base' => "\4" . $x . $y, + 'order' => $order + ]; + + return $returnArray ? + ['specifiedCurve' => $data] : + ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); + } + if ($curve instanceof BinaryCurve) { + $modulo = $curve->getModulo(); + $basis = count($modulo); + $m = array_shift($modulo); + array_pop($modulo); // the last parameter should always be 0 + //rsort($modulo); + switch ($basis) { + case 3: + $basis = 'tpBasis'; + $modulo = new BigInteger($modulo[0]); + break; + case 5: + $basis = 'ppBasis'; + // these should be in strictly ascending order (hence the commented out rsort above) + $modulo = [ + 'k1' => new BigInteger($modulo[2]), + 'k2' => new BigInteger($modulo[1]), + 'k3' => new BigInteger($modulo[0]) + ]; + $modulo = ASN1::encodeDER($modulo, Maps\Pentanomial::MAP); + $modulo = new ASN1\Element($modulo); + } + $params = ASN1::encodeDER([ + 'm' => new BigInteger($m), + 'basis' => $basis, + 'parameters' => $modulo + ], Maps\Characteristic_two::MAP); + $params = new ASN1\Element($params); + $a = ltrim($curve->getA()->toBytes(), "\0"); + if (!strlen($a)) { + $a = "\0"; + } + $b = ltrim($curve->getB()->toBytes(), "\0"); + if (!strlen($b)) { + $b = "\0"; + } + $data = [ + 'version' => 'ecdpVer1', + 'fieldID' => [ + 'fieldType' => 'characteristic-two-field', + 'parameters' => $params + ], + 'curve' => [ + 'a' => $a, + 'b' => $b + ], + 'base' => "\4" . $x . $y, + 'order' => $order + ]; + + return $returnArray ? + ['specifiedCurve' => $data] : + ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); + } + + throw new UnsupportedCurveException('Curve cannot be serialized'); + } + + /** + * Use Specified Curve + * + * A specified curve has all the coefficients, the base points, etc, explicitely included. + * A specified curve is a more verbose way of representing a curve + */ + public static function useSpecifiedCurve() + { + self::$useNamedCurves = false; + } + + /** + * Use Named Curve + * + * A named curve does not include any parameters. It is up to the EC parameters to + * know what the coefficients, the base points, etc, are from the name of the curve. + * A named curve is a more concise way of representing a curve + */ + public static function useNamedCurve() + { + self::$useNamedCurves = true; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php new file mode 100644 index 000000000..fd18a9815 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php @@ -0,0 +1,189 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\secp256k1; +use phpseclib3\Crypt\EC\Curves\secp256r1; +use phpseclib3\Crypt\EC\Curves\secp384r1; +use phpseclib3\Crypt\EC\Curves\secp521r1; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; + +/** + * JWK Formatted EC Handler + * + * @author Jim Wigginton + */ +abstract class JWK extends Progenitor +{ + use Common; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + switch ($key->kty) { + case 'EC': + switch ($key->crv) { + case 'P-256': + case 'P-384': + case 'P-521': + case 'secp256k1': + break; + default: + throw new UnsupportedCurveException('Only P-256, P-384, P-521 and secp256k1 curves are accepted (' . $key->crv . ' provided)'); + } + break; + case 'OKP': + switch ($key->crv) { + case 'Ed25519': + case 'Ed448': + break; + default: + throw new UnsupportedCurveException('Only Ed25519 and Ed448 curves are accepted (' . $key->crv . ' provided)'); + } + break; + default: + throw new \Exception('Only EC and OKP JWK keys are supported'); + } + + $curve = '\phpseclib3\Crypt\EC\Curves\\' . str_replace('P-', 'nistp', $key->crv); + $curve = new $curve(); + + if ($curve instanceof TwistedEdwardsCurve) { + $QA = self::extractPoint(Strings::base64url_decode($key->x), $curve); + if (!isset($key->d)) { + return compact('curve', 'QA'); + } + $arr = $curve->extractSecret(Strings::base64url_decode($key->d)); + return compact('curve', 'QA') + $arr; + } + + $QA = [ + $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->x), 256)), + $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->y), 256)) + ]; + + if (!$curve->verifyPoint($QA)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + + if (!isset($key->d)) { + return compact('curve', 'QA'); + } + + $dA = new BigInteger(Strings::base64url_decode($key->d), 256); + + $curve->rangeCheck($dA); + + return compact('curve', 'dA', 'QA'); + } + + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(BaseCurve $curve) + { + switch (true) { + case $curve instanceof secp256r1: + return 'P-256'; + case $curve instanceof secp384r1: + return 'P-384'; + case $curve instanceof secp521r1: + return 'P-521'; + case $curve instanceof secp256k1: + return 'secp256k1'; + } + + $reflect = new \ReflectionClass($curve); + $curveName = $reflect->isFinal() ? + $reflect->getParentClass()->getShortName() : + $reflect->getShortName(); + throw new UnsupportedCurveException("$curveName is not a supported curve"); + } + + /** + * Return the array superstructure for an EC public key + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return array + */ + private static function savePublicKeyHelper(BaseCurve $curve, array $publicKey) + { + if ($curve instanceof TwistedEdwardsCurve) { + return [ + 'kty' => 'OKP', + 'crv' => $curve instanceof Ed25519 ? 'Ed25519' : 'Ed448', + 'x' => Strings::base64url_encode($curve->encodePoint($publicKey)) + ]; + } + + return [ + 'kty' => 'EC', + 'crv' => self::getAlias($curve), + 'x' => Strings::base64url_encode($publicKey[0]->toBytes()), + 'y' => Strings::base64url_encode($publicKey[1]->toBytes()) + ]; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + $key = self::savePublicKeyHelper($curve, $publicKey); + + return self::wrapKey($key, $options); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + $key = self::savePublicKeyHelper($curve, $publicKey); + $key['d'] = $curve instanceof TwistedEdwardsCurve ? $secret : $privateKey->toBytes(); + $key['d'] = Strings::base64url_encode($key['d']); + + return self::wrapKey($key, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php new file mode 100644 index 000000000..5741b05ad --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php @@ -0,0 +1,101 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Curve448; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Montgomery Curve Private Key Handler + * + * @author Jim Wigginton + */ +abstract class MontgomeryPrivate +{ + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $curve = new Curve25519(); + break; + case 56: + $curve = new Curve448(); + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + + $components = ['curve' => $curve]; + $components['dA'] = new BigInteger($key, 256); + $curve->rangeCheck($components['dA']); + // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) + { + return strrev($publicKey[0]->toBytes()); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $secret = null, $password = '') + { + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); + } + + return $privateKey->toBytes(); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php new file mode 100644 index 000000000..d1ad48a5b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php @@ -0,0 +1,71 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Curve448; +use phpseclib3\Math\BigInteger; + +/** + * Montgomery Public Key Handler + * + * @author Jim Wigginton + */ +abstract class MontgomeryPublic +{ + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $curve = new Curve25519(); + break; + case 56: + $curve = new Curve448(); + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + + $components = ['curve' => $curve]; + $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key), 256))]; + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) + { + return strrev($publicKey[0]->toBytes()); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..2cd3e19d0 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php @@ -0,0 +1,209 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSH Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends Progenitor +{ + use Common; + + /** + * Supported Key Types + * + * @var array + */ + protected static $types = [ + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'ssh-ed25519' + ]; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + $paddedKey = $parsed['paddedKey']; + list($type) = Strings::unpackSSH2('s', $paddedKey); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + if ($type == 'ssh-ed25519') { + list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey); + $key = libsodium::load($key); + $key['comment'] = $comment; + return $key; + } + list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); + $curve = self::loadCurveByParam(['namedCurve' => $curveName]); + $curve->rangeCheck($privateKey); + return [ + 'curve' => $curve, + 'dA' => $privateKey, + 'QA' => self::extractPoint("\0$publicKey", $curve), + 'comment' => $comment + ]; + } + + if ($parsed['type'] == 'ssh-ed25519') { + if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + + $curve = new Ed25519(); + $qa = self::extractPoint($parsed['publicKey'], $curve); + } else { + list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']); + $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; + $curve = new $curveName(); + + $qa = self::extractPoint("\0" . $publicKey, $curve); + } + + return [ + 'curve' => $curve, + 'QA' => $qa, + 'comment' => $parsed['comment'] + ]; + } + + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(BaseCurve $curve) + { + self::initialize_static_variables(); + + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + + $oid = self::$curveOIDs[$name]; + $aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) { + return $v == $oid; + }); + $aliases = array_keys($aliases); + + for ($i = 0; $i < count($aliases); $i++) { + if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { + $alias = $aliases[$i]; + break; + } + } + + if (!isset($alias)) { + throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); + } + + return $alias; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + + if ($curve instanceof Ed25519) { + $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + + $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment; + return $key; + } + + $alias = self::getAlias($curve); + + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + + $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment; + + return $key; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + if ($curve instanceof Ed25519) { + if (!isset($secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (strlen($secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + + $pubKey = $curve->encodePoint($publicKey); + + $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); + $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $secret . $pubKey); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } + + $alias = self::getAlias($curve); + + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]); + + $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..9f4b33003 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php @@ -0,0 +1,194 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * "PKCS1" (RFC5915) Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + use Common; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { + $components = []; + + preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); + $decoded = parent::load($matches[0], $password); + $decoded = ASN1::decodeBER($decoded); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (!is_array($ecPrivate)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (isset($ecPrivate['parameters'])) { + $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); + } + + preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); + $decoded = parent::load($matches[0], ''); + $decoded = ASN1::decodeBER($decoded); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (!is_array($ecParams)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + $ecParams = self::loadCurveByParam($ecParams); + + // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes + // even if the modulo is the same + if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { + throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); + } + + if (!isset($components['curve'])) { + $components['curve'] = $ecParams; + } + + $components['dA'] = new BigInteger($ecPrivate['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); + $components['QA'] = isset($ecPrivate['publicKey']) ? + self::extractPoint($ecPrivate['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (is_array($key)) { + return ['curve' => self::loadCurveByParam($key)]; + } + + $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (!is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (!isset($key['parameters'])) { + throw new \RuntimeException('Key cannot be loaded without parameters'); + } + + $components = []; + $components['curve'] = self::loadCurveByParam($key['parameters']); + $components['dA'] = new BigInteger($key['privateKey'], 256); + $components['QA'] = isset($ecPrivate['publicKey']) ? + self::extractPoint($ecPrivate['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert EC parameters to the appropriate format + * + * @return string + */ + public static function saveParameters(BaseCurve $curve, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + + $key = self::encodeParameters($curve, false, $options); + + return "-----BEGIN EC PARAMETERS-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END EC PARAMETERS-----\r\n"; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards Curves are not supported'); + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + 'parameters' => new ASN1\Element(self::encodeParameters($curve)), + 'publicKey' => "\0" . $publicKey + ]; + + $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'EC', $password, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..0ec7742fc --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php @@ -0,0 +1,234 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Ed448; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + use Common; + + /** + * OID Name + * + * @var array + */ + const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + // initialize_static_variables() is defined in both the trait and the parent class + // when it's defined in two places it's the traits one that's called + // the parent one is needed, as well, but the parent one is called by other methods + // in the parent class as needed and in the context of the parent it's the parent + // one that's called + self::initialize_static_variables(); + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + switch ($key[$type . 'Algorithm']['algorithm']) { + case 'id-Ed25519': + case 'id-Ed448': + return self::loadEdDSA($key); + } + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (!$params) { + throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); + } + + $components = []; + $components['curve'] = self::loadCurveByParam($params); + + if ($type == 'publicKey') { + $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); + + return $components; + } + + $decoded = ASN1::decodeBER($key['privateKey']); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (isset($key['parameters']) && $params != $key['parameters']) { + throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); + } + + $components['dA'] = new BigInteger($key['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); + $components['QA'] = isset($key['publicKey']) ? + self::extractPoint($key['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Break a public or private EdDSA key down into its constituent components + * + * @return array + */ + private static function loadEdDSA(array $key) + { + $components = []; + + if (isset($key['privateKey'])) { + $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); + + // 0x04 == octet string + // 0x20 == length (32 bytes) + if (substr($key['privateKey'], 0, 2) != "\x04\x20") { + throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); + } + $arr = $components['curve']->extractSecret(substr($key['privateKey'], 2)); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } + + if (isset($key['publicKey'])) { + if (!isset($components['curve'])) { + $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); + } + + $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); + } + + if (isset($key['privateKey']) && !isset($components['QA'])) { + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + } + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('Montgomery Curves are not supported'); + } + + if ($curve instanceof TwistedEdwardsCurve) { + return self::wrapPublicKey( + $curve->encodePoint($publicKey), + null, + $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' + ); + } + + $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); + + $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + return self::wrapPublicKey($key, $params, 'id-ecPublicKey'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('Montgomery Curves are not supported'); + } + + if ($curve instanceof TwistedEdwardsCurve) { + return self::wrapPrivateKey( + "\x04\x20" . $secret, + [], + null, + $password, + $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' + ); + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); + + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + //'parameters' => $params, + 'publicKey' => "\0" . $publicKey + ]; + + $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); + + return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..866c883fb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php @@ -0,0 +1,138 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Math\BigInteger; + +/** + * PuTTY Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends Progenitor +{ + use Common; + + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\EC\Formats\Keys\OpenSSH'; + + /** + * Supported Key Types + * + * @var array + */ + protected static $types = [ + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'ssh-ed25519' + ]; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + + $private = $components['private']; + + $temp = Strings::base64_encode(Strings::packSSH2('s', $components['type']) . $components['public']); + $components = OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); + + if ($components['curve'] instanceof TwistedEdwardsCurve) { + if (Strings::shift($private, 4) != "\0\0\0\x20") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + $arr = $components['curve']->extractSecret($private); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } else { + list($components['dA']) = Strings::unpackSSH2('i', $private); + $components['curve']->rangeCheck($components['dA']); + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = false, array $options = []) + { + self::initialize_static_variables(); + + $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); + $name = $public[0]; + $public = Strings::base64_decode($public[1]); + list(, $length) = unpack('N', Strings::shift($public, 4)); + Strings::shift($public, $length); + + // PuTTY pads private keys with a null byte per the following: + // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 + if (!$curve instanceof TwistedEdwardsCurve) { + $private = $privateKey->toBytes(); + if (!(strlen($privateKey->toBits()) & 7)) { + $private = "\0$private"; + } + } + + $private = $curve instanceof TwistedEdwardsCurve ? + Strings::packSSH2('s', $secret) : + Strings::packSSH2('s', $private); + + return self::wrapPrivateKey($public, $private, $name, $password, $options); + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField[] $publicKey + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey) + { + $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); + $type = $public[0]; + $public = Strings::base64_decode($public[1]); + list(, $length) = unpack('N', Strings::shift($public, 4)); + Strings::shift($public, $length); + + return self::wrapPublicKey($public, $type); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php new file mode 100644 index 000000000..27d9218fb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php @@ -0,0 +1,485 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; + +/** + * XML Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + use Common; + + /** + * Default namespace + * + * @var string + */ + private static $namespace; + + /** + * Flag for using RFC4050 syntax + * + * @var bool + */ + private static $rfc4050 = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (!class_exists('DOMDocument')) { + throw new BadConfigurationException('The dom extension is not setup correctly on this system'); + } + + $use_errors = libxml_use_internal_errors(true); + + $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); + if ($temp) { + $key = $temp; + } + + $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); + if ($temp) { + $key = $temp; + } + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + libxml_use_internal_errors($use_errors); + $curve = self::loadCurveByParam($xpath); + + $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); + + $QA = self::query($xpath, 'ecdsakeyvalue')->length ? + self::extractPointRFC4050($xpath, $curve) : + self::extractPoint("\0" . $pubkey, $curve); + + libxml_use_internal_errors($use_errors); + + return compact('curve', 'QA'); + } + + /** + * Case-insensitive xpath query + * + * @param \DOMXPath $xpath + * @param string $name + * @param string $error optional + * @param bool $decode optional + * @return \DOMNodeList + */ + private static function query(\DOMXPath $xpath, $name, $error = null, $decode = true) + { + $query = '/'; + $names = explode('/', $name); + foreach ($names as $name) { + $query .= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$name']"; + } + $result = $xpath->query($query); + if (!isset($error)) { + return $result; + } + + if (!$result->length) { + throw new \RuntimeException($error); + } + return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; + } + + /** + * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. + * + * @param string $xml + * @param string $ns + */ + private static function isolateNamespace($xml, $ns) + { + $dom = new \DOMDocument(); + if (!$dom->loadXML($xml)) { + return false; + } + $xpath = new \DOMXPath($dom); + $nodes = $xpath->query("//*[namespace::*[.='$ns'] and not(../namespace::*[.='$ns'])]"); + if (!$nodes->length) { + return false; + } + $node = $nodes->item(0); + $ns_name = $node->lookupPrefix($ns); + if ($ns_name) { + $node->removeAttributeNS($ns, $ns_name); + } + return $dom->saveXML($node); + } + + /** + * Decodes the value + * + * @param string $value + */ + private static function decodeValue($value) + { + return Strings::base64_decode(str_replace(["\r", "\n", ' ', "\t"], '', $value)); + } + + /** + * Extract points from an XML document + * + * @param \DOMXPath $xpath + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + private static function extractPointRFC4050(\DOMXPath $xpath, BaseCurve $curve) + { + $x = self::query($xpath, 'publickey/x'); + $y = self::query($xpath, 'publickey/y'); + if (!$x->length || !$x->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / X coordinate not found'); + } + if (!$y->length || !$y->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / Y coordinate not found'); + } + $point = [ + $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), + $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))) + ]; + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParam(\DOMXPath $xpath) + { + $namedCurve = self::query($xpath, 'namedcurve'); + if ($namedCurve->length == 1) { + $oid = $namedCurve->item(0)->getAttribute('URN'); + $oid = preg_replace('#[^\d.]#', '', $oid); + $name = array_search($oid, self::$curveOIDs); + if ($name === false) { + throw new UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); + } + + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $name; + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); + } + return new $curve(); + } + + $params = self::query($xpath, 'explicitparams'); + if ($params->length) { + return self::loadCurveByParamRFC4050($xpath); + } + + $params = self::query($xpath, 'ecparameters'); + if (!$params->length) { + throw new \RuntimeException('No parameters are present'); + } + + $fieldTypes = [ + 'prime-field' => ['fieldid/prime/p'], + 'gnb' => ['fieldid/gnb/m'], + 'tnb' => ['fieldid/tnb/k'], + 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], + 'unknown' => [] + ]; + + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = preg_replace('#.*/#', '', $query); + $$param = self::decodeValue($result->item(0)->textContent); + } + break; + } + + $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); + $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); + $base = self::query($xpath, 'base', 'Base point is not present'); + $order = self::query($xpath, 'order', 'Order is not present'); + + switch ($type) { + case 'prime-field': + $curve = new PrimeCurve(); + $curve->setModulo(new BigInteger($p, 256)); + $curve->setCoefficients( + new BigInteger($a, 256), + new BigInteger($b, 256) + ); + $point = self::extractPoint("\0" . $base, $curve); + $curve->setBasePoint(...$point); + $curve->setOrder(new BigInteger($order, 256)); + return $curve; + case 'gnb': + case 'tnb': + case 'pnb': + default: + throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParamRFC4050(\DOMXPath $xpath) + { + $fieldTypes = [ + 'prime-field' => ['primefieldparamstype/p'], + 'unknown' => [] + ]; + + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = preg_replace('#.*/#', '', $query); + $$param = $result->item(0)->textContent; + } + break; + } + + $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', false); + $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', false); + $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', false); + $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', false); + $order = self::query($xpath, 'order', 'Order is not present', false); + + switch ($type) { + case 'prime-field': + $curve = new PrimeCurve(); + + $p = str_replace(["\r", "\n", ' ', "\t"], '', $p); + $curve->setModulo(new BigInteger($p)); + + $a = str_replace(["\r", "\n", ' ', "\t"], '', $a); + $b = str_replace(["\r", "\n", ' ', "\t"], '', $b); + $curve->setCoefficients( + new BigInteger($a), + new BigInteger($b) + ); + + $x = str_replace(["\r", "\n", ' ', "\t"], '', $x); + $y = str_replace(["\r", "\n", ' ', "\t"], '', $y); + $curve->setBasePoint( + new BigInteger($x), + new BigInteger($y) + ); + + $order = str_replace(["\r", "\n", ' ', "\t"], '', $order); + $curve->setOrder(new BigInteger($order)); + return $curve; + default: + throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + + /** + * Sets the namespace. dsig11 is the most common one. + * + * Set to null to unset. Used only for creating public keys. + * + * @param string $namespace + */ + public static function setNamespace($namespace) + { + self::$namespace = $namespace; + } + + /** + * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 + */ + public static function enableRFC4050Syntax() + { + self::$rfc4050 = true; + } + + /** + * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters + */ + public static function disableRFC4050Syntax() + { + self::$rfc4050 = false; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + + if (empty(static::$namespace)) { + $pre = $post = ''; + } else { + $pre = static::$namespace . ':'; + $post = ':' . static::$namespace; + } + + if (self::$rfc4050) { + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . + self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . + '<' . $pre . 'PublicKey>' . "\r\n" . + '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . + '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . + '' . "\r\n" . + ''; + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . + self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . + '<' . $pre . 'PublicKey>' . Strings::base64_encode($publicKey) . '' . "\r\n" . + ''; + } + + /** + * Encode Parameters + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param string $pre + * @param array $options optional + * @return string|false + */ + private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = []) + { + $result = self::encodeParameters($curve, true, $options); + + if (isset($result['namedCurve'])) { + $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; + return self::$rfc4050 ? + '' . str_replace('URI', 'URN', $namedCurve) . '' : + $namedCurve; + } + + if (self::$rfc4050) { + $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . + '<' . $pre . 'FieldParams>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml .= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . + '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . + '' . "\r\n"; + $a = $curve->getA(); + $b = $curve->getB(); + list($x, $y) = $curve->getBasePoint(); + break; + default: + throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml .= '' . "\r\n" . + '<' . $pre . 'CurveParamsType>' . "\r\n" . + '<' . $pre . 'A>' . $a . '' . "\r\n" . + '<' . $pre . 'B>' . $b . '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'BasePointParams>' . "\r\n" . + '<' . $pre . 'BasePoint>' . "\r\n" . + '<' . $pre . 'ECPointType>' . "\r\n" . + '<' . $pre . 'X>' . $x . '' . "\r\n" . + '<' . $pre . 'Y>' . $y . '' . "\r\n" . + '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . + '' . "\r\n" . + '' . "\r\n"; + + return $xml; + } + + if (isset($result['specifiedCurve'])) { + $xml = '<' . $pre . 'ECParameters>' . "\r\n" . + '<' . $pre . 'FieldID>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml .= '<' . $pre . 'Prime>' . "\r\n" . + '<' . $pre . 'P>' . Strings::base64_encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . + '' . "\r\n" ; + break; + default: + throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml .= '' . "\r\n" . + '<' . $pre . 'Curve>' . "\r\n" . + '<' . $pre . 'A>' . Strings::base64_encode($temp['curve']['a']) . '' . "\r\n" . + '<' . $pre . 'B>' . Strings::base64_encode($temp['curve']['b']) . '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'Base>' . Strings::base64_encode($temp['base']) . '' . "\r\n" . + '<' . $pre . 'Order>' . Strings::base64_encode($temp['order']) . '' . "\r\n" . + ''; + return $xml; + } + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php new file mode 100644 index 000000000..2be6ba59b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php @@ -0,0 +1,116 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * libsodium Key Handler + * + * @author Jim Wigginton + */ +abstract class libsodium +{ + use Common; + + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $public = $key; + break; + case 64: + $private = substr($key, 0, 32); + $public = substr($key, -32); + break; + case 96: + $public = substr($key, -32); + if (substr($key, 32, 32) != $public) { + throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); + } + $private = substr($key, 0, 32); + break; + default: + throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); + } + + $curve = new Ed25519(); + $components = ['curve' => $curve]; + if (isset($private)) { + $arr = $curve->extractSecret($private); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } + $components['QA'] = isset($public) ? + self::extractPoint($public, $curve) : + $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(Ed25519 $curve, array $publicKey) + { + return $curve->encodePoint($publicKey); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $secret = null, $password = '') + { + if (!isset($secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (strlen($secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('libsodium private keys do not support encryption'); + } + return $secret . $curve->encodePoint($publicKey); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php new file mode 100644 index 000000000..d2a80a14f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php @@ -0,0 +1,62 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\File\ASN1 as Encoder; +use phpseclib3\File\ASN1\Maps\EcdsaSigValue; +use phpseclib3\Math\BigInteger; + +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @param string $sig + * @return array + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $decoded = Encoder::decodeBER($sig); + if (empty($decoded)) { + return false; + } + $components = Encoder::asn1map($decoded[0], EcdsaSigValue::MAP); + + return $components; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return Encoder::encodeDER(compact('r', 's'), EcdsaSigValue::MAP); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php new file mode 100644 index 000000000..7e4b47fe6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php @@ -0,0 +1,25 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; + +/** + * Raw DSA Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw extends Progenitor +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php new file mode 100644 index 000000000..e06444212 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php @@ -0,0 +1,94 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; + +/** + * SSH2 Signature Handler + * + * @author Jim Wigginton + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $result = Strings::unpackSSH2('ss', $sig); + if ($result === false) { + return false; + } + list($type, $blob) = $result; + switch ($type) { + // see https://tools.ietf.org/html/rfc5656#section-3.1.2 + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + break; + default: + return false; + } + + $result = Strings::unpackSSH2('ii', $blob); + if ($result === false) { + return false; + } + + return [ + 'r' => $result[0], + 's' => $result[1] + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @param string $curve + * @return string + */ + public static function save(BigInteger $r, BigInteger $s, $curve) + { + switch ($curve) { + case 'secp256r1': + $curve = 'nistp256'; + break; + case 'secp384r1': + $curve = 'nistp384'; + break; + case 'secp521r1': + $curve = 'nistp521'; + break; + default: + return false; + } + + $blob = Strings::packSSH2('ii', $r, $s); + + return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php new file mode 100644 index 000000000..c0ed64a84 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php @@ -0,0 +1,36 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Crypt\EC; + +/** + * EC Parameters + * + * @author Jim Wigginton + */ +final class Parameters extends EC +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->curve, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php new file mode 100644 index 000000000..462ea1a33 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php @@ -0,0 +1,256 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Math\BigInteger; + +/** + * EC Private Key + * + * @author Jim Wigginton + */ +final class PrivateKey extends EC implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * Private Key dA + * + * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of + * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by + * a certain amount whereas a BigInteger isn't. + * + * @var object + */ + protected $dA; + + /** + * @var string + */ + protected $secret; + + /** + * Multiplies an encoded point by the private key + * + * Used by ECDH + * + * @param string $coordinates + * @return string + */ + public function multiply($coordinates) + { + if ($this->curve instanceof MontgomeryCurve) { + if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) { + return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); + } + + $point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))]; + $point = $this->curve->multiplyPoint($point, $this->dA); + return strrev($point[0]->toBytes(true)); + } + if (!$this->curve instanceof TwistedEdwardsCurve) { + $coordinates = "\0$coordinates"; + } + $point = PKCS1::extractPoint($coordinates, $this->curve); + $point = $this->curve->multiplyPoint($point, $this->dA); + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve->encodePoint($point); + } + if (empty($point)) { + throw new \RuntimeException('The infinity point is invalid'); + } + return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); + } + + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return mixed + */ + public function sign($message) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $dA = $this->dA; + $order = $this->curve->getOrder(); + + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === false) { + return false; + } + + if ($this->curve instanceof TwistedEdwardsCurve) { + if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + $result = sodium_crypto_sign_detached($message, $this->withPassword()->toString('libsodium')); + return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result; + } + + // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. + // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , + // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" + $A = $this->curve->encodePoint($this->QA); + $curve = $this->curve; + $hash = new Hash($curve::HASH); + + $secret = substr($hash->hash($this->secret), $curve::SIZE); + + if ($curve instanceof Ed25519) { + $dom = !isset($this->context) ? '' : + 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom = 'SigEd448' . "\0" . chr(strlen($context)) . $context; + } + // SHA-512(dom2(F, C) || prefix || PH(M)) + $r = $hash->hash($dom . $secret . $message); + $r = strrev($r); + $r = new BigInteger($r, 256); + list(, $r) = $r->divide($order); + $R = $curve->multiplyPoint($curve->getBasePoint(), $r); + $R = $curve->encodePoint($R); + $k = $hash->hash($dom . $R . $A . $message); + $k = strrev($k); + $k = new BigInteger($k, 256); + list(, $k) = $k->divide($order); + $S = $k->multiply($dA)->add($r); + list(, $S) = $S->divide($order); + $S = str_pad(strrev($S->toBytes()), $curve::SIZE, "\0"); + return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S; + } + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $signature = ''; + // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long + // supported signing / verification + // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; + // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even + // has curve-specific optimizations + $result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + + if ($result) { + if ($shortFormat == 'ASN1') { + return $signature; + } + + extract(ASN1Signature::load($signature)); + + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + } + + $e = $this->hash->hash($message); + $e = new BigInteger($e, 256); + + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + + while (true) { + $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($order); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($order); + $temp = $z->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($order); + if (!$s->equals(self::$zero)) { + break; + } + } + + // the following is an RFC6979 compliant implementation of deterministic ECDSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + // if this were actually being used it'd probably be better if this lived in load() and createKey() + $this->q = $this->curve->getOrder(); + $dA = $this->dA->toBigInteger(); + $this->x = $dA; + + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->secret, $this->password, $options); + } + + /** + * Returns the public key + * + * @see self::getPrivateKey() + * @return mixed + */ + public function getPublicKey() + { + $format = 'PKCS8'; + if ($this->curve instanceof MontgomeryCurve) { + $format = 'MontgomeryPublic'; + } + + $type = self::validatePlugin('Keys', $format, 'savePublicKey'); + + $key = $type::savePublicKey($this->curve, $this->QA); + $key = EC::loadFormat($format, $key); + if ($this->curve instanceof MontgomeryCurve) { + return $key; + } + $key = $key + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + if ($this->curve instanceof TwistedEdwardsCurve) { + $key = $key->withContext($this->context); + } + return $key; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php new file mode 100644 index 000000000..4558ce34d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php @@ -0,0 +1,172 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Math\BigInteger; + +/** + * EC Public Key + * + * @author Jim Wigginton + */ +final class PublicKey extends EC implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Verify a signature + * + * @see self::verify() + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === false) { + return false; + } + + $order = $this->curve->getOrder(); + + if ($this->curve instanceof TwistedEdwardsCurve) { + if ($shortFormat == 'SSH2') { + list(, $signature) = Strings::unpackSSH2('ss', $signature); + } + + if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); + } + + $curve = $this->curve; + if (strlen($signature) != 2 * $curve::SIZE) { + return false; + } + + $R = substr($signature, 0, $curve::SIZE); + $S = substr($signature, $curve::SIZE); + + try { + $R = PKCS1::extractPoint($R, $curve); + $R = $this->curve->convertToInternal($R); + } catch (\Exception $e) { + return false; + } + + $S = strrev($S); + $S = new BigInteger($S, 256); + + if ($S->compare($order) >= 0) { + return false; + } + + $A = $curve->encodePoint($this->QA); + + if ($curve instanceof Ed25519) { + $dom2 = !isset($this->context) ? '' : + 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context; + } + + $hash = new Hash($curve::HASH); + $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message); + $k = strrev($k); + $k = new BigInteger($k, 256); + list(, $k) = $k->divide($order); + + $qa = $curve->convertToInternal($this->QA); + + $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S); + $rhs = $curve->multiplyPoint($qa, $k); + $rhs = $curve->addPoint($rhs, $R); + $rhs = $curve->convertToAffine($rhs); + + return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); + } + + $params = $format::load($signature); + if ($params === false || count($params) != 2) { + return false; + } + extract($params); + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; + + $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + + if ($result != -1) { + return (bool) $result; + } + } + + $n_1 = $order->subtract(self::$one); + if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { + return false; + } + + $e = $this->hash->hash($message); + $e = new BigInteger($e, 256); + + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + + $w = $s->modInverse($order); + list(, $u1) = $z->multiply($w)->divide($order); + list(, $u2) = $r->multiply($w)->divide($order); + + $u1 = $this->curve->convertInteger($u1); + $u2 = $this->curve->convertInteger($u2); + + list($x1, $y1) = $this->curve->multiplyAddPoints( + [$this->curve->getBasePoint(), $this->QA], + [$u1, $u2] + ); + + $x1 = $x1->toBigInteger(); + list(, $x1) = $x1->divide($order); + + return $x1->equals($r); + } + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->curve, $this->QA, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php new file mode 100644 index 000000000..0e02544eb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php @@ -0,0 +1,1455 @@ + + * setKey('abcdefg'); + * + * echo base64_encode($hash->hash('abcdefg')); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @author Andreas Fischer + * @copyright 2015 Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; + +/** + * @author Jim Wigginton + * @author Andreas Fischer + */ +class Hash +{ + /** + * Padding Types + * + */ + const PADDING_KECCAK = 1; + + /** + * Padding Types + * + */ + const PADDING_SHA3 = 2; + + /** + * Padding Types + * + */ + const PADDING_SHAKE = 3; + + /** + * Padding Type + * + * Only used by SHA3 + * + * @var int + */ + private $paddingType = 0; + + /** + * Hash Parameter + * + * @see self::setHash() + * @var int + */ + private $hashParam; + + /** + * Byte-length of hash output (Internal HMAC) + * + * @see self::setHash() + * @var int + */ + private $length; + + /** + * Hash Algorithm + * + * @see self::setHash() + * @var string + */ + private $algo; + + /** + * Key + * + * @see self::setKey() + * @var string + */ + private $key = false; + + /** + * Nonce + * + * @see self::setNonce() + * @var string + */ + private $nonce = false; + + /** + * Hash Parameters + * + * @var array + */ + private $parameters = []; + + /** + * Computed Key + * + * @see self::_computeKey() + * @var string + */ + private $computedKey = false; + + /** + * Outer XOR (Internal HMAC) + * + * Used only for sha512/* + * + * @see self::hash() + * @var string + */ + private $opad; + + /** + * Inner XOR (Internal HMAC) + * + * Used only for sha512/* + * + * @see self::hash() + * @var string + */ + private $ipad; + + /** + * Recompute AES Key + * + * Used only for umac + * + * @see self::hash() + * @var boolean + */ + private $recomputeAESKey; + + /** + * umac cipher object + * + * @see self::hash() + * @var \phpseclib3\Crypt\AES + */ + private $c; + + /** + * umac pad + * + * @see self::hash() + * @var string + */ + private $pad; + + /** + * Block Size + * + * @var int + */ + private $blockSize; + + /**#@+ + * UMAC variables + * + * @var PrimeField + */ + private static $factory36; + private static $factory64; + private static $factory128; + private static $offset64; + private static $offset128; + private static $marker64; + private static $marker128; + private static $maxwordrange64; + private static $maxwordrange128; + /**#@-*/ + + /** + * Default Constructor. + * + * @param string $hash + */ + public function __construct($hash = 'sha256') + { + $this->setHash($hash); + } + + /** + * Sets the key for HMACs + * + * Keys can be of any length. + * + * @param string $key + */ + public function setKey($key = false) + { + $this->key = $key; + $this->computeKey(); + $this->recomputeAESKey = true; + } + + /** + * Sets the nonce for UMACs + * + * Keys can be of any length. + * + * @param string $nonce + */ + public function setNonce($nonce = false) + { + switch (true) { + case !is_string($nonce): + case strlen($nonce) > 0 && strlen($nonce) <= 16: + $this->recomputeAESKey = true; + $this->nonce = $nonce; + return; + } + + throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); + } + + /** + * Pre-compute the key used by the HMAC + * + * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes + * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." + * + * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ + * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during + * every call + * + */ + private function computeKey() + { + if ($this->key === false) { + $this->computedKey = false; + return; + } + + if (strlen($this->key) <= $this->getBlockLengthInBytes()) { + $this->computedKey = $this->key; + return; + } + + $this->computedKey = is_array($this->algo) ? + call_user_func($this->algo, $this->key) : + hash($this->algo, $this->key, true); + } + + /** + * Gets the hash function. + * + * As set by the constructor or by the setHash() method. + * + * @return string + */ + public function getHash() + { + return $this->hashParam; + } + + /** + * Sets the hash function. + * + * @param string $hash + */ + public function setHash($hash) + { + $this->hashParam = $hash = strtolower($hash); + switch ($hash) { + case 'umac-32': + case 'umac-64': + case 'umac-96': + case 'umac-128': + $this->blockSize = 128; + $this->length = abs(substr($hash, -3)) >> 3; + $this->algo = 'umac'; + return; + case 'md2-96': + case 'md5-96': + case 'sha1-96': + case 'sha224-96': + case 'sha256-96': + case 'sha384-96': + case 'sha512-96': + case 'sha512/224-96': + case 'sha512/256-96': + $hash = substr($hash, 0, -3); + $this->length = 12; // 96 / 8 = 12 + break; + case 'md2': + case 'md5': + $this->length = 16; + break; + case 'sha1': + $this->length = 20; + break; + case 'sha224': + case 'sha512/224': + case 'sha3-224': + $this->length = 28; + break; + case 'keccak256': + $this->paddingType = self::PADDING_KECCAK; + // fall-through + case 'sha256': + case 'sha512/256': + case 'sha3-256': + $this->length = 32; + break; + case 'sha384': + case 'sha3-384': + $this->length = 48; + break; + case 'sha512': + case 'sha3-512': + $this->length = 64; + break; + default: + if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { + $this->paddingType = self::PADDING_SHAKE; + $hash = $matches[1]; + $this->length = $matches[2] >> 3; + } else { + throw new UnsupportedAlgorithmException( + "$hash is not a supported algorithm" + ); + } + } + + switch ($hash) { + case 'md2': + case 'md2-96': + $this->blockSize = 128; + break; + case 'md5-96': + case 'sha1-96': + case 'sha224-96': + case 'sha256-96': + case 'md5': + case 'sha1': + case 'sha224': + case 'sha256': + $this->blockSize = 512; + break; + case 'sha3-224': + $this->blockSize = 1152; // 1600 - 2*224 + break; + case 'sha3-256': + case 'shake256': + case 'keccak256': + $this->blockSize = 1088; // 1600 - 2*256 + break; + case 'sha3-384': + $this->blockSize = 832; // 1600 - 2*384 + break; + case 'sha3-512': + $this->blockSize = 576; // 1600 - 2*512 + break; + case 'shake128': + $this->blockSize = 1344; // 1600 - 2*128 + break; + default: + $this->blockSize = 1024; + } + + if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) { + // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": + // http://php.net/ChangeLog-7.php#7.1.0 + if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0, 5) != 'sha3-') { + //preg_match('#(\d+)$#', $hash, $matches); + //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize + //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize + if (!$this->paddingType) { + $this->paddingType = self::PADDING_SHA3; + } + $this->parameters = [ + 'capacity' => 1600 - $this->blockSize, + 'rate' => $this->blockSize, + 'length' => $this->length, + 'padding' => $this->paddingType + ]; + $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; + } + } + + if ($hash == 'sha512/224' || $hash == 'sha512/256') { + // PHP 7.1.0 introduced sha512/224 and sha512/256 support: + // http://php.net/ChangeLog-7.php#7.1.0 + if (version_compare(PHP_VERSION, '7.1.0') < 0) { + // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 + $initial = $hash == 'sha512/256' ? + [ + '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', + '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' + ] : + [ + '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', + '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' + ]; + for ($i = 0; $i < 8; $i++) { + $initial[$i] = new BigInteger($initial[$i], 16); + $initial[$i]->setPrecision(64); + } + + $this->parameters = compact('initial'); + + $hash = ['phpseclib3\Crypt\Hash', 'sha512']; + } + } + + if (is_array($hash)) { + $b = $this->blockSize >> 3; + $this->ipad = str_repeat(chr(0x36), $b); + $this->opad = str_repeat(chr(0x5C), $b); + } + + $this->algo = $hash; + + $this->computeKey(); + } + + /** + * KDF: Key-Derivation Function + * + * The key-derivation function generates pseudorandom bits used to key the hash functions. + * + * @param int $index a non-negative integer less than 2^64 + * @param int $numbytes a non-negative integer less than 2^64 + * @return string string of length numbytes bytes + */ + private function kdf($index, $numbytes) + { + $this->c->setIV(pack('N4', 0, $index, 0, 1)); + + return $this->c->encrypt(str_repeat("\0", $numbytes)); + } + + /** + * PDF Algorithm + * + * @return string string of length taglen bytes. + */ + private function pdf() + { + $k = $this->key; + $nonce = $this->nonce; + $taglen = $this->length; + + // + // Extract and zero low bit(s) of Nonce if needed + // + if ($taglen <= 8) { + $last = strlen($nonce) - 1; + $mask = $taglen == 4 ? "\3" : "\1"; + $index = $nonce[$last] & $mask; + $nonce[$last] = $nonce[$last] ^ $index; + } + + // + // Make Nonce BLOCKLEN bytes by appending zeroes if needed + // + $nonce = str_pad($nonce, 16, "\0"); + + // + // Generate subkey, encipher and extract indexed substring + // + $kp = $this->kdf(0, 16); + $c = new AES('ctr'); + $c->disablePadding(); + $c->setKey($kp); + $c->setIV($nonce); + $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); + + // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you + // unpack() doesn't leak timing info + return $taglen <= 8 ? + substr($t, unpack('C', $index)[1] * $taglen, $taglen) : + substr($t, 0, $taglen); + } + + /** + * UHASH Algorithm + * + * @param string $m string of length less than 2^67 bits. + * @param int $taglen the integer 4, 8, 12 or 16. + * @return string string of length taglen bytes. + */ + private function uhash($m, $taglen) + { + // + // One internal iteration per 4 bytes of output + // + $iters = $taglen >> 2; + + // + // Define total key needed for all iterations using KDF. + // L1Key reuses most key material between iterations. + // + //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); + $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); + $L2Key = $this->kdf(2, $iters * 24); + $L3Key1 = $this->kdf(3, $iters * 64); + $L3Key2 = $this->kdf(4, $iters * 4); + + // + // For each iteration, extract key and do three-layer hash. + // If bytelength(M) <= 1024, then skip L2-HASH. + // + $y = ''; + for ($i = 0; $i < $iters; $i++) { + $L1Key_i = substr($L1Key, $i * 16, 1024); + $L2Key_i = substr($L2Key, $i * 24, 24); + $L3Key1_i = substr($L3Key1, $i * 64, 64); + $L3Key2_i = substr($L3Key2, $i * 4, 4); + + $a = self::L1Hash($L1Key_i, $m); + $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); + $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); + $y .= $c; + } + + return $y; + } + + /** + * L1-HASH Algorithm + * + * The first-layer hash breaks the message into 1024-byte chunks and + * hashes each with a function called NH. Concatenating the results + * forms a string, which is up to 128 times shorter than the original. + * + * @param string $k string of length 1024 bytes. + * @param string $m string of length less than 2^67 bits. + * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. + */ + private static function L1Hash($k, $m) + { + // + // Break M into 1024 byte chunks (final chunk may be shorter) + // + $m = str_split($m, 1024); + + // + // For each chunk, except the last: endian-adjust, NH hash + // and add bit-length. Use results to build Y. + // + $length = new BigInteger(1024 * 8); + $y = ''; + for ($i = 0; $i < count($m) - 1; $i++) { + $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP + $y .= static::nh($k, $m[$i], $length); + } + + // + // For the last chunk: pad to 32-byte boundary, endian-adjust, + // NH hash and add bit-length. Concatenate the result to Y. + // + $length = count($m) ? strlen($m[$i]) : 0; + $pad = 32 - ($length % 32); + $pad = max(32, $length + $pad % 32); + $m[$i] = str_pad(isset($m[$i]) ? $m[$i] : '', $pad, "\0"); // zeropad + $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP + + $y .= static::nh($k, $m[$i], new BigInteger($length * 8)); + + return $y; + } + + /** + * NH Algorithm + * + * @param string $k string of length 1024 bytes. + * @param string $m string with length divisible by 32 bytes. + * @return string string of length 8 bytes. + */ + private static function nh($k, $m, $length) + { + $toUInt32 = function ($x) { + $x = new BigInteger($x, 256); + $x->setPrecision(32); + return $x; + }; + + // + // Break M and K into 4-byte chunks + // + //$t = strlen($m) >> 2; + $m = str_split($m, 4); + $t = count($m); + $k = str_split($k, 4); + $k = array_pad(array_slice($k, 0, $t), $t, 0); + + $m = array_map($toUInt32, $m); + $k = array_map($toUInt32, $k); + + // + // Perform NH hash on the chunks, pairing words for multiplication + // which are 4 apart to accommodate vector-parallelism. + // + $y = new BigInteger(); + $y->setPrecision(64); + $i = 0; + while ($i < $t) { + $temp = $m[$i]->add($k[$i]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 4]->add($k[$i + 4])); + $y = $y->add($temp); + + $temp = $m[$i + 1]->add($k[$i + 1]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 5]->add($k[$i + 5])); + $y = $y->add($temp); + + $temp = $m[$i + 2]->add($k[$i + 2]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 6]->add($k[$i + 6])); + $y = $y->add($temp); + + $temp = $m[$i + 3]->add($k[$i + 3]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 7]->add($k[$i + 7])); + $y = $y->add($temp); + + $i += 8; + } + + return $y->add($length)->toBytes(); + } + + /** + * L2-HASH: Second-Layer Hash + * + * The second-layer rehashes the L1-HASH output using a polynomial hash + * called POLY. If the L1-HASH output is long, then POLY is called once + * on a prefix of the L1-HASH output and called using different settings + * on the remainder. (This two-step hashing of the L1-HASH output is + * needed only if the message length is greater than 16 megabytes.) + * Careful implementation of POLY is necessary to avoid a possible + * timing attack (see Section 6.6 for more information). + * + * @param string $k string of length 24 bytes. + * @param string $m string of length less than 2^64 bytes. + * @return string string of length 16 bytes. + */ + private static function L2Hash($k, $m) + { + // + // Extract keys and restrict to special key-sets + // + $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; + $k64 = new BigInteger($k64, 256); + $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; + $k128 = new BigInteger($k128, 256); + + // + // If M is no more than 2^17 bytes, hash under 64-bit prime, + // otherwise, hash first 2^17 bytes under 64-bit prime and + // remainder under 128-bit prime. + // + if (strlen($m) <= 0x20000) { // 2^14 64-bit words + $y = self::poly(64, self::$maxwordrange64, $k64, $m); + } else { + $m_1 = substr($m, 0, 0x20000); // 1 << 17 + $m_2 = substr($m, 0x20000) . "\x80"; + $length = strlen($m_2); + $pad = 16 - ($length % 16); + $pad %= 16; + $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad + $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); + $y = str_pad($y, 16, "\0", STR_PAD_LEFT); + $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); + } + + return str_pad($y, 16, "\0", STR_PAD_LEFT); + } + + /** + * POLY Algorithm + * + * @param int $wordbits the integer 64 or 128. + * @param BigInteger $maxwordrange positive integer less than 2^wordbits. + * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. + * @param string $m string with length divisible by (wordbits / 8) bytes. + * @return integer in the range 0 ... prime(wordbits) - 1. + */ + private static function poly($wordbits, $maxwordrange, $k, $m) + { + // + // Define constants used for fixing out-of-range words + // + $wordbytes = $wordbits >> 3; + if ($wordbits == 128) { + $factory = self::$factory128; + $offset = self::$offset128; + $marker = self::$marker128; + } else { + $factory = self::$factory64; + $offset = self::$offset64; + $marker = self::$marker64; + } + + $k = $factory->newInteger($k); + + // + // Break M into chunks of length wordbytes bytes + // + $m_i = str_split($m, $wordbytes); + + // + // Each input word m is compared with maxwordrange. If not smaller + // then 'marker' and (m - offset), both in range, are hashed. + // + $y = $factory->newInteger(new BigInteger(1)); + foreach ($m_i as $m) { + $m = $factory->newInteger(new BigInteger($m, 256)); + if ($m->compare($maxwordrange) >= 0) { + $y = $k->multiply($y)->add($marker); + $y = $k->multiply($y)->add($m->subtract($offset)); + } else { + $y = $k->multiply($y)->add($m); + } + } + + return $y->toBytes(); + } + + /** + * L3-HASH: Third-Layer Hash + * + * The output from L2-HASH is 16 bytes long. This final hash function + * hashes the 16-byte string to a fixed length of 4 bytes. + * + * @param string $k1 string of length 64 bytes. + * @param string $k2 string of length 4 bytes. + * @param string $m string of length 16 bytes. + * @return string string of length 4 bytes. + */ + private static function L3Hash($k1, $k2, $m) + { + $factory = self::$factory36; + + $y = $factory->newInteger(new BigInteger()); + for ($i = 0; $i < 8; $i++) { + $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); + $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); + $y = $y->add($m_i->multiply($k_i)); + } + $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); + $y = $y ^ $k2; + + return $y; + } + + /** + * Compute the Hash / HMAC / UMAC. + * + * @param string $text + * @return string + */ + public function hash($text) + { + $algo = $this->algo; + if ($algo == 'umac') { + if ($this->recomputeAESKey) { + if (!is_string($this->nonce)) { + throw new InsufficientSetupException('No nonce has been set'); + } + if (!is_string($this->key)) { + throw new InsufficientSetupException('No key has been set'); + } + if (strlen($this->key) != 16) { + throw new \LengthException('Key must be 16 bytes long'); + } + + if (!isset(self::$maxwordrange64)) { + $one = new BigInteger(1); + + $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); + self::$factory36 = new PrimeField($prime36); + + $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); + self::$factory64 = new PrimeField($prime64); + + $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); + self::$factory128 = new PrimeField($prime128); + + self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); + self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); + self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); + self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); + + self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); + self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); + + $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); + self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); + + $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); + self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); + } + + $this->c = new AES('ctr'); + $this->c->disablePadding(); + $this->c->setKey($this->key); + + $this->pad = $this->pdf(); + + $this->recomputeAESKey = false; + } + + $hashedmessage = $this->uhash($text, $this->length); + return $hashedmessage ^ $this->pad; + } + + if (is_array($algo)) { + if (empty($this->key) || !is_string($this->key)) { + return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); + } + + // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 + + $key = str_pad($this->computedKey, $b, chr(0)); + $temp = $this->ipad ^ $key; + $temp .= $text; + $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); + $output = $this->opad ^ $key; + $output .= $temp; + $output = $algo($output, ...array_values($this->parameters)); + + return substr($output, 0, $this->length); + } + + $output = !empty($this->key) || is_string($this->key) ? + hash_hmac($algo, $text, $this->computedKey, true) : + hash($algo, $text, true); + + return strlen($output) > $this->length + ? substr($output, 0, $this->length) + : $output; + } + + /** + * Returns the hash length (in bits) + * + * @return int + */ + public function getLength() + { + return $this->length << 3; + } + + /** + * Returns the hash length (in bytes) + * + * @return int + */ + public function getLengthInBytes() + { + return $this->length; + } + + /** + * Returns the block length (in bits) + * + * @return int + */ + public function getBlockLength() + { + return $this->blockSize; + } + + /** + * Returns the block length (in bytes) + * + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->blockSize >> 3; + } + + /** + * Pads SHA3 based on the mode + * + * @param int $padLength + * @param int $padType + * @return string + */ + private static function sha3_pad($padLength, $padType) + { + switch ($padType) { + case self::PADDING_KECCAK: + $temp = chr(0x01) . str_repeat("\0", $padLength - 1); + $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + return $temp; + case self::PADDING_SHAKE: + $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); + $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + return $temp; + //case self::PADDING_SHA3: + default: + // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 + return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); + } + } + + /** + * Pure-PHP 32-bit implementation of SHA3 + * + * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation + * of SHA3 will *not* work on PHP 64-bit. This is because this implementation + * employees bitwise NOTs and bitwise left shifts. And the round constants only work + * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and + * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow + * things down. + * + * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees + * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed + * 64-bit integers, which complicates addition, whereas that limitation isn't an issue + * for SHA3. + * + * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is + * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and + * capacity c". This is relevant because, altho the KECCAK standard defines a mode + * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 + * + * @param string $p + * @param int $c + * @param int $r + * @param int $d + * @param int $padType + */ + private static function sha3_32($p, $c, $r, $d, $padType) + { + $block_size = $r >> 3; + $padLength = $block_size - (strlen($p) % $block_size); + $num_ints = $block_size >> 2; + + $p .= static::sha3_pad($padLength, $padType); + + $n = strlen($p) / $r; // number of blocks + + $s = [ + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] + ]; + + $p = str_split($p, $block_size); + + foreach ($p as $pi) { + $pi = unpack('V*', $pi); + $x = $y = 0; + for ($i = 1; $i <= $num_ints; $i += 2) { + $s[$x][$y][0] ^= $pi[$i + 1]; + $s[$x][$y][1] ^= $pi[$i]; + if (++$y == 5) { + $y = 0; + $x++; + } + } + static::processSHA3Block32($s); + } + + $z = ''; + $i = $j = 0; + while (strlen($z) < $d) { + $z .= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); + if ($j == 5) { + $j = 0; + $i++; + if ($i == 5) { + $i = 0; + static::processSHA3Block32($s); + } + } + } + + return $z; + } + + /** + * 32-bit block processing method for SHA3 + * + * @param array $s + */ + private static function processSHA3Block32(&$s) + { + static $rotationOffsets = [ + [ 0, 1, 62, 28, 27], + [36, 44, 6, 55, 20], + [ 3, 10, 43, 25, 39], + [41, 45, 15, 21, 8], + [18, 2, 61, 56, 14] + ]; + + // the standards give these constants in hexadecimal notation. it's tempting to want to use + // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive + // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead + static $roundConstants = [ + [0, 1], + [0, 32898], + [-2147483648, 32906], + [-2147483648, -2147450880], + [0, 32907], + [0, -2147483647], + [-2147483648, -2147450751], + [-2147483648, 32777], + [0, 138], + [0, 136], + [0, -2147450871], + [0, -2147483638], + [0, -2147450741], + [-2147483648, 139], + [-2147483648, 32905], + [-2147483648, 32771], + [-2147483648, 32770], + [-2147483648, 128], + [0, 32778], + [-2147483648, -2147483638], + [-2147483648, -2147450751], + [-2147483648, 32896], + [0, -2147483647], + [-2147483648, -2147450872] + ]; + + for ($round = 0; $round < 24; $round++) { + // theta step + $parity = $rotated = []; + for ($i = 0; $i < 5; $i++) { + $parity[] = [ + $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], + $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] + ]; + $rotated[] = static::rotateLeft32($parity[$i], 1); + } + + $temp = [ + [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], + [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], + [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], + [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], + [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] + ]; + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $s[$i][$j][0] ^= $temp[$j][0]; + $s[$i][$j][1] ^= $temp[$j][1]; + } + } + + $st = $s; + + // rho and pi steps + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); + } + } + + // chi step + for ($i = 0; $i < 5; $i++) { + $s[$i][0] = [ + $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), + $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) + ]; + $s[$i][1] = [ + $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), + $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) + ]; + $s[$i][2] = [ + $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), + $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) + ]; + $s[$i][3] = [ + $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), + $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) + ]; + $s[$i][4] = [ + $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), + $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) + ]; + } + + // iota step + $s[0][0][0] ^= $roundConstants[$round][0]; + $s[0][0][1] ^= $roundConstants[$round][1]; + } + } + + /** + * Rotate 32-bit int + * + * @param array $x + * @param int $shift + */ + private static function rotateLeft32($x, $shift) + { + if ($shift < 32) { + list($hi, $lo) = $x; + } else { + $shift -= 32; + list($lo, $hi) = $x; + } + + return [ + ($hi << $shift) | (($lo >> (32 - $shift)) & (1 << $shift) - 1), + ($lo << $shift) | (($hi >> (32 - $shift)) & (1 << $shift) - 1) + ]; + } + + /** + * Pure-PHP 64-bit implementation of SHA3 + * + * @param string $p + * @param int $c + * @param int $r + * @param int $d + * @param int $padType + */ + private static function sha3_64($p, $c, $r, $d, $padType) + { + $block_size = $r >> 3; + $padLength = $block_size - (strlen($p) % $block_size); + $num_ints = $block_size >> 2; + + $p .= static::sha3_pad($padLength, $padType); + + $n = strlen($p) / $r; // number of blocks + + $s = [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0] + ]; + + $p = str_split($p, $block_size); + + foreach ($p as $pi) { + $pi = unpack('P*', $pi); + $x = $y = 0; + foreach ($pi as $subpi) { + $s[$x][$y++] ^= $subpi; + if ($y == 5) { + $y = 0; + $x++; + } + } + static::processSHA3Block64($s); + } + + $z = ''; + $i = $j = 0; + while (strlen($z) < $d) { + $z .= pack('P', $s[$i][$j++]); + if ($j == 5) { + $j = 0; + $i++; + if ($i == 5) { + $i = 0; + static::processSHA3Block64($s); + } + } + } + + return $z; + } + + /** + * 64-bit block processing method for SHA3 + * + * @param array $s + */ + private static function processSHA3Block64(&$s) + { + static $rotationOffsets = [ + [ 0, 1, 62, 28, 27], + [36, 44, 6, 55, 20], + [ 3, 10, 43, 25, 39], + [41, 45, 15, 21, 8], + [18, 2, 61, 56, 14] + ]; + + static $roundConstants = [ + 1, + 32898, + -9223372036854742902, + -9223372034707259392, + 32907, + 2147483649, + -9223372034707259263, + -9223372036854743031, + 138, + 136, + 2147516425, + 2147483658, + 2147516555, + -9223372036854775669, + -9223372036854742903, + -9223372036854743037, + -9223372036854743038, + -9223372036854775680, + 32778, + -9223372034707292150, + -9223372034707259263, + -9223372036854742912, + 2147483649, + -9223372034707259384 + ]; + + for ($round = 0; $round < 24; $round++) { + // theta step + $parity = []; + for ($i = 0; $i < 5; $i++) { + $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; + } + $temp = [ + $parity[4] ^ static::rotateLeft64($parity[1], 1), + $parity[0] ^ static::rotateLeft64($parity[2], 1), + $parity[1] ^ static::rotateLeft64($parity[3], 1), + $parity[2] ^ static::rotateLeft64($parity[4], 1), + $parity[3] ^ static::rotateLeft64($parity[0], 1) + ]; + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $s[$i][$j] ^= $temp[$j]; + } + } + + $st = $s; + + // rho and pi steps + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); + } + } + + // chi step + for ($i = 0; $i < 5; $i++) { + $s[$i] = [ + $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), + $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), + $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), + $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), + $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) + ]; + } + + // iota step + $s[0][0] ^= $roundConstants[$round]; + } + } + + /** + * Rotate 64-bit int + * + * @param int $x + * @param int $shift + */ + private static function rotateLeft64($x, $shift) + { + return ($x << $shift) | (($x >> (64 - $shift)) & ((1 << $shift) - 1)); + } + + /** + * Pure-PHP implementation of SHA512 + * + * @param string $m + * @param array $hash + * @return string + */ + private static function sha512($m, $hash) + { + static $k; + + if (!isset($k)) { + // Initialize table of round constants + // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) + $k = [ + '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', + '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', + 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', + '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', + 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', + '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', + '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', + 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', + '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', + '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', + 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', + 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', + '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', + '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', + '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', + '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', + 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', + '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', + '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', + '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' + ]; + + for ($i = 0; $i < 80; $i++) { + $k[$i] = new BigInteger($k[$i], 16); + } + } + + // Pre-processing + $length = strlen($m); + // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 + $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); + $m[$length] = chr(0x80); + // we don't support hashing strings 512MB long + $m .= pack('N4', 0, 0, 0, $length << 3); + + // Process the message in successive 1024-bit chunks + $chunks = str_split($m, 128); + foreach ($chunks as $chunk) { + $w = []; + for ($i = 0; $i < 16; $i++) { + $temp = new BigInteger(Strings::shift($chunk, 8), 256); + $temp->setPrecision(64); + $w[] = $temp; + } + + // Extend the sixteen 32-bit words into eighty 32-bit words + for ($i = 16; $i < 80; $i++) { + $temp = [ + $w[$i - 15]->bitwise_rightRotate(1), + $w[$i - 15]->bitwise_rightRotate(8), + $w[$i - 15]->bitwise_rightShift(7) + ]; + $s0 = $temp[0]->bitwise_xor($temp[1]); + $s0 = $s0->bitwise_xor($temp[2]); + $temp = [ + $w[$i - 2]->bitwise_rightRotate(19), + $w[$i - 2]->bitwise_rightRotate(61), + $w[$i - 2]->bitwise_rightShift(6) + ]; + $s1 = $temp[0]->bitwise_xor($temp[1]); + $s1 = $s1->bitwise_xor($temp[2]); + $w[$i] = clone $w[$i - 16]; + $w[$i] = $w[$i]->add($s0); + $w[$i] = $w[$i]->add($w[$i - 7]); + $w[$i] = $w[$i]->add($s1); + } + + // Initialize hash value for this chunk + $a = clone $hash[0]; + $b = clone $hash[1]; + $c = clone $hash[2]; + $d = clone $hash[3]; + $e = clone $hash[4]; + $f = clone $hash[5]; + $g = clone $hash[6]; + $h = clone $hash[7]; + + // Main loop + for ($i = 0; $i < 80; $i++) { + $temp = [ + $a->bitwise_rightRotate(28), + $a->bitwise_rightRotate(34), + $a->bitwise_rightRotate(39) + ]; + $s0 = $temp[0]->bitwise_xor($temp[1]); + $s0 = $s0->bitwise_xor($temp[2]); + $temp = [ + $a->bitwise_and($b), + $a->bitwise_and($c), + $b->bitwise_and($c) + ]; + $maj = $temp[0]->bitwise_xor($temp[1]); + $maj = $maj->bitwise_xor($temp[2]); + $t2 = $s0->add($maj); + + $temp = [ + $e->bitwise_rightRotate(14), + $e->bitwise_rightRotate(18), + $e->bitwise_rightRotate(41) + ]; + $s1 = $temp[0]->bitwise_xor($temp[1]); + $s1 = $s1->bitwise_xor($temp[2]); + $temp = [ + $e->bitwise_and($f), + $g->bitwise_and($e->bitwise_not()) + ]; + $ch = $temp[0]->bitwise_xor($temp[1]); + $t1 = $h->add($s1); + $t1 = $t1->add($ch); + $t1 = $t1->add($k[$i]); + $t1 = $t1->add($w[$i]); + + $h = clone $g; + $g = clone $f; + $f = clone $e; + $e = $d->add($t1); + $d = clone $c; + $c = clone $b; + $b = clone $a; + $a = $t1->add($t2); + } + + // Add this chunk's hash to result so far + $hash = [ + $hash[0]->add($a), + $hash[1]->add($b), + $hash[2]->add($c), + $hash[3]->add($d), + $hash[4]->add($e), + $hash[5]->add($f), + $hash[6]->add($g), + $hash[7]->add($h) + ]; + } + + // Produce the final hash value (big-endian) + // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) + $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . + $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); + + return $temp; + } + + /** + * __toString() magic method + */ + public function __toString() + { + return $this->getHash(); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php new file mode 100644 index 000000000..61afbaeb6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php @@ -0,0 +1,111 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\File\X509; + +/** + * PublicKeyLoader + * + * @author Jim Wigginton + */ +abstract class PublicKeyLoader +{ + /** + * Loads a public or private key + * + * @return AsymmetricKey + * @param string|array $key + * @param string $password optional + */ + public static function load($key, $password = false) + { + try { + return EC::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + try { + return RSA::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + try { + return DSA::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + try { + $x509 = new X509(); + $x509->loadX509($key); + $key = $x509->getPublicKey(); + if ($key) { + return $key; + } + } catch (\Exception $e) { + } + + throw new NoKeyLoadedException('Unable to read key'); + } + + /** + * Loads a private key + * + * @return PrivateKey + * @param string|array $key + * @param string $password optional + */ + public static function loadPrivateKey($key, $password = false) + { + $key = self::load($key, $password); + if (!$key instanceof PrivateKey) { + throw new NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + + /** + * Loads a public key + * + * @return PublicKey + * @param string|array $key + */ + public static function loadPublicKey($key) + { + $key = self::load($key); + if (!$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string|array $key + */ + public static function loadParameters($key) + { + $key = self::load($key); + if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php similarity index 59% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php index b2b9d48ea..654c90642 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php @@ -16,7 +16,7 @@ * setKey('abcdefgh'); * @@ -26,121 +26,105 @@ * ?> * * - * @category Crypt - * @package RC2 * @author Patrick Monnerat * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; /** * Pure-PHP implementation of RC2. * - * @package RC2 - * @access public */ -class RC2 extends Base +class RC2 extends BlockCipher { /** * Block Length of the cipher * - * @see \phpseclib\Crypt\Base::block_size + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size * @var int - * @access private */ - var $block_size = 8; + protected $block_size = 8; /** * The Key * - * @see \phpseclib\Crypt\Base::key + * @see \phpseclib3\Crypt\Common\SymmetricKey::key * @see self::setKey() * @var string - * @access private */ - var $key; + protected $key; /** * The Original (unpadded) Key * - * @see \phpseclib\Crypt\Base::key + * @see \phpseclib3\Crypt\Common\SymmetricKey::key * @see self::setKey() * @see self::encrypt() * @see self::decrypt() * @var string - * @access private */ - var $orig_key; - - /** - * Don't truncate / null pad key - * - * @see \phpseclib\Crypt\Base::_clearBuffers() - * @var bool - * @access private - */ - var $skip_key_adjustment = true; + private $orig_key; /** * Key Length (in bytes) * - * @see \phpseclib\Crypt\RC2::setKeyLength() + * @see \phpseclib3\Crypt\RC2::setKeyLength() * @var int - * @access private */ - var $key_length = 16; // = 128 bits + protected $key_length = 16; // = 128 bits /** * The mcrypt specific name of the cipher * - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt * @var string - * @access private */ - var $cipher_name_mcrypt = 'rc2'; + protected $cipher_name_mcrypt = 'rc2'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib\Crypt\Base::cfb_init_len + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len * @var int - * @access private */ - var $cfb_init_len = 500; + protected $cfb_init_len = 500; /** * The key length in bits. * + * {@internal Should be in range [1..1024].} + * + * {@internal Changing this value after setting the key has no effect.} + * * @see self::setKeyLength() * @see self::setKey() * @var int - * @access private - * @internal Should be in range [1..1024]. - * @internal Changing this value after setting the key has no effect. */ - var $default_key_length = 1024; + private $default_key_length = 1024; /** * The key length in bits. * + * {@internal Should be in range [1..1024].} + * * @see self::isValidEnine() * @see self::setKey() * @var int - * @access private - * @internal Should be in range [1..1024]. */ - var $current_key_length; + private $current_key_length; /** * The Key Schedule * - * @see self::_setupKey() + * @see self::setupKey() * @var array - * @access private */ - var $keys; + private $keys; /** * Key expansion randomization table. @@ -148,9 +132,8 @@ class RC2 extends Base * * @see self::setKey() * @var array - * @access private */ - var $pitable = array( + private static $pitable = [ 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, @@ -215,16 +198,15 @@ class RC2 extends Base 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD - ); + ]; /** * Inverse key expansion randomization table. * * @see self::setKey() * @var array - * @access private */ - var $invpitable = array( + private static $invpitable = [ 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66, 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4, 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20, @@ -257,30 +239,50 @@ class RC2 extends Base 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75, 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87, 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 - ); + ]; + + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * - * @see \phpseclib\Crypt\Base::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @param int $engine - * @access public * @return bool */ - function isValidEngine($engine) + protected function isValidEngineHelper($engine) { switch ($engine) { case self::ENGINE_OPENSSL: if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { return false; } + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } $this->cipher_name_openssl_ecb = 'rc2-ecb'; - $this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode(); + $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode(); } - return parent::isValidEngine($engine); + return parent::isValidEngineHelper($engine); } /** @@ -288,32 +290,27 @@ class RC2 extends Base * * Valid key lengths are 8 to 1024. * Calling this function after setting the key has no effect until the next - * \phpseclib\Crypt\RC2::setKey() call. + * \phpseclib3\Crypt\RC2::setKey() call. * - * @access public * @param int $length in bits + * @throws \LengthException if the key length isn't supported */ - function setKeyLength($length) + public function setKeyLength($length) { - if ($length < 8) { - $this->default_key_length = 1; - } elseif ($length > 1024) { - $this->default_key_length = 128; - } else { - $this->default_key_length = $length; + if ($length < 8 || $length > 1024) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); } - $this->current_key_length = $this->default_key_length; - parent::setKeyLength($length); + $this->default_key_length = $this->current_key_length = $length; + $this->explicit_key_length = $length >> 3; } /** * Returns the current key length * - * @access public * @return int */ - function getKeyLength() + public function getKeyLength() { return $this->current_key_length; } @@ -326,26 +323,28 @@ class RC2 extends Base * has more then 128 bytes in it, and set $key to a single null byte if * it is empty. * - * If the key is not explicitly set, it'll be assumed to be a single - * null byte. - * - * @see \phpseclib\Crypt\Base::setKey() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() * @param string $key - * @param int $t1 optional Effective key length in bits. + * @param int|boolean $t1 optional Effective key length in bits. + * @throws \LengthException if the key length isn't supported */ - function setKey($key, $t1 = 0) + public function setKey($key, $t1 = false) { $this->orig_key = $key; - if ($t1 <= 0) { + if ($t1 === false) { $t1 = $this->default_key_length; - } elseif ($t1 > 1024) { - $t1 = 1024; } + + if ($t1 < 1 || $t1 > 1024) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); + } + $this->current_key_length = $t1; - // Key byte count should be 1..128. - $key = strlen($key) ? substr($key, 0, 128) : "\x00"; + if (strlen($key) < 1 || strlen($key) > 128) { + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); + } + $t = strlen($key); // The mcrypt RC2 implementation only supports effective key length @@ -360,7 +359,7 @@ class RC2 extends Base $tm = 0xFF >> (8 * $t8 - $t1); // Expand key. - $pitable = $this->pitable; + $pitable = self::$pitable; for ($i = $t; $i < 128; $i++) { $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]]; } @@ -371,23 +370,25 @@ class RC2 extends Base } // Prepare the key for mcrypt. - $l[0] = $this->invpitable[$l[0]]; + $l[0] = self::$invpitable[$l[0]]; array_unshift($l, 'C*'); - parent::setKey(call_user_func_array('pack', $l)); + $this->key = pack(...$l); + $this->key_length = strlen($this->key); + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); } /** * Encrypts a message. * - * Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code + * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code * * @see self::decrypt() - * @access public * @param string $plaintext * @return string $ciphertext */ - function encrypt($plaintext) + public function encrypt($plaintext) { if ($this->engine == self::ENGINE_OPENSSL) { $temp = $this->key; @@ -403,14 +404,13 @@ class RC2 extends Base /** * Decrypts a message. * - * Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code + * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code * * @see self::encrypt() - * @access public * @param string $ciphertext * @return string $plaintext */ - function decrypt($ciphertext) + public function decrypt($ciphertext) { if ($this->engine == self::ENGINE_OPENSSL) { $temp = $this->key; @@ -426,18 +426,17 @@ class RC2 extends Base /** * Encrypts a block * - * @see \phpseclib\Crypt\Base::_encryptBlock() - * @see \phpseclib\Crypt\Base::encrypt() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @param string $in * @return string */ - function _encryptBlock($in) + protected function encryptBlock($in) { list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); $keys = $this->keys; $limit = 20; - $actions = array($limit => 44, 44 => 64); + $actions = [$limit => 44, 44 => 64]; $j = 0; for (;;) { @@ -471,18 +470,17 @@ class RC2 extends Base /** * Decrypts a block * - * @see \phpseclib\Crypt\Base::_decryptBlock() - * @see \phpseclib\Crypt\Base::decrypt() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() * @param string $in * @return string */ - function _decryptBlock($in) + protected function decryptBlock($in) { list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); $keys = $this->keys; $limit = 44; - $actions = array($limit => 20, 20 => 0); + $actions = [$limit => 20, 20 => 0]; $j = 64; for (;;) { @@ -513,37 +511,21 @@ class RC2 extends Base return pack('vvvv', $r0, $r1, $r2, $r3); } - /** - * Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine - * - * @see \phpseclib\Crypt\Base::_setupMcrypt() - * @access private - */ - function _setupMcrypt() - { - if (!isset($this->key)) { - $this->setKey(''); - } - - parent::_setupMcrypt(); - } - /** * Creates the key schedule * - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() */ - function _setupKey() + protected function setupKey() { if (!isset($this->key)) { $this->setKey(''); } - // Key has already been expanded in \phpseclib\Crypt\RC2::setKey(): + // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey(): // Only the first value must be altered. $l = unpack('Ca/Cb/v*', $this->key); - array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8)); + array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8)); unset($l['a']); unset($l['b']); $this->keys = $l; @@ -552,137 +534,107 @@ class RC2 extends Base /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib\Crypt\Base::_setupInlineCrypt() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() */ - function _setupInlineCrypt() + protected function setupInlineCrypt() { - $lambda_functions =& self::_getLambdaFunctions(); + // Init code for both, encrypt and decrypt. + $init_crypt = '$keys = $this->keys;'; - // The first 10 generated $lambda_functions will use the $keys hardcoded as integers - // for the mixing rounds, for better inline crypt performance [~20% faster]. - // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10. - // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit) - $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); + $keys = $this->keys; - // Generation of a unique hash for our generated code - $code_hash = "Crypt_RC2, {$this->mode}"; - if ($gen_hi_opt_code) { - $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); - } + // $in is the current 8 bytes block which has to be en/decrypt + $encrypt_block = $decrypt_block = ' + $in = unpack("v4", $in); + $r0 = $in[1]; + $r1 = $in[2]; + $r2 = $in[3]; + $r3 = $in[4]; + '; - // Is there a re-usable $lambda_functions in there? - // If not, we have to create it. - if (!isset($lambda_functions[$code_hash])) { - // Init code for both, encrypt and decrypt. - $init_crypt = '$keys = $self->keys;'; + // Create code for encryption. + $limit = 20; + $actions = [$limit => 44, 44 => 64]; + $j = 0; - switch (true) { - case $gen_hi_opt_code: - $keys = $this->keys; - default: - $keys = array(); - foreach ($this->keys as $k => $v) { - $keys[$k] = '$keys[' . $k . ']'; - } - } + for (;;) { + // Mixing round. + $encrypt_block .= ' + $r0 = (($r0 + ' . $keys[$j++] . ' + + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; + $r0 |= $r0 >> 16; + $r1 = (($r1 + ' . $keys[$j++] . ' + + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; + $r1 |= $r1 >> 16; + $r2 = (($r2 + ' . $keys[$j++] . ' + + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; + $r2 |= $r2 >> 16; + $r3 = (($r3 + ' . $keys[$j++] . ' + + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; + $r3 |= $r3 >> 16;'; - // $in is the current 8 bytes block which has to be en/decrypt - $encrypt_block = $decrypt_block = ' - $in = unpack("v4", $in); - $r0 = $in[1]; - $r1 = $in[2]; - $r2 = $in[3]; - $r3 = $in[4]; - '; + if ($j === $limit) { + if ($limit === 64) { + break; + } - // Create code for encryption. - $limit = 20; - $actions = array($limit => 44, 44 => 64); - $j = 0; - - for (;;) { - // Mixing round. + // Mashing round. $encrypt_block .= ' - $r0 = (($r0 + ' . $keys[$j++] . ' + - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; - $r0 |= $r0 >> 16; - $r1 = (($r1 + ' . $keys[$j++] . ' + - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; - $r1 |= $r1 >> 16; - $r2 = (($r2 + ' . $keys[$j++] . ' + - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; - $r2 |= $r2 >> 16; - $r3 = (($r3 + ' . $keys[$j++] . ' + - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; - $r3 |= $r3 >> 16;'; - - if ($j === $limit) { - if ($limit === 64) { - break; - } - - // Mashing round. - $encrypt_block .= ' - $r0 += $keys[$r3 & 0x3F]; - $r1 += $keys[$r0 & 0x3F]; - $r2 += $keys[$r1 & 0x3F]; - $r3 += $keys[$r2 & 0x3F];'; - $limit = $actions[$limit]; - } + $r0 += $keys[$r3 & 0x3F]; + $r1 += $keys[$r0 & 0x3F]; + $r2 += $keys[$r1 & 0x3F]; + $r3 += $keys[$r2 & 0x3F];'; + $limit = $actions[$limit]; } - - $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; - - // Create code for decryption. - $limit = 44; - $actions = array($limit => 20, 20 => 0); - $j = 64; - - for (;;) { - // R-mixing round. - $decrypt_block .= ' - $r3 = ($r3 | ($r3 << 16)) >> 5; - $r3 = ($r3 - ' . $keys[--$j] . ' - - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; - $r2 = ($r2 | ($r2 << 16)) >> 3; - $r2 = ($r2 - ' . $keys[--$j] . ' - - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; - $r1 = ($r1 | ($r1 << 16)) >> 2; - $r1 = ($r1 - ' . $keys[--$j] . ' - - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; - $r0 = ($r0 | ($r0 << 16)) >> 1; - $r0 = ($r0 - ' . $keys[--$j] . ' - - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; - - if ($j === $limit) { - if ($limit === 0) { - break; - } - - // R-mashing round. - $decrypt_block .= ' - $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; - $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; - $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; - $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; - $limit = $actions[$limit]; - } - } - - $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; - - // Creates the inline-crypt function - $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( - array( - 'init_crypt' => $init_crypt, - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ) - ); } - // Set the inline-crypt function as callback in: $this->inline_crypt - $this->inline_crypt = $lambda_functions[$code_hash]; + $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Create code for decryption. + $limit = 44; + $actions = [$limit => 20, 20 => 0]; + $j = 64; + + for (;;) { + // R-mixing round. + $decrypt_block .= ' + $r3 = ($r3 | ($r3 << 16)) >> 5; + $r3 = ($r3 - ' . $keys[--$j] . ' - + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; + $r2 = ($r2 | ($r2 << 16)) >> 3; + $r2 = ($r2 - ' . $keys[--$j] . ' - + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; + $r1 = ($r1 | ($r1 << 16)) >> 2; + $r1 = ($r1 - ' . $keys[--$j] . ' - + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; + $r0 = ($r0 | ($r0 << 16)) >> 1; + $r0 = ($r0 - ' . $keys[--$j] . ' - + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; + + if ($j === $limit) { + if ($limit === 0) { + break; + } + + // R-mashing round. + $decrypt_block .= ' + $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; + $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; + $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; + $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; + $limit = $actions[$limit]; + } + } + + $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Creates the inline-crypt function + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); } } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php similarity index 50% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php index 25e4ff854..5f3bff2c0 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php @@ -20,7 +20,7 @@ * setKey('abcdefgh'); * @@ -34,160 +34,90 @@ * ?> * * - * @category Crypt - * @package RC4 * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\StreamCipher; /** * Pure-PHP implementation of RC4. * - * @package RC4 * @author Jim Wigginton - * @access public */ -class RC4 extends Base +class RC4 extends StreamCipher { - /**#@+ - * @access private - * @see \phpseclib\Crypt\RC4::_crypt() - */ + /** + * @see \phpseclib3\Crypt\RC4::_crypt() + */ const ENCRYPT = 0; - const DECRYPT = 1; - /**#@-*/ /** - * Block Length of the cipher - * - * RC4 is a stream cipher - * so we the block_size to 0 - * - * @see \phpseclib\Crypt\Base::block_size - * @var int - * @access private + * @see \phpseclib3\Crypt\RC4::_crypt() */ - var $block_size = 0; + const DECRYPT = 1; /** * Key Length (in bytes) * - * @see \phpseclib\Crypt\RC4::setKeyLength() + * @see \phpseclib3\Crypt\RC4::setKeyLength() * @var int - * @access private */ - var $key_length = 128; // = 1024 bits + protected $key_length = 128; // = 1024 bits /** * The mcrypt specific name of the cipher * - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt * @var string - * @access private */ - var $cipher_name_mcrypt = 'arcfour'; - - /** - * Holds whether performance-optimized $inline_crypt() can/should be used. - * - * @see \phpseclib\Crypt\Base::inline_crypt - * @var mixed - * @access private - */ - var $use_inline_crypt = false; // currently not available + protected $cipher_name_mcrypt = 'arcfour'; /** * The Key * * @see self::setKey() * @var string - * @access private */ - var $key; + protected $key; /** * The Key Stream for decryption and encryption * * @see self::setKey() * @var array - * @access private */ - var $stream; - - /** - * Default Constructor. - * - * Determines whether or not the mcrypt extension should be used. - * - * @see \phpseclib\Crypt\Base::__construct() - * @return \phpseclib\Crypt\RC4 - * @access public - */ - function __construct() - { - parent::__construct(Base::MODE_STREAM); - } + private $stream; /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * - * @see \phpseclib\Crypt\Base::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @param int $engine - * @access public * @return bool */ - function isValidEngine($engine) + protected function isValidEngineHelper($engine) { - if ($engine == Base::ENGINE_OPENSSL) { - if (version_compare(PHP_VERSION, '5.3.7') >= 0) { - $this->cipher_name_openssl = 'rc4-40'; - } else { - switch (strlen($this->key)) { - case 5: - $this->cipher_name_openssl = 'rc4-40'; - break; - case 8: - $this->cipher_name_openssl = 'rc4-64'; - break; - case 16: - $this->cipher_name_openssl = 'rc4'; - break; - default: - return false; - } + if ($engine == self::ENGINE_OPENSSL) { + if ($this->continuousBuffer) { + return false; } + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } + $this->cipher_name_openssl = 'rc4-40'; } - return parent::isValidEngine($engine); - } - - /** - * Dummy function. - * - * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1]. - * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before - * calling setKey(). - * - * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol, - * the IV's are relatively easy to predict, an attack described by - * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir} - * can be used to quickly guess at the rest of the key. The following links elaborate: - * - * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009} - * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack} - * - * @param string $iv - * @see self::setKey() - * @access public - */ - function setIV($iv) - { + return parent::isValidEngineHelper($engine); } /** @@ -195,37 +125,51 @@ class RC4 extends Base * * Keys can be between 1 and 256 bytes long. * - * @access public * @param int $length + * @throws \LengthException if the key length is invalid */ - function setKeyLength($length) + public function setKeyLength($length) { - if ($length < 8) { - $this->key_length = 1; - } elseif ($length > 2048) { - $this->key_length = 256; - } else { - $this->key_length = $length >> 3; + if ($length < 8 || $length > 2048) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); } + $this->key_length = $length >> 3; + parent::setKeyLength($length); } + /** + * Sets the key length + * + * Keys can be between 1 and 256 bytes long. + * + * @param string $key + */ + public function setKey($key) + { + $length = strlen($key); + if ($length < 1 || $length > 256) { + throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); + } + + parent::setKey($key); + } + /** * Encrypts a message. * - * @see \phpseclib\Crypt\Base::decrypt() - * @see self::_crypt() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() * @param string $plaintext * @return string $ciphertext */ - function encrypt($plaintext) + public function encrypt($plaintext) { - if ($this->engine != Base::ENGINE_INTERNAL) { + if ($this->engine != self::ENGINE_INTERNAL) { return parent::encrypt($plaintext); } - return $this->_crypt($plaintext, self::ENCRYPT); + return $this->crypt($plaintext, self::ENCRYPT); } /** @@ -234,27 +178,25 @@ class RC4 extends Base * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). * At least if the continuous buffer is disabled. * - * @see \phpseclib\Crypt\Base::encrypt() - * @see self::_crypt() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() * @param string $ciphertext * @return string $plaintext */ - function decrypt($ciphertext) + public function decrypt($ciphertext) { - if ($this->engine != Base::ENGINE_INTERNAL) { + if ($this->engine != self::ENGINE_INTERNAL) { return parent::decrypt($ciphertext); } - return $this->_crypt($ciphertext, self::DECRYPT); + return $this->crypt($ciphertext, self::DECRYPT); } /** * Encrypts a block * - * @access private * @param string $in */ - function _encryptBlock($in) + protected function encryptBlock($in) { // RC4 does not utilize this method } @@ -262,10 +204,9 @@ class RC4 extends Base /** * Decrypts a block * - * @access private * @param string $in */ - function _decryptBlock($in) + protected function decryptBlock($in) { // RC4 does not utilize this method } @@ -273,10 +214,9 @@ class RC4 extends Base /** * Setup the key (expansion) * - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() */ - function _setupKey() + protected function setupKey() { $key = $this->key; $keyLength = strlen($key); @@ -289,12 +229,12 @@ class RC4 extends Base $keyStream[$j] = $temp; } - $this->stream = array(); - $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array( + $this->stream = []; + $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = [ 0, // index $i 0, // index $j $keyStream - ); + ]; } /** @@ -302,16 +242,14 @@ class RC4 extends Base * * @see self::encrypt() * @see self::decrypt() - * @access private * @param string $text * @param int $mode * @return string $text */ - function _crypt($text, $mode) + private function crypt($text, $mode) { if ($this->changed) { - $this->_setup(); - $this->changed = false; + $this->setup(); } $stream = &$this->stream[$mode]; diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php new file mode 100644 index 000000000..135719979 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -0,0 +1,933 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $ciphertext = $public->encrypt($plaintext); + * + * echo $private->decrypt($ciphertext); + * ?> + * + * + * Here's an example of how to create signatures and verify signatures with this library: + * + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * One thing to consider when using this: so phpseclib uses PSS mode by default. + * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So + * should phpseclib save to the id-RSASSA-PSS format by default or the + * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better + * because SSH doesn't use PSS and idk how many SSH servers would be able to + * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS + * format is used by default (unless you change it up to use PKCS1 instead) + * + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Crypt\RSA\PrivateKey; +use phpseclib3\Crypt\RSA\PublicKey; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP PKCS#1 compliant implementation of RSA. + * + * @author Jim Wigginton + */ +abstract class RSA extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'RSA'; + + /** + * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} + * (OAEP) for encryption / decryption. + * + * Uses sha256 by default + * + * @see self::setHash() + * @see self::setMGFHash() + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_OAEP = 1; + + /** + * Use PKCS#1 padding. + * + * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards + * compatibility with protocols (like SSH-1) written before OAEP's introduction. + * + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_PKCS1 = 2; + + /** + * Do not use any padding + * + * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy + * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. + * + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_NONE = 4; + + /** + * Use the Probabilistic Signature Scheme for signing + * + * Uses sha256 and 0 as the salt length + * + * @see self::setSaltLength() + * @see self::setMGFHash() + * @see self::setHash() + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_PSS = 16; + + /** + * Use a relaxed version of PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_RELAXED_PKCS1 = 32; + + /** + * Use PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_PKCS1 = 64; + + /** + * Encryption padding mode + * + * @var int + */ + protected $encryptionPadding = self::ENCRYPTION_OAEP; + + /** + * Signature padding mode + * + * @var int + */ + protected $signaturePadding = self::SIGNATURE_PSS; + + /** + * Length of hash function output + * + * @var int + */ + protected $hLen; + + /** + * Length of salt + * + * @var int + */ + protected $sLen; + + /** + * Label + * + * @var string + */ + protected $label = ''; + + /** + * Hash function for the Mask Generation Function + * + * @var \phpseclib3\Crypt\Hash + */ + protected $mgfHash; + + /** + * Length of MGF hash function output + * + * @var int + */ + protected $mgfHLen; + + /** + * Modulus (ie. n) + * + * @var \phpseclib3\Math\BigInteger + */ + protected $modulus; + + /** + * Modulus length + * + * @var \phpseclib3\Math\BigInteger + */ + protected $k; + + /** + * Exponent (ie. e or d) + * + * @var \phpseclib3\Math\BigInteger + */ + protected $exponent; + + /** + * Default public exponent + * + * @var int + * @link http://en.wikipedia.org/wiki/65537_%28number%29 + */ + private static $defaultExponent = 65537; + + /** + * Enable Blinding? + * + * @var bool + */ + protected static $enableBlinding = true; + + /** + * OpenSSL configuration file name. + * + * @see self::createKey() + * @var ?string + */ + protected static $configFile; + + /** + * Smallest Prime + * + * Per , this number ought not result in primes smaller + * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime + * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if + * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is + * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's + * a chance neither gmp nor OpenSSL are installed) + * + * @var int + */ + private static $smallestPrime = 4096; + + /** + * Public Exponent + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicExponent; + + /** + * Sets the public exponent for key generation + * + * This will be 65537 unless changed. + * + * @param int $val + */ + public static function setExponent($val) + { + self::$defaultExponent = $val; + } + + /** + * Sets the smallest prime number in bits. Used for key generation + * + * This will be 4096 unless changed. + * + * @param int $val + */ + public static function setSmallestPrime($val) + { + self::$smallestPrime = $val; + } + + /** + * Sets the OpenSSL config file path + * + * Set to the empty string to use the default config file + * + * @param string $val + */ + public static function setOpenSSLConfigPath($val) + { + self::$configFile = $val; + } + + /** + * Create a private key + * + * The public key can be extracted from the private key + * + * @return RSA\PrivateKey + * @param int $bits + */ + public static function createKey($bits = 2048) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be + if ($regSize > self::$smallestPrime) { + $num_primes = floor($bits / self::$smallestPrime); + $regSize = self::$smallestPrime; + } else { + $num_primes = 2; + } + + if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum + if (self::$engines['OpenSSL']) { + $config = []; + if (self::$configFile) { + $config['config'] = self::$configFile; + } + $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config); + openssl_pkey_export($rsa, $privatekeystr, null, $config); + + // clear the buffer of error strings stemming from a minimalistic openssl.cnf + while (openssl_error_string() !== false) { + } + + return RSA::load($privatekeystr); + } + } + + static $e; + if (!isset($e)) { + $e = new BigInteger(self::$defaultExponent); + } + + $n = clone self::$one; + $exponents = $coefficients = $primes = []; + $lcm = [ + 'top' => clone self::$one, + 'bottom' => false + ]; + + do { + for ($i = 1; $i <= $num_primes; $i++) { + if ($i != $num_primes) { + $primes[$i] = BigInteger::randomPrime($regSize); + } else { + extract(BigInteger::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + list($min) = $min->divide($n); + $min = $min->add(self::$one); + list($max) = $max->divide($n); + $primes[$i] = BigInteger::randomRangePrime($min, $max); + } + + // the first coefficient is calculated differently from the rest + // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) + if ($i > 2) { + $coefficients[$i] = $n->modInverse($primes[$i]); + } + + $n = $n->multiply($primes[$i]); + + $temp = $primes[$i]->subtract(self::$one); + + // textbook RSA implementations use Euler's totient function instead of the least common multiple. + // see http://en.wikipedia.org/wiki/Euler%27s_totient_function + $lcm['top'] = $lcm['top']->multiply($temp); + $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); + } + + list($temp) = $lcm['top']->divide($lcm['bottom']); + $gcd = $temp->gcd($e); + $i0 = 1; + } while (!$gcd->equals(self::$one)); + + $coefficients[2] = $primes[2]->modInverse($primes[1]); + + $d = $e->modInverse($temp); + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $e->modInverse($temp); + } + + // from : + // RSAPrivateKey ::= SEQUENCE { + // version Version, + // modulus INTEGER, -- n + // publicExponent INTEGER, -- e + // privateExponent INTEGER, -- d + // prime1 INTEGER, -- p + // prime2 INTEGER, -- q + // exponent1 INTEGER, -- d mod (p-1) + // exponent2 INTEGER, -- d mod (q-1) + // coefficient INTEGER, -- (inverse of q) mod p + // otherPrimeInfos OtherPrimeInfos OPTIONAL + // } + $privatekey = new PrivateKey(); + $privatekey->modulus = $n; + $privatekey->k = $bits >> 3; + $privatekey->publicExponent = $e; + $privatekey->exponent = $d; + $privatekey->primes = $primes; + $privatekey->exponents = $exponents; + $privatekey->coefficients = $coefficients; + + /* + $publickey = new PublicKey; + $publickey->modulus = $n; + $publickey->k = $bits >> 3; + $publickey->exponent = $e; + $publickey->publicExponent = $e; + $publickey->isPublic = true; + */ + + return $privatekey; + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + $key = $components['isPublicKey'] ? + new PublicKey() : + new PrivateKey(); + + $key->modulus = $components['modulus']; + $key->publicExponent = $components['publicExponent']; + $key->k = $key->modulus->getLengthInBytes(); + + if ($components['isPublicKey'] || !isset($components['privateExponent'])) { + $key->exponent = $key->publicExponent; + } else { + $key->privateExponent = $components['privateExponent']; + $key->exponent = $key->privateExponent; + $key->primes = $components['primes']; + $key->exponents = $components['exponents']; + $key->coefficients = $components['coefficients']; + } + + if ($components['format'] == PSS::class) { + // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is + // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib + // uses PSS padding by default. it assumes the more secure method by default and altho it provides + // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent + // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that + // not only does it defaults to the most secure methods - it doesn't even let you choose less + // secure methods + //$key = $key->withPadding(self::SIGNATURE_PSS); + if (isset($components['hash'])) { + $key = $key->withHash($components['hash']); + } + if (isset($components['MGFHash'])) { + $key = $key->withMGFHash($components['MGFHash']); + } + if (isset($components['saltLength'])) { + $key = $key->withSaltLength($components['saltLength']); + } + } + + return $key; + } + + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$configFile)) { + self::$configFile = dirname(__FILE__) . '/../openssl.cnf'; + } + + parent::initialize_static_variables(); + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + parent::__construct(); + + $this->hLen = $this->hash->getLengthInBytes(); + $this->mgfHash = new Hash('sha256'); + $this->mgfHLen = $this->mgfHash->getLengthInBytes(); + } + + /** + * Integer-to-Octet-String primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. + * + * @param bool|\phpseclib3\Math\BigInteger $x + * @param int $xLen + * @return bool|string + */ + protected function i2osp($x, $xLen) + { + if ($x === false) { + return false; + } + $x = $x->toBytes(); + if (strlen($x) > $xLen) { + throw new \OutOfRangeException('Resultant string length out of range'); + } + return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); + } + + /** + * Octet-String-to-Integer primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. + * + * @param string $x + * @return \phpseclib3\Math\BigInteger + */ + protected function os2ip($x) + { + return new BigInteger($x, 256); + } + + /** + * EMSA-PKCS1-V1_5-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. + * + * @param string $m + * @param int $emLen + * @throws \LengthException if the intended encoded message length is too short + * @return string + */ + protected function emsa_pkcs1_v1_5_encode($m, $emLen) + { + $h = $this->hash->hash($m); + + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'md2': + $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10"; + break; + case 'md5': + $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; + break; + case 'sha1': + $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"; + break; + case 'sha256': + $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; + break; + case 'sha384': + $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"; + break; + case 'sha512': + $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"; + break; + case 'sha512/224': + $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c"; + break; + case 'sha512/256': + $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20"; + } + $t .= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + + /** + * EMSA-PKCS1-V1_5-ENCODE (without NULL) + * + * Quoting https://tools.ietf.org/html/rfc8017#page-65, + * + * "The parameters field associated with id-sha1, id-sha224, id-sha256, + * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should + * generally be omitted, but if present, it shall have a value of type + * NULL" + * + * @param string $m + * @param int $emLen + * @return string + */ + protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen) + { + $h = $this->hash->hash($m); + + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'sha1': + $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14"; + break; + case 'sha256': + $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20"; + break; + case 'sha384': + $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30"; + break; + case 'sha512': + $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c"; + break; + case 'sha512/224': + $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c"; + break; + case 'sha512/256': + $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20"; + break; + default: + throw new UnsupportedAlgorithmException('md2 and md5 require NULLs'); + } + $t .= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + + /** + * MGF1 + * + * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. + * + * @param string $mgfSeed + * @param int $maskLen + * @return string + */ + protected function mgf1($mgfSeed, $maskLen) + { + // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. + + $t = ''; + $count = ceil($maskLen / $this->mgfHLen); + for ($i = 0; $i < $count; $i++) { + $c = pack('N', $i); + $t .= $this->mgfHash->hash($mgfSeed . $c); + } + + return substr($t, 0, $maskLen); + } + + /** + * Returns the key size + * + * More specifically, this returns the size of the modulo in bits. + * + * @return int + */ + public function getLength() + { + return !isset($this->modulus) ? 0 : $this->modulus->getLength(); + } + + /** + * Determines which hashing function should be used + * + * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and + * decryption. + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->hash = new Hash($hash); + break; + default: + throw new UnsupportedAlgorithmException( + 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' + ); + } + $new->hLen = $new->hash->getLengthInBytes(); + + return $new; + } + + /** + * Determines which hashing function should be used for the mask generation function + * + * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's + * best if Hash and MGFHash are set to the same thing this is not a requirement. + * + * @param string $hash + */ + public function withMGFHash($hash) + { + $new = clone $this; + + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->mgfHash = new Hash($hash); + break; + default: + throw new UnsupportedAlgorithmException( + 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' + ); + } + $new->mgfHLen = $new->mgfHash->getLengthInBytes(); + + return $new; + } + + /** + * Returns the MGF hash algorithm currently being used + * + */ + public function getMGFHash() + { + return clone $this->mgfHash; + } + + /** + * Determines the salt length + * + * Used by RSA::PADDING_PSS + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * + * Typical salt lengths in octets are hLen (the length of the output + * of the hash function Hash) and 0. + * + * @param int $sLen + */ + public function withSaltLength($sLen) + { + $new = clone $this; + $new->sLen = $sLen; + return $new; + } + + /** + * Returns the salt length currently being used + * + */ + public function getSaltLength() + { + return $this->sLen !== null ? $this->sLen : $this->hLen; + } + + /** + * Determines the label + * + * Used by RSA::PADDING_OAEP + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: + * + * Both the encryption and the decryption operations of RSAES-OAEP take + * the value of a label L as input. In this version of PKCS #1, L is + * the empty string; other uses of the label are outside the scope of + * this document. + * + * @param string $label + */ + public function withLabel($label) + { + $new = clone $this; + $new->label = $label; + return $new; + } + + /** + * Returns the label currently being used + * + */ + public function getLabel() + { + return $this->label; + } + + /** + * Determines the padding modes + * + * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); + * + * @param int $padding + */ + public function withPadding($padding) + { + $masks = [ + self::ENCRYPTION_OAEP, + self::ENCRYPTION_PKCS1, + self::ENCRYPTION_NONE + ]; + $encryptedCount = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $encryptedCount++; + } + } + if ($encryptedCount > 1) { + throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); + } + $encryptionPadding = $selected; + + $masks = [ + self::SIGNATURE_PSS, + self::SIGNATURE_RELAXED_PKCS1, + self::SIGNATURE_PKCS1 + ]; + $signatureCount = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $signatureCount++; + } + } + if ($signatureCount > 1) { + throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); + } + $signaturePadding = $selected; + + $new = clone $this; + if ($encryptedCount) { + $new->encryptionPadding = $encryptionPadding; + } + if ($signatureCount) { + $new->signaturePadding = $signaturePadding; + } + return $new; + } + + /** + * Returns the padding currently being used + * + */ + public function getPadding() + { + return $this->signaturePadding | $this->encryptionPadding; + } + + /** + * Returns the current engine being used + * + * OpenSSL is only used in this class (and it's subclasses) for key generation + * Even then it depends on the parameters you're using. It's not used for + * multi-prime RSA nor is it used if the key length is outside of the range + * supported by OpenSSL + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ? + 'OpenSSL' : + 'PHP'; + } + + /** + * Enable RSA Blinding + * + */ + public static function enableBlinding() + { + static::$enableBlinding = true; + } + + /** + * Disable RSA Blinding + * + */ + public static function disableBlinding() + { + static::$enableBlinding = false; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php new file mode 100644 index 000000000..87f543de9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php @@ -0,0 +1,142 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * JWK Formatted RSA Handler + * + * @author Jim Wigginton + */ +abstract class JWK extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + if ($key->kty != 'RSA') { + throw new \RuntimeException('Only RSA JWK keys are supported'); + } + + $count = $publicCount = 0; + $vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']; + foreach ($vars as $var) { + if (!isset($key->$var) || !is_string($key->$var)) { + continue; + } + $count++; + $value = new BigInteger(Strings::base64url_decode($key->$var), 256); + switch ($var) { + case 'n': + $publicCount++; + $components['modulus'] = $value; + break; + case 'e': + $publicCount++; + $components['publicExponent'] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'qi': + $components['coefficients'][2] = $value; + } + } + + if ($count == count($vars)) { + return $components + ['isPublicKey' => false]; + } + + if ($count == 2 && $publicCount == 2) { + return $components + ['isPublicKey' => true]; + } + + throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys'); + } + + $key = [ + 'kty' => 'RSA', + 'n' => Strings::base64url_encode($n->toBytes()), + 'e' => Strings::base64url_encode($e->toBytes()), + 'd' => Strings::base64url_encode($d->toBytes()), + 'p' => Strings::base64url_encode($primes[1]->toBytes()), + 'q' => Strings::base64url_encode($primes[2]->toBytes()), + 'dp' => Strings::base64url_encode($exponents[1]->toBytes()), + 'dq' => Strings::base64url_encode($exponents[2]->toBytes()), + 'qi' => Strings::base64url_encode($coefficients[2]->toBytes()) + ]; + + return self::wrapKey($key, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $key = [ + 'kty' => 'RSA', + 'n' => Strings::base64url_encode($n->toBytes()), + 'e' => Strings::base64url_encode($e->toBytes()) + ]; + + return self::wrapKey($key, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php new file mode 100644 index 000000000..e9a0c4f3c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php @@ -0,0 +1,228 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Microsoft BLOB Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class MSBLOB +{ + /** + * Public/Private Key Pair + * + */ + const PRIVATEKEYBLOB = 0x7; + /** + * Public Key + * + */ + const PUBLICKEYBLOB = 0x6; + /** + * Public Key + * + */ + const PUBLICKEYBLOBEX = 0xA; + /** + * RSA public key exchange algorithm + * + */ + const CALG_RSA_KEYX = 0x0000A400; + /** + * RSA public key exchange algorithm + * + */ + const CALG_RSA_SIGN = 0x00002400; + /** + * Public Key + * + */ + const RSA1 = 0x31415352; + /** + * Private Key + * + */ + const RSA2 = 0x32415352; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $key = Strings::base64_decode($key); + + if (!is_string($key)) { + throw new \UnexpectedValueException('Base64 decoding produced an error'); + } + if (strlen($key) < 20) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + // PUBLICKEYSTRUC publickeystruc + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx + extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8))); + /** + * @var string $type + * @var string $version + * @var integer $reserved + * @var integer $algo + */ + switch (ord($type)) { + case self::PUBLICKEYBLOB: + case self::PUBLICKEYBLOBEX: + $publickey = true; + break; + case self::PRIVATEKEYBLOB: + $publickey = false; + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $components = ['isPublicKey' => $publickey]; + + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx + switch ($algo) { + case self::CALG_RSA_KEYX: + case self::CALG_RSA_SIGN: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + // RSAPUBKEY rsapubkey + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx + // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit + extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12))); + /** + * @var integer $magic + * @var integer $bitlen + * @var string $pubexp + */ + switch ($magic) { + case self::RSA2: + $components['isPublicKey'] = false; + // fall-through + case self::RSA1: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $baseLength = $bitlen / 16; + if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); + // BYTE modulus[rsapubkey.bitlen/8] + $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); + + if ($publickey) { + return $components; + } + + $components['isPublicKey'] = false; + + // BYTE prime1[rsapubkey.bitlen/16] + $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE prime2[rsapubkey.bitlen/16] + $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); + // BYTE exponent1[rsapubkey.bitlen/16] + $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE exponent2[rsapubkey.bitlen/16] + $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); + // BYTE coefficient[rsapubkey.bitlen/16] + $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + if (isset($components['privateExponent'])) { + $components['publicExponent'] = $components['privateExponent']; + } + // BYTE privateExponent[rsapubkey.bitlen/8] + $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); + } + + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('MSBLOB private keys do not support encryption'); + } + + $n = strrev($n->toBytes()); + $e = str_pad(strrev($e->toBytes()), 4, "\0"); + $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); + $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e); + $key .= $n; + $key .= strrev($primes[1]->toBytes()); + $key .= strrev($primes[2]->toBytes()); + $key .= strrev($exponents[1]->toBytes()); + $key .= strrev($exponents[2]->toBytes()); + $key .= strrev($coefficients[2]->toBytes()); + $key .= strrev($d->toBytes()); + + return Strings::base64_encode($key); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + $n = strrev($n->toBytes()); + $e = str_pad(strrev($e->toBytes()), 4, "\0"); + $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); + $key .= pack('VVa*', self::RSA1, 8 * strlen($n), $e); + $key .= $n; + + return Strings::base64_encode($key); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php new file mode 100644 index 000000000..2367810a7 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,132 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSH Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends Progenitor +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-rsa']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + + $primes = $coefficients = []; + + list( + $modulus, + $publicExponent, + $privateExponent, + $coefficients[2], + $primes[1], + $primes[2], + $comment, + ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']); + + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + + $isPublicKey = false; + + return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + + list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']); + + return [ + 'isPublicKey' => true, + 'modulus' => $modulus, + 'publicExponent' => $publicExponent, + 'comment' => $parsed['comment'] + ]; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $RSAPublicKey; + } + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment; + + return $RSAPublicKey; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($n, $e, ['binary' => true]); + $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php new file mode 100644 index 000000000..276c6024f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php @@ -0,0 +1,160 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#1 Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'PUBLIC') !== false) { + $components = ['isPublicKey' => true]; + } elseif (strpos($key, 'PRIVATE') !== false) { + $components = ['isPublicKey' => false]; + } else { + $components = []; + } + + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); + if (is_array($key)) { + $components += [ + 'modulus' => $key['modulus'], + 'publicExponent' => $key['publicExponent'], + 'privateExponent' => $key['privateExponent'], + 'primes' => [1 => $key['prime1'], $key['prime2']], + 'exponents' => [1 => $key['exponent1'], $key['exponent2']], + 'coefficients' => [2 => $key['coefficient']] + ]; + if ($key['version'] == 'multi') { + foreach ($key['otherPrimeInfos'] as $primeInfo) { + $components['primes'][] = $primeInfo['prime']; + $components['exponents'][] = $primeInfo['exponent']; + $components['coefficients'][] = $primeInfo['coefficient']; + } + } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = false; + } + return $components; + } + + $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); + + if (!is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = true; + } + + return $components + $key; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $num_primes = count($primes); + $key = [ + 'version' => $num_primes == 2 ? 'two-prime' : 'multi', + 'modulus' => $n, + 'publicExponent' => $e, + 'privateExponent' => $d, + 'prime1' => $primes[1], + 'prime2' => $primes[2], + 'exponent1' => $exponents[1], + 'exponent2' => $exponents[2], + 'coefficient' => $coefficients[2] + ]; + for ($i = 3; $i <= $num_primes; $i++) { + $key['otherPrimeInfos'][] = [ + 'prime' => $primes[$i], + 'exponent' => $exponents[$i], + 'coefficient' => $coefficients[$i] + ]; + } + + $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'RSA', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + $key = [ + 'modulus' => $n, + 'publicExponent' => $e + ]; + + $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP); + + return self::wrapPublicKey($key, 'RSA'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php new file mode 100644 index 000000000..1eaac6ef8 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php @@ -0,0 +1,122 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'rsaEncryption'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.1.1'; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + if (isset($key['privateKey'])) { + $components['isPublicKey'] = false; + $type = 'private'; + } else { + $components['isPublicKey'] = true; + $type = 'public'; + } + + $result = $components + PKCS1::load($key[$type . 'Key']); + + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + + return $result; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = ASN1::extractBER($key); + return self::wrapPrivateKey($key, [], null, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $key = PKCS1::savePublicKey($n, $e); + $key = ASN1::extractBER($key); + return self::wrapPublicKey($key, null); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php new file mode 100644 index 000000000..ed75b9b7a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php @@ -0,0 +1,238 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted RSA-PSS Key Handler + * + * @author Jim Wigginton + */ +abstract class PSS extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'id-RSASSA-PSS'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.1.10'; + + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = false; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!self::$oidsLoaded) { + ASN1::loadOIDs([ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + + 'id-mgf1' => '1.2.840.113549.1.1.8' + ]); + self::$oidsLoaded = true; + } + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'private' : 'public'; + + $result = $components + PKCS1::load($key[$type . 'Key']); + + if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { + $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); + if ($decoded === false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); + } else { + $params = []; + } + + if (isset($params['maskGenAlgorithm']['parameters'])) { + $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); + if ($decoded === false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); + } else { + $params['maskGenAlgorithm'] = [ + 'algorithm' => 'id-mgf1', + 'parameters' => ['algorithm' => 'id-sha1'] + ]; + } + + if (!isset($params['hashAlgorithm']['algorithm'])) { + $params['hashAlgorithm']['algorithm'] = 'id-sha1'; + } + + $result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']); + $result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); + if (isset($params['saltLength'])) { + $result['saltLength'] = (int) $params['saltLength']->toString(); + } + + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + + return $result; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + self::initialize_static_variables(); + + $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + self::initialize_static_variables(); + + $key = PKCS1::savePublicKey($n, $e); + $key = ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPublicKey($key, $params); + } + + /** + * Encodes PSS parameters + * + * @param array $options + * @return string + */ + public static function savePSSParams(array $options) + { + /* + The trailerField field is an integer. It provides + compatibility with IEEE Std 1363a-2004 [P1363A]. The value + MUST be 1, which represents the trailer field with hexadecimal + value 0xBC. Other trailer fields, including the trailer field + composed of HashID concatenated with 0xCC that is specified in + IEEE Std 1363a, are not supported. Implementations that + perform signature generation MUST omit the trailerField field, + indicating that the default trailer field value was used. + Implementations that perform signature validation MUST + recognize both a present trailerField field with value 1 and an + absent trailerField field. + + source: https://tools.ietf.org/html/rfc4055#page-9 + */ + $params = [ + 'trailerField' => new BigInteger(1) + ]; + if (isset($options['hash'])) { + $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; + } + if (isset($options['MGFHash'])) { + $temp = ['algorithm' => 'id-' . $options['MGFHash']]; + $temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP); + $params['maskGenAlgorithm'] = [ + 'algorithm' => 'id-mgf1', + 'parameters' => new ASN1\Element($temp) + ]; + } + if (isset($options['saltLength'])) { + $params['saltLength'] = new BigInteger($options['saltLength']); + } + + return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php new file mode 100644 index 000000000..fe35717bb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php @@ -0,0 +1,121 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * PuTTY Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends Progenitor +{ + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH'; + + /** + * Algorithm Identifier + * + * @var array + */ + protected static $types = ['ssh-rsa']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + extract($components); + unset($components['public'], $components['private']); + + $isPublicKey = false; + + $result = Strings::unpackSSH2('ii', $public); + if ($result === false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + list($publicExponent, $modulus) = $result; + + $result = Strings::unpackSSH2('iiii', $private); + if ($result === false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $primes = $coefficients = []; + list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; + + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + + return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); + } + + $public = Strings::packSSH2('ii', $e, $n); + $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); + + return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php new file mode 100644 index 000000000..db7287840 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php @@ -0,0 +1,184 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); + } + + $key = array_change_key_case($key, CASE_LOWER); + + $components = ['isPublicKey' => false]; + + foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) { + if (isset($key[$index])) { + $components['publicExponent'] = $key[$index]; + break; + } + } + + foreach (['n', 'modulo', 'modulus', 1] as $index) { + if (isset($key[$index])) { + $components['modulus'] = $key[$index]; + break; + } + } + + if (!isset($components['publicExponent']) || !isset($components['modulus'])) { + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + + if (isset($key['primes'])) { + $components['primes'] = $key['primes']; + } elseif (isset($key['p']) && isset($key['q'])) { + $indices = [ + ['p', 'q'], + ['prime1', 'prime2'] + ]; + foreach ($indices as $index) { + list($i0, $i1) = $index; + if (isset($key[$i0]) && isset($key[$i1])) { + $components['primes'] = [1 => $key[$i0], $key[$i1]]; + } + } + } + + if (isset($key['exponents'])) { + $components['exponents'] = $key['exponents']; + } else { + $indices = [ + ['dp', 'dq'], + ['exponent1', 'exponent2'] + ]; + foreach ($indices as $index) { + list($i0, $i1) = $index; + if (isset($key[$i0]) && isset($key[$i1])) { + $components['exponents'] = [1 => $key[$i0], $key[$i1]]; + } + } + } + + if (isset($key['coefficients'])) { + $components['coefficients'] = $key['coefficients']; + } else { + foreach (['inverseq', 'q\'', 'coefficient'] as $index) { + if (isset($key[$index])) { + $components['coefficients'] = [2 => $key[$index]]; + } + } + } + + if (!isset($components['primes'])) { + $components['isPublicKey'] = true; + return $components; + } + + if (!isset($components['exponents'])) { + $one = new BigInteger(1); + $temp = $components['primes'][1]->subtract($one); + $exponents = [1 => $components['publicExponent']->modInverse($temp)]; + $temp = $components['primes'][2]->subtract($one); + $exponents[] = $components['publicExponent']->modInverse($temp); + $components['exponents'] = $exponents; + } + + if (!isset($components['coefficients'])) { + $components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])]; + } + + foreach (['privateexponent', 'd'] as $index) { + if (isset($key[$index])) { + $components['privateExponent'] = $key[$index]; + break; + } + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return array + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('Raw private keys do not support encryption'); + } + + return [ + 'e' => clone $e, + 'n' => clone $n, + 'd' => clone $d, + 'primes' => array_map(function ($var) { + return clone $var; + }, $primes), + 'exponents' => array_map(function ($var) { + return clone $var; + }, $exponents), + 'coefficients' => array_map(function ($var) { + return clone $var; + }, $coefficients) + ]; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return array + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return ['e' => clone $e, 'n' => clone $n]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php new file mode 100644 index 000000000..280048cc0 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php @@ -0,0 +1,171 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * XML Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (!class_exists('DOMDocument')) { + throw new BadConfigurationException('The dom extension is not setup correctly on this system'); + } + + $components = [ + 'isPublicKey' => false, + 'primes' => [], + 'exponents' => [], + 'coefficients' => [] + ]; + + $use_errors = libxml_use_internal_errors(true); + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); + if (!$temp->length) { + continue; + } + $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'modulus': + $components['modulus'] = $value; + break; + case 'exponent': + $components['publicExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'inverseq': + $components['coefficients'][2] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + } + } + + libxml_use_internal_errors($use_errors); + + foreach ($components as $key => $value) { + if (is_array($value) && !count($value)) { + unset($components[$key]); + } + } + + if (isset($components['modulus']) && isset($components['publicExponent'])) { + if (count($components) == 3) { + $components['isPublicKey'] = true; + } + return $components; + } + + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); + } + + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('XML private keys do not support encryption'); + } + + return "\r\n" . + ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . + '

' . Strings::base64_encode($primes[1]->toBytes()) . "

\r\n" . + ' ' . Strings::base64_encode($primes[2]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($exponents[1]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($exponents[2]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($coefficients[2]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($d->toBytes()) . "\r\n" . + '
'; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return "\r\n" . + ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . + ''; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php new file mode 100644 index 000000000..37dd09a45 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php @@ -0,0 +1,530 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +final class PrivateKey extends RSA implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * Primes for Chinese Remainder Theorem (ie. p and q) + * + * @var array + */ + protected $primes; + + /** + * Exponents for Chinese Remainder Theorem (ie. dP and dQ) + * + * @var array + */ + protected $exponents; + + /** + * Coefficients for Chinese Remainder Theorem (ie. qInv) + * + * @var array + */ + protected $coefficients; + + /** + * Private Exponent + * + * @var \phpseclib3\Math\BigInteger + */ + protected $privateExponent; + + /** + * RSADP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. + * + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsadp(BigInteger $c) + { + if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Ciphertext representative out of range'); + } + return $this->exponentiate($c); + } + + /** + * RSASP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. + * + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsasp1(BigInteger $m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Signature representative out of range'); + } + return $this->exponentiate($m); + } + + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + protected function exponentiate(BigInteger $x) + { + switch (true) { + case empty($this->primes): + case $this->primes[1]->equals(self::$zero): + case empty($this->coefficients): + case $this->coefficients[2]->equals(self::$zero): + case empty($this->exponents): + case $this->exponents[1]->equals(self::$zero): + return $x->modPow($this->exponent, $this->modulus); + } + + $num_primes = count($this->primes); + + if (!static::$enableBlinding) { + $m_i = [ + 1 => $x->modPow($this->exponents[1], $this->primes[1]), + 2 => $x->modPow($this->exponents[2], $this->primes[2]) + ]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } else { + $smallest = $this->primes[1]; + for ($i = 2; $i <= $num_primes; $i++) { + if ($smallest->compare($this->primes[$i]) > 0) { + $smallest = $this->primes[$i]; + } + } + + $r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); + + $m_i = [ + 1 => $this->blind($x, $r, 1), + 2 => $this->blind($x, $r, 2) + ]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $this->blind($x, $r, $i); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } + + return $m; + } + + /** + * Performs RSA Blinding + * + * Protects against timing attacks by employing RSA Blinding. + * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) + * + * @param \phpseclib3\Math\BigInteger $x + * @param \phpseclib3\Math\BigInteger $r + * @param int $i + * @return \phpseclib3\Math\BigInteger + */ + private function blind(BigInteger $x, BigInteger $r, $i) + { + $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); + $x = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->modInverse($this->primes[$i]); + $x = $x->multiply($r); + list(, $x) = $x->divide($this->primes[$i]); + + return $x; + } + + /** + * EMSA-PSS-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. + * + * @return string + * @param string $m + * @throws \RuntimeException on encoding error + * @param int $emBits + */ + private function emsa_pss_encode($m, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + throw new \LengthException('RSA modulus too short'); + } + + $salt = Random::string($sLen); + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h = $this->hash->hash($m2); + $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); + $db = $ps . chr(1) . $salt; + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); // ie. stlren($db) + $maskedDB = $db ^ $dbMask; + $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; + $em = $maskedDB . $h . chr(0xBC); + + return $em; + } + + /** + * RSASSA-PSS-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. + * + * @param string $m + * @return bool|string + */ + private function rsassa_pss_sign($m) + { + // EMSA-PSS encoding + + $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); + + // RSA signature + + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + + // Output the signature S + + return $s; + } + + /** + * RSASSA-PKCS1-V1_5-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. + * + * @param string $m + * @throws \LengthException if the RSA modulus is too short + * @return bool|string + */ + private function rsassa_pkcs1_v1_5_sign($m) + { + // EMSA-PKCS1-v1_5 encoding + + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + } catch (\LengthException $e) { + throw new \LengthException('RSA modulus too short'); + } + + // RSA signature + + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + + // Output the signature S + + return $s; + } + + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return string + */ + public function sign($message) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_PKCS1: + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_sign($message); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_sign($message); + } + } + + /** + * RSAES-PKCS1-V1_5-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. + * + * @param string $c + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_decrypt($c) + { + // Length checking + + if (strlen($c) != $this->k) { // or if k < 11 + throw new \LengthException('Ciphertext representative too long'); + } + + // RSA decryption + + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + + // EME-PKCS1-v1_5 decoding + + if (ord($em[0]) != 0 || ord($em[1]) > 2) { + throw new \RuntimeException('Decryption error'); + } + + $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); + $m = substr($em, strlen($ps) + 3); + + if (strlen($ps) < 8) { + throw new \RuntimeException('Decryption error'); + } + + // Output M + + return $m; + } + + /** + * RSAES-OAEP-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error + * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: + * + * Note. Care must be taken to ensure that an opponent cannot + * distinguish the different error conditions in Step 3.g, whether by + * error message or timing, or, more generally, learn partial + * information about the encoded message EM. Otherwise an opponent may + * be able to obtain useful information about the decryption of the + * ciphertext C, leading to a chosen-ciphertext attack such as the one + * observed by Manger [36]. + * + * @param string $c + * @return bool|string + */ + private function rsaes_oaep_decrypt($c) + { + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { + throw new \LengthException('Ciphertext representative too long'); + } + + // RSA decryption + + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + + // EME-OAEP decoding + + $lHash = $this->hash->hash($this->label); + $y = ord($em[0]); + $maskedSeed = substr($em, 1, $this->hLen); + $maskedDB = substr($em, $this->hLen + 1); + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $seed = $maskedSeed ^ $seedMask; + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $lHash2 = substr($db, 0, $this->hLen); + $m = substr($db, $this->hLen); + $hashesMatch = hash_equals($lHash, $lHash2); + $leadingZeros = 1; + $patternMatch = 0; + $offset = 0; + for ($i = 0; $i < strlen($m); $i++) { + $patternMatch |= $leadingZeros & ($m[$i] === "\1"); + $leadingZeros &= $m[$i] === "\0"; + $offset += $patternMatch ? 0 : 1; + } + + // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // to protect against timing attacks + if (!$hashesMatch | !$patternMatch) { + throw new \RuntimeException('Decryption error'); + } + + // Output the message M + + return substr($m, $offset + 1); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (strlen($m) > $this->k) { + throw new \LengthException('Ciphertext representative too long'); + } + + $temp = $this->os2ip($m); + $temp = $this->rsadp($temp); + return $this->i2osp($temp, $this->k); + } + + /** + * Decryption + * + * @see self::encrypt() + * @param string $ciphertext + * @return bool|string + */ + public function decrypt($ciphertext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($ciphertext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_decrypt($ciphertext); + } + } + + /** + * Returns the public key + * + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + if (empty($this->modulus) || empty($this->publicExponent)) { + throw new \RuntimeException('Public key components not found'); + } + + $key = $type::savePublicKey($this->modulus, $this->publicExponent); + return RSA::loadFormat('PKCS8', $key) + ->withHash($this->hash->getHash()) + ->withMGFHash($this->mgfHash->getHash()) + ->withSaltLength($this->sLen) + ->withLabel($this->label) + ->withPadding($this->signaturePadding | $this->encryptionPadding); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin( + 'Keys', + $type, + empty($this->primes) ? 'savePublicKey' : 'savePrivateKey' + ); + + if ($type == PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options += [ + 'hash' => $this->hash->getHash(), + 'MGFHash' => $this->mgfHash->getHash(), + 'saltLength' => $this->getSaltLength() + ]; + } else { + throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + + if (empty($this->primes)) { + return $type::savePublicKey($this->modulus, $this->exponent, $options); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + + /* + $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + if ($key !== false || count($this->primes) == 2) { + return $key; + } + + $nSize = $this->getSize() >> 1; + + $primes = [1 => clone self::$one, clone self::$one]; + $i = 1; + foreach ($this->primes as $prime) { + $primes[$i] = $primes[$i]->multiply($prime); + if ($primes[$i]->getLength() >= $nSize) { + $i++; + } + } + + $exponents = []; + $coefficients = [2 => $primes[2]->modInverse($primes[1])]; + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $this->modulus->modInverse($temp); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); + */ + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php new file mode 100644 index 000000000..58939a9f6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php @@ -0,0 +1,513 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps\DigestInfo; +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +final class PublicKey extends RSA implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + private function exponentiate(BigInteger $x) + { + return $x->modPow($this->exponent, $this->modulus); + } + + /** + * RSAVP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. + * + * @param \phpseclib3\Math\BigInteger $s + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsavp1($s) + { + if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { + return false; + } + return $this->exponentiate($s); + } + + /** + * RSASSA-PKCS1-V1_5-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. + * + * @param string $m + * @param string $s + * @throws \LengthException if the RSA modulus is too short + * @return bool + */ + private function rsassa_pkcs1_v1_5_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === false) { + return false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + // EMSA-PKCS1-v1_5 encoding + + $exception = false; + + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + $r1 = hash_equals($em, $em2); + } catch (\LengthException $e) { + $exception = true; + } + + try { + $em3 = $this->emsa_pkcs1_v1_5_encode_without_null($m, $this->k); + $r2 = hash_equals($em, $em3); + } catch (\LengthException $e) { + $exception = true; + } catch (UnsupportedAlgorithmException $e) { + $r2 = false; + } + + if ($exception) { + throw new \LengthException('RSA modulus too short'); + } + + // Compare + return $r1 || $r2; + } + + /** + * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) + * + * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 + * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. + * This means that under rare conditions you can have a perfectly valid v1.5 signature + * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends + * that if you're going to validate these types of signatures you "should indicate + * whether the underlying BER encoding is a DER encoding and hence whether the signature + * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do + * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of + * RSA::PADDING_PKCS1... that means BER encoding was used. + * + * @param string $m + * @param string $s + * @return bool + */ + private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === false) { + return false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + if (Strings::shift($em, 2) != "\0\1") { + return false; + } + + $em = ltrim($em, "\xFF"); + if (Strings::shift($em) != "\0") { + return false; + } + + $decoded = ASN1::decodeBER($em); + if (!is_array($decoded) || empty($decoded[0]) || strlen($em) > $decoded[0]['length']) { + return false; + } + + static $oids; + if (!isset($oids)) { + $oids = [ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', // from PKCS1 v1.5 + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + // from PKCS1 v2.2 + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + ]; + ASN1::loadOIDs($oids); + } + + $decoded = ASN1::asn1map($decoded[0], DigestInfo::MAP); + if (!isset($decoded) || $decoded === false) { + return false; + } + + if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { + return false; + } + + if (isset($decoded['digestAlgorithm']['parameters']) && $decoded['digestAlgorithm']['parameters'] !== ['null' => '']) { + return false; + } + + $hash = $decoded['digestAlgorithm']['algorithm']; + $hash = substr($hash, 0, 3) == 'id-' ? + substr($hash, 3) : + $hash; + $hash = new Hash($hash); + $em = $hash->hash($m); + $em2 = $decoded['digest']; + + return hash_equals($em, $em2); + } + + /** + * EMSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. + * + * @param string $m + * @param string $em + * @param int $emBits + * @return string + */ + private function emsa_pss_verify($m, $em, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + return false; + } + + if ($em[strlen($em) - 1] != chr(0xBC)) { + return false; + } + + $maskedDB = substr($em, 0, -$this->hLen - 1); + $h = substr($em, -$this->hLen - 1, $this->hLen); + $temp = chr(0xFF << ($emBits & 7)); + if ((~$maskedDB[0] & $temp) != $temp) { + return false; + } + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; + $temp = $emLen - $this->hLen - $sLen - 2; + if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { + return false; + } + $salt = substr($db, $temp + 1); // should be $sLen long + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h2 = $this->hash->hash($m2); + return hash_equals($h, $h2); + } + + /** + * RSASSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. + * + * @param string $m + * @param string $s + * @return bool|string + */ + private function rsassa_pss_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $modBits = strlen($this->modulus->toBits()); + + $s2 = $this->os2ip($s); + $m2 = $this->rsavp1($s2); + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + // EMSA-PSS verification + + return $this->emsa_pss_verify($m, $em, $modBits - 1); + } + + /** + * Verifies a signature + * + * @see self::sign() + * @param string $message + * @param string $signature + * @return bool + */ + public function verify($message, $signature) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); + case self::SIGNATURE_PKCS1: + return $this->rsassa_pkcs1_v1_5_verify($message, $signature); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_verify($message, $signature); + } + } + + /** + * RSAES-PKCS1-V1_5-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. + * + * @param string $m + * @param bool $pkcs15_compat optional + * @throws \LengthException if strlen($m) > $this->k - 11 + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = false) + { + $mLen = strlen($m); + + // Length checking + + if ($mLen > $this->k - 11) { + throw new \LengthException('Message too long'); + } + + // EME-PKCS1-v1_5 encoding + + $psLen = $this->k - $mLen - 3; + $ps = ''; + while (strlen($ps) != $psLen) { + $temp = Random::string($psLen - strlen($ps)); + $temp = str_replace("\x00", '', $temp); + $ps .= $temp; + } + $type = 2; + $em = chr(0) . chr($type) . $ps . chr(0) . $m; + + // RSA encryption + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAES-OAEP-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and + * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. + * + * @param string $m + * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 + * @return string + */ + private function rsaes_oaep_encrypt($m) + { + $mLen = strlen($m); + + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if ($mLen > $this->k - 2 * $this->hLen - 2) { + throw new \LengthException('Message too long'); + } + + // EME-OAEP encoding + + $lHash = $this->hash->hash($this->label); + $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); + $db = $lHash . $ps . chr(1) . $m; + $seed = Random::string($this->hLen); + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $maskedSeed = $seed ^ $seedMask; + $em = chr(0) . $maskedSeed . $maskedDB; + + // RSA encryption + + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAEP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. + * + * @param \phpseclib3\Math\BigInteger $m + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsaep($m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Message representative out of range'); + } + return $this->exponentiate($m); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (strlen($m) > $this->k) { + throw new \LengthException('Message too long'); + } + + $temp = $this->os2ip($m); + $temp = $this->rsaep($temp); + return $this->i2osp($temp, $this->k); + } + + /** + * Encryption + * + * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. + * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will + * be concatenated together. + * + * @see self::decrypt() + * @param string $plaintext + * @return bool|string + * @throws \LengthException if the RSA modulus is too short + */ + public function encrypt($plaintext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($plaintext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_encrypt($plaintext); + } + } + + /** + * Returns the public key + * + * The public key is only returned under two circumstances - if the private key had the public key embedded within it + * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this + * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. + * + * @param string $type + * @param array $options optional + * @return mixed + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + if ($type == PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options += [ + 'hash' => $this->hash->getHash(), + 'MGFHash' => $this->mgfHash->getHash(), + 'saltLength' => $this->getSaltLength() + ]; + } else { + throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + + return $type::savePublicKey($this->modulus, $this->publicExponent, $options); + } + + /** + * Converts a public key to a private key + * + * @return RSA + */ + public function asPrivateKey() + { + $new = new PrivateKey(); + $new->exponent = $this->exponent; + $new->modulus = $this->modulus; + $new->k = $this->k; + $new->format = $this->format; + return $new + ->withHash($this->hash->getHash()) + ->withMGFHash($this->mgfHash->getHash()) + ->withSaltLength($this->sLen) + ->withLabel($this->label) + ->withPadding($this->signaturePadding | $this->encryptionPadding); + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php similarity index 51% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php index 8f53eb319..f813a2eac 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php @@ -10,28 +10,24 @@ * * * - * @category Crypt - * @package Random * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; /** * Pure-PHP Random Number Generator * - * @package Random * @author Jim Wigginton - * @access public */ -class Random +abstract class Random { /** * Generate a random string. @@ -41,75 +37,26 @@ class Random * eg. for RSA key generation. * * @param int $length + * @throws \RuntimeException if a symmetric cipher is needed but not loaded * @return string */ - static function string($length) + public static function string($length) { if (!$length) { return ''; } - if (version_compare(PHP_VERSION, '7.0.0', '>=')) { - try { - return \random_bytes($length); - } catch (\Throwable $e) { - // If a sufficient source of randomness is unavailable, random_bytes() will throw an - // object that implements the Throwable interface (Exception, TypeError, Error). - // We don't actually need to do anything here. The string() method should just continue - // as normal. Note, however, that if we don't have a sufficient source of randomness for - // random_bytes(), most of the other calls here will fail too, so we'll end up using - // the PHP implementation. - } - } - - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call. - // ie. class_alias is a function that was introduced in PHP 5.3 - if (extension_loaded('mcrypt') && function_exists('class_alias')) { - return @mcrypt_create_iv($length); - } - // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was, - // to quote , "possible blocking behavior". as of 5.3.4 - // openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both - // call php_win32_get_random_bytes(): - // - // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008 - // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392 - // - // php_win32_get_random_bytes() is defined thusly: - // - // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80 - // - // we're calling it, all the same, in the off chance that the mcrypt extension is not available - if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) { - return openssl_random_pseudo_bytes($length); - } - } else { - // method 1. the fastest - if (extension_loaded('openssl')) { - return openssl_random_pseudo_bytes($length); - } - // method 2 - static $fp = true; - if ($fp === true) { - // warning's will be output unles the error suppression operator is used. errors such as - // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc. - $fp = @fopen('/dev/urandom', 'rb'); - } - if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource() - $temp = fread($fp, $length); - if (strlen($temp) == $length) { - return $temp; - } - } - // method 3. pretty much does the same thing as method 2 per the following url: - // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391 - // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're - // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir - // restrictions or some such - if (extension_loaded('mcrypt')) { - return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); - } + try { + return random_bytes($length); + } catch (\Exception $e) { + // random_compat will throw an Exception, which in PHP 5 does not implement Throwable + } catch (\Throwable $e) { + // If a sufficient source of randomness is unavailable, random_bytes() will throw an + // object that implements the Throwable interface (Exception, TypeError, Error). + // We don't actually need to do anything here. The string() method should just continue + // as normal. Note, however, that if we don't have a sufficient source of randomness for + // random_bytes(), most of the other calls here will fail too, so we'll end up using + // the PHP implementation. } // at this point we have no choice but to use a pure-PHP CSPRNG @@ -122,11 +69,11 @@ class Random // PHP isn't low level to be able to use those as sources and on a web server there's not likely // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use // however, a ton of people visiting the website. obviously you don't want to base your seeding - // soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled + // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled // by the user and (2) this isn't just looking at the data sent by the current user - it's based // on the data sent by all users. one user requests the page and a hash of their info is saved. // another user visits the page and the serialization of their data is utilized along with the - // server envirnment stuff and a hash of the previous http request data (which itself utilizes + // server environment stuff and a hash of the previous http request data (which itself utilizes // a hash of the session data before that). certainly an attacker should be assumed to have // full control over his own http requests. he, however, is not going to have control over // everyone's http requests. @@ -146,15 +93,17 @@ class Random session_cache_limiter(''); session_start(); - $v = $seed = $_SESSION['seed'] = pack('H*', sha1( - (isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') . - (isset($_POST) ? phpseclib_safe_serialize($_POST) : '') . - (isset($_GET) ? phpseclib_safe_serialize($_GET) : '') . - (isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') . - phpseclib_safe_serialize($GLOBALS) . - phpseclib_safe_serialize($_SESSION) . - phpseclib_safe_serialize($_OLD_SESSION) - )); + $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . + (isset($_POST) ? self::safe_serialize($_POST) : '') . + (isset($_GET) ? self::safe_serialize($_GET) : '') . + (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . + // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates + // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage + // for more info + (version_compare(PHP_VERSION, '8.1.0', '>=') ? serialize($GLOBALS) : self::safe_serialize($GLOBALS)) . + self::safe_serialize($_SESSION) . + self::safe_serialize($_OLD_SESSION); + $v = $seed = $_SESSION['seed'] = sha1($v, true); if (!isset($_SESSION['count'])) { $_SESSION['count'] = 0; } @@ -185,38 +134,37 @@ class Random // http://tools.ietf.org/html/rfc4253#section-7.2 // // see the is_string($crypto) part for an example of how to expand the keys - $key = pack('H*', sha1($seed . 'A')); - $iv = pack('H*', sha1($seed . 'C')); + $key = sha1($seed . 'A', true); + $iv = sha1($seed . 'C', true); // ciphers are used as per the nist.gov link below. also, see this link: // // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives switch (true) { - case class_exists('\phpseclib\Crypt\AES'): - $crypto = new AES(Base::MODE_CTR); + case class_exists('\phpseclib3\Crypt\AES'): + $crypto = new AES('ctr'); break; - case class_exists('\phpseclib\Crypt\Twofish'): - $crypto = new Twofish(Base::MODE_CTR); + case class_exists('\phpseclib3\Crypt\Twofish'): + $crypto = new Twofish('ctr'); break; - case class_exists('\phpseclib\Crypt\Blowfish'): - $crypto = new Blowfish(Base::MODE_CTR); + case class_exists('\phpseclib3\Crypt\Blowfish'): + $crypto = new Blowfish('ctr'); break; - case class_exists('\phpseclib\Crypt\TripleDES'): - $crypto = new TripleDES(Base::MODE_CTR); + case class_exists('\phpseclib3\Crypt\TripleDES'): + $crypto = new TripleDES('ctr'); break; - case class_exists('\phpseclib\Crypt\DES'): - $crypto = new DES(Base::MODE_CTR); + case class_exists('\phpseclib3\Crypt\DES'): + $crypto = new DES('ctr'); break; - case class_exists('\phpseclib\Crypt\RC4'): + case class_exists('\phpseclib3\Crypt\RC4'): $crypto = new RC4(); break; default: - user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded'); - return false; + throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); } - $crypto->setKey($key); - $crypto->setIV($iv); + $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); + $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3)); $crypto->enableContinuousBuffer(); } @@ -235,23 +183,20 @@ class Random $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21 $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20 $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20 - $result.= $r; + $result .= $r; } + return substr($result, 0, $length); } -} -if (!function_exists('phpseclib_safe_serialize')) { /** * Safely serialize variables * - * If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier. - * PHP 5.3 will emit a warning. - * + * If a class has a private __sleep() it'll emit a warning + * @return mixed * @param mixed $arr - * @access public */ - function phpseclib_safe_serialize(&$arr) + private static function safe_serialize(&$arr) { if (is_object($arr)) { return ''; @@ -263,12 +208,12 @@ if (!function_exists('phpseclib_safe_serialize')) { if (isset($arr['__phpseclib_marker'])) { return ''; } - $safearr = array(); + $safearr = []; $arr['__phpseclib_marker'] = true; foreach (array_keys($arr) as $key) { // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage if ($key !== '__phpseclib_marker') { - $safearr[$key] = phpseclib_safe_serialize($arr[$key]); + $safearr[$key] = self::safe_serialize($arr[$key]); } } unset($arr['__phpseclib_marker']); diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php similarity index 63% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php index 3648a1972..ff31f9c88 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php @@ -30,7 +30,7 @@ * setKey('abcdefghijklmnop'); * @@ -44,135 +44,136 @@ * ?> * * - * @category Crypt - * @package Rijndael * @author Jim Wigginton * @copyright 2008 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\BadModeException; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\InsufficientSetupException; /** * Pure-PHP implementation of Rijndael. * - * @package Rijndael * @author Jim Wigginton - * @access public */ -class Rijndael extends Base +class Rijndael extends BlockCipher { /** * The mcrypt specific name of the cipher * * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. - * \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable + * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable * or not for the current $block_size/$key_length. * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. * - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt - * @see \phpseclib\Crypt\Base::engine + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::engine * @see self::isValidEngine() * @var string - * @access private */ - var $cipher_name_mcrypt = 'rijndael-128'; - - /** - * The default salt used by setPassword() - * - * @see \phpseclib\Crypt\Base::password_default_salt - * @see \phpseclib\Crypt\Base::setPassword() - * @var string - * @access private - */ - var $password_default_salt = 'phpseclib'; + protected $cipher_name_mcrypt = 'rijndael-128'; /** * The Key Schedule * - * @see self::_setup() + * @see self::setup() * @var array - * @access private */ - var $w; + private $w; /** * The Inverse Key Schedule * - * @see self::_setup() + * @see self::setup() * @var array - * @access private */ - var $dw; + private $dw; /** * The Block Length divided by 32 * - * @see self::setBlockLength() - * @var int - * @access private - * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size + * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once. + * of that, we'll just precompute it once.} + * + * @see self::setBlockLength() + * @var int */ - var $Nb = 4; + private $Nb = 4; /** * The Key Length (in bytes) * - * @see self::setKeyLength() - * @var int - * @access private - * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once. + * of that, we'll just precompute it once.} + * + * @see self::setKeyLength() + * @var int */ - var $key_length = 16; + protected $key_length = 16; /** * The Key Length divided by 32 * * @see self::setKeyLength() * @var int - * @access private * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 */ - var $Nk = 4; + private $Nk = 4; /** * The Number of Rounds * + * {@internal The max value is 14, the min value is 10.} + * * @var int - * @access private - * @internal The max value is 14, the min value is 10. */ - var $Nr; + private $Nr; /** * Shift offsets * * @var array - * @access private */ - var $c; + private $c; /** * Holds the last used key- and block_size information * * @var array - * @access private */ - var $kl; + private $kl; + + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } /** * Sets the key length. * - * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to - * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. + * Valid key lengths are 128, 160, 192, 224, and 256. * * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to @@ -185,73 +186,111 @@ class Rijndael extends Base * the mcrypt php extension, even if available. * This results then in slower encryption. * - * @access public + * @throws \LengthException if the key length is invalid * @param int $length */ - function setKeyLength($length) + public function setKeyLength($length) { - switch (true) { - case $length <= 128: - $this->key_length = 16; - break; - case $length <= 160: - $this->key_length = 20; - break; - case $length <= 192: - $this->key_length = 24; - break; - case $length <= 224: - $this->key_length = 28; + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + $this->key_length = $length >> 3; break; default: - $this->key_length = 32; + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); } parent::setKeyLength($length); } + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 20: + case 24: + case 28: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); + } + + parent::setKey($key); + } + /** * Sets the block length * - * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to - * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. + * Valid block lengths are 128, 160, 192, 224, and 256. * - * @access public * @param int $length */ - function setBlockLength($length) + public function setBlockLength($length) { - $length >>= 5; - if ($length > 8) { - $length = 8; - } elseif ($length < 4) { - $length = 4; + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); } - $this->Nb = $length; - $this->block_size = $length << 2; - $this->changed = true; - $this->_setEngine(); + + $this->Nb = $length >> 5; + $this->block_size = $length >> 3; + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * - * @see \phpseclib\Crypt\Base::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @param int $engine - * @access public * @return bool */ - function isValidEngine($engine) + protected function isValidEngineHelper($engine) { switch ($engine) { + case self::ENGINE_LIBSODIUM: + return function_exists('sodium_crypto_aead_aes256gcm_is_available') && + sodium_crypto_aead_aes256gcm_is_available() && + $this->mode == self::MODE_GCM && + $this->key_length == 32 && + $this->nonce && strlen($this->nonce) == 12 && + $this->block_size == 16; + case self::ENGINE_OPENSSL_GCM: + if (!extension_loaded('openssl')) { + return false; + } + $methods = openssl_get_cipher_methods(); + return $this->mode == self::MODE_GCM && + version_compare(PHP_VERSION, '7.1.0', '>=') && + in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && + $this->block_size == 16; case self::ENGINE_OPENSSL: if ($this->block_size != 16) { return false; } $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; - $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode(); + $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); break; case self::ENGINE_MCRYPT: $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); @@ -261,21 +300,20 @@ class Rijndael extends Base } } - return parent::isValidEngine($engine); + return parent::isValidEngineHelper($engine); } /** * Encrypts a block * - * @access private * @param string $in * @return string */ - function _encryptBlock($in) + protected function encryptBlock($in) { static $tables; if (empty($tables)) { - $tables = &$this->_getTables(); + $tables = &$this->getTables(); } $t0 = $tables[0]; $t1 = $tables[1]; @@ -283,7 +321,7 @@ class Rijndael extends Base $t3 = $tables[3]; $sbox = $tables[4]; - $state = array(); + $state = []; $words = unpack('N*', $in); $c = $this->c; @@ -305,7 +343,7 @@ class Rijndael extends Base // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf - $temp = array(); + $temp = []; for ($round = 1; $round < $Nr; ++$round) { $i = 0; // $c[0] == 0 $j = $c[1]; @@ -340,7 +378,7 @@ class Rijndael extends Base $k = $c[2]; $l = $c[3]; while ($i < $Nb) { - $temp[$i] = ($state[$i] & 0xFF000000) ^ + $temp[$i] = ($state[$i] & intval(0xFF000000)) ^ ($state[$j] & 0x00FF0000) ^ ($state[$k] & 0x0000FF00) ^ ($state[$l] & 0x000000FF) ^ @@ -351,32 +389,20 @@ class Rijndael extends Base $l = ($l + 1) % $Nb; } - switch ($Nb) { - case 8: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]); - case 7: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]); - case 6: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]); - case 5: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]); - default: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]); - } + return pack('N*', ...$temp); } /** * Decrypts a block * - * @access private * @param string $in * @return string */ - function _decryptBlock($in) + protected function decryptBlock($in) { static $invtables; if (empty($invtables)) { - $invtables = &$this->_getInvTables(); + $invtables = &$this->getInvTables(); } $dt0 = $invtables[0]; $dt1 = $invtables[1]; @@ -384,7 +410,7 @@ class Rijndael extends Base $dt3 = $invtables[3]; $isbox = $invtables[4]; - $state = array(); + $state = []; $words = unpack('N*', $in); $c = $this->c; @@ -398,7 +424,7 @@ class Rijndael extends Base $state[] = $word ^ $dw[++$wc]; } - $temp = array(); + $temp = []; for ($round = $Nr - 1; $round > 0; --$round) { $i = 0; // $c[0] == 0 $j = $Nb - $c[1]; @@ -426,7 +452,7 @@ class Rijndael extends Base $l = $Nb - $c[3]; while ($i < $Nb) { - $word = ($state[$i] & 0xFF000000) | + $word = ($state[$i] & intval(0xFF000000)) | ($state[$j] & 0x00FF0000) | ($state[$k] & 0x0000FF00) | ($state[$l] & 0x000000FF); @@ -441,44 +467,75 @@ class Rijndael extends Base $l = ($l + 1) % $Nb; } - switch ($Nb) { - case 8: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]); - case 7: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]); - case 6: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]); - case 5: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]); - default: - return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]); + return pack('N*', ...$temp); + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + parent::setup(); + + if (is_string($this->iv) && strlen($this->iv) != $this->block_size) { + throw new InconsistentSetupException('The IV length (' . strlen($this->iv) . ') does not match the block size (' . $this->block_size . ')'); } } /** * Setup the key (expansion) * - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() */ - function _setupKey() + protected function setupKey() { // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse - static $rcon = array(0, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, - 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, - 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, - 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, - 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 - ); + static $rcon; + + if (!isset($rcon)) { + $rcon = [0, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, + 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, + 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, + 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 + ]; + $rcon = array_map('intval', $rcon); + } if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { // already expanded return; } - $this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size); + $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; $this->Nk = $this->key_length >> 2; // see Rijndael-ammended.pdf#page=44 @@ -492,13 +549,13 @@ class Rijndael extends Base case 4: case 5: case 6: - $this->c = array(0, 1, 2, 3); + $this->c = [0, 1, 2, 3]; break; case 7: - $this->c = array(0, 1, 2, 4); + $this->c = [0, 1, 2, 4]; break; case 8: - $this->c = array(0, 1, 3, 4); + $this->c = [0, 1, 3, 4]; } $w = array_values(unpack('N*words', $this->key)); @@ -511,10 +568,10 @@ class Rijndael extends Base // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. - $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord - $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk]; + $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord + $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { - $temp = $this->_subWord($temp); + $temp = $this->subWord($temp); } $w[$i] = $w[$i - $this->Nk] ^ $temp; } @@ -526,8 +583,8 @@ class Rijndael extends Base // 1. Apply the Key Expansion. // 2. Apply InvMixColumn to all Round Keys except the first and the last one." // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" - list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables(); - $temp = $this->w = $this->dw = array(); + list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); + $temp = $this->w = $this->dw = []; for ($i = $row = $col = 0; $i < $length; $i++, $col++) { if ($col == $this->Nb) { if ($row == 0) { @@ -536,7 +593,7 @@ class Rijndael extends Base // subWord + invMixColumn + invSubWord = invMixColumn $j = 0; while ($j < $this->Nb) { - $dw = $this->_subWord($this->w[$row][$j]); + $dw = $this->subWord($this->w[$row][$j]); $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ $dt1[$dw >> 16 & 0x000000FF] ^ $dt2[$dw >> 8 & 0x000000FF] ^ @@ -571,14 +628,14 @@ class Rijndael extends Base /** * Performs S-Box substitutions * - * @access private + * @return array * @param int $word */ - function _subWord($word) + private function subWord($word) { static $sbox; if (empty($sbox)) { - list(, , , , $sbox) = $this->_getTables(); + list(, , , , $sbox) = self::getTables(); } return $sbox[$word & 0x000000FF] | @@ -590,20 +647,19 @@ class Rijndael extends Base /** * Provides the mixColumns and sboxes tables * - * @see self::_encryptBlock() - * @see self::_setupInlineCrypt() - * @see self::_subWord() - * @access private + * @see self::encryptBlock() + * @see self::setupInlineCrypt() + * @see self::subWord() * @return array &$tables */ - function &_getTables() + protected function &getTables() { static $tables; if (empty($tables)) { // according to (section 5.2.1), // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so // those are the names we'll use. - $t3 = array_map('intval', array( + $t3 = array_map('intval', [ // with array_map('intval', ...) we ensure we have only int's and not // some slower floats converted by php automatically on high values 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, @@ -638,22 +694,22 @@ class Rijndael extends Base 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C - )); + ]); foreach ($t3 as $t3i) { - $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF); - $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF); - $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF); + $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF); + $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF); + $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF); } - $tables = array( + $tables = [ // The Precomputed mixColumns tables t0 - t3 $t0, $t1, $t2, $t3, // The SubByte S-Box - array( + [ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, @@ -670,8 +726,8 @@ class Rijndael extends Base 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 - ) - ); + ] + ]; } return $tables; } @@ -679,17 +735,16 @@ class Rijndael extends Base /** * Provides the inverse mixColumns and inverse sboxes tables * - * @see self::_decryptBlock() - * @see self::_setupInlineCrypt() - * @see self::_setupKey() - * @access private + * @see self::decryptBlock() + * @see self::setupInlineCrypt() + * @see self::setupKey() * @return array &$tables */ - function &_getInvTables() + protected function &getInvTables() { static $tables; if (empty($tables)) { - $dt3 = array_map('intval', array( + $dt3 = array_map('intval', [ 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, @@ -722,22 +777,22 @@ class Rijndael extends Base 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 - )); + ]); foreach ($dt3 as $dt3i) { - $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF); - $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF); - $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF); + $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF); + $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF); + $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF); }; - $tables = array( + $tables = [ // The Precomputed inverse mixColumns tables dt0 - dt3 $dt0, $dt1, $dt2, $dt3, // The inverse SubByte S-Box - array( + [ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, @@ -754,8 +809,8 @@ class Rijndael extends Base 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D - ) - ); + ] + ]; } return $tables; } @@ -763,174 +818,219 @@ class Rijndael extends Base /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib\Crypt\Base::_setupInlineCrypt() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() */ - function _setupInlineCrypt() + protected function setupInlineCrypt() { - // Note: _setupInlineCrypt() will be called only if $this->changed === true - // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt(). - // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible. + $w = $this->w; + $dw = $this->dw; + $init_encrypt = ''; + $init_decrypt = ''; - $lambda_functions =& self::_getLambdaFunctions(); + $Nr = $this->Nr; + $Nb = $this->Nb; + $c = $this->c; - // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. - // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit) - // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. - $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); + // Generating encrypt code: + $init_encrypt .= ' + if (empty($tables)) { + $tables = &$this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + '; - // Generation of a uniqe hash for our generated code - $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}"; - if ($gen_hi_opt_code) { - $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $encrypt_block = '$in = unpack("N*", $in);' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ";\n"; } - if (!isset($lambda_functions[$code_hash])) { - switch (true) { - case $gen_hi_opt_code: - // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance. - $w = $this->w; - $dw = $this->dw; - $init_encrypt = ''; - $init_decrypt = ''; + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= + '$' . $e . $i . ' = + $t0[($' . $s . $i . ' >> 24) & 0xff] ^ + $t1[($' . $s . (($i + $c[1]) % $Nb) . ' >> 16) & 0xff] ^ + $t2[($' . $s . (($i + $c[2]) % $Nb) . ' >> 8) & 0xff] ^ + $t3[ $' . $s . (($i + $c[3]) % $Nb) . ' & 0xff] ^ + ' . $w[++$wc] . ";\n"; + } + } + + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= + '$' . $e . $i . ' = + $sbox[ $' . $e . $i . ' & 0xff] | + ($sbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | + ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | + ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; + } + $encrypt_block .= '$in = pack("N*"' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= ', + ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ + ($' . $e . (($i + $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ + ($' . $e . (($i + $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ + ($' . $e . (($i + $c[3]) % $Nb) . ' & 0x000000FF ) ^ + ' . $w[$i] . "\n"; + } + $encrypt_block .= ');'; + + // Generating decrypt code: + $init_decrypt .= ' + if (empty($invtables)) { + $invtables = &$this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $decrypt_block = '$in = unpack("N*", $in);' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n"; + } + + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= + '$' . $e . $i . ' = + $dt0[($' . $s . $i . ' >> 24) & 0xff] ^ + $dt1[($' . $s . (($Nb + $i - $c[1]) % $Nb) . ' >> 16) & 0xff] ^ + $dt2[($' . $s . (($Nb + $i - $c[2]) % $Nb) . ' >> 8) & 0xff] ^ + $dt3[ $' . $s . (($Nb + $i - $c[3]) % $Nb) . ' & 0xff] ^ + ' . $dw[++$wc] . ";\n"; + } + } + + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= + '$' . $e . $i . ' = + $isbox[ $' . $e . $i . ' & 0xff] | + ($isbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | + ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | + ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; + } + $decrypt_block .= '$in = pack("N*"' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= ', + ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ + ($' . $e . (($Nb + $i - $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ + ($' . $e . (($Nb + $i - $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ + ($' . $e . (($Nb + $i - $c[3]) % $Nb) . ' & 0x000000FF ) ^ + ' . $dw[$i] . "\n"; + } + $decrypt_block .= ');'; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => 'static $tables; static $invtables;', + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } + + /** + * Encrypts a message. + * + * @see self::decrypt() + * @see parent::encrypt() + * @param string $plaintext + * @return string + */ + public function encrypt($plaintext) + { + $this->setup(); + + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + $this->newtag = sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); + return Strings::shift($this->newtag, strlen($plaintext)); + case self::ENGINE_OPENSSL_GCM: + return openssl_encrypt( + $plaintext, + 'aes-' . $this->getKeyLength() . '-gcm', + $this->key, + OPENSSL_RAW_DATA, + $this->nonce, + $this->newtag, + $this->aad + ); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * @see self::encrypt() + * @see parent::decrypt() + * @param string $ciphertext + * @return string + */ + public function decrypt($ciphertext) + { + $this->setup(); + + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + if (strlen($this->oldtag) != 16) { break; - default: - for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) { - $w[] = '$w[' . $i . ']'; - $dw[] = '$dw[' . $i . ']'; - } - $init_encrypt = '$w = $self->w;'; - $init_decrypt = '$dw = $self->dw;'; - } - - $Nr = $this->Nr; - $Nb = $this->Nb; - $c = $this->c; - - // Generating encrypt code: - $init_encrypt.= ' - static $tables; - if (empty($tables)) { - $tables = &$self->_getTables(); } - $t0 = $tables[0]; - $t1 = $tables[1]; - $t2 = $tables[2]; - $t3 = $tables[3]; - $sbox = $tables[4]; - '; - - $s = 'e'; - $e = 's'; - $wc = $Nb - 1; - - // Preround: addRoundKey - $encrypt_block = '$in = unpack("N*", $in);'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n"; - } - - // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey - for ($round = 1; $round < $Nr; ++$round) { - list($s, $e) = array($e, $s); - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block.= - '$'.$e.$i.' = - $t0[($'.$s.$i .' >> 24) & 0xff] ^ - $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^ - $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^ - $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^ - '.$w[++$wc].";\n"; + $plaintext = sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); + if ($plaintext === false) { + $this->oldtag = false; + throw new BadDecryptionException('Error decrypting ciphertext with libsodium'); } - } - - // Finalround: subWord + shiftRows + addRoundKey - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block.= - '$'.$e.$i.' = - $sbox[ $'.$e.$i.' & 0xff] | - ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) | - ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) | - ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; - } - $encrypt_block .= '$in = pack("N*"'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block.= ', - ($'.$e.$i .' & '.((int)0xFF000000).') ^ - ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^ - ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^ - ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^ - '.$w[$i]."\n"; - } - $encrypt_block .= ');'; - - // Generating decrypt code: - $init_decrypt.= ' - static $invtables; - if (empty($invtables)) { - $invtables = &$self->_getInvTables(); + return $plaintext; + case self::ENGINE_OPENSSL_GCM: + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); } - $dt0 = $invtables[0]; - $dt1 = $invtables[1]; - $dt2 = $invtables[2]; - $dt3 = $invtables[3]; - $isbox = $invtables[4]; - '; - - $s = 'e'; - $e = 's'; - $wc = $Nb - 1; - - // Preround: addRoundKey - $decrypt_block = '$in = unpack("N*", $in);'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n"; - } - - // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey - for ($round = 1; $round < $Nr; ++$round) { - list($s, $e) = array($e, $s); - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block.= - '$'.$e.$i.' = - $dt0[($'.$s.$i .' >> 24) & 0xff] ^ - $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^ - $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^ - $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^ - '.$dw[++$wc].";\n"; + $plaintext = openssl_decrypt( + $ciphertext, + 'aes-' . $this->getKeyLength() . '-gcm', + $this->key, + OPENSSL_RAW_DATA, + $this->nonce, + $this->oldtag, + $this->aad + ); + if ($plaintext === false) { + $this->oldtag = false; + throw new BadDecryptionException('Error decrypting ciphertext with OpenSSL'); } - } - - // Finalround: subWord + shiftRows + addRoundKey - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block.= - '$'.$e.$i.' = - $isbox[ $'.$e.$i.' & 0xff] | - ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) | - ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) | - ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n"; - } - $decrypt_block .= '$in = pack("N*"'."\n"; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block.= ', - ($'.$e.$i. ' & '.((int)0xFF000000).') ^ - ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^ - ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^ - ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^ - '.$dw[$i]."\n"; - } - $decrypt_block .= ');'; - - $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( - array( - 'init_crypt' => '', - 'init_encrypt' => $init_encrypt, - 'init_decrypt' => $init_decrypt, - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ) - ); + return $plaintext; } - $this->inline_crypt = $lambda_functions[$code_hash]; + + return parent::decrypt($ciphertext); } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php new file mode 100644 index 000000000..0a35f478d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php @@ -0,0 +1,526 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\StreamCipher; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\InsufficientSetupException; + +/** + * Pure-PHP implementation of Salsa20. + * + * @author Jim Wigginton + */ +class Salsa20 extends StreamCipher +{ + /** + * Part 1 of the state + * + * @var string|false + */ + protected $p1 = false; + + /** + * Part 2 of the state + * + * @var string|false + */ + protected $p2 = false; + + /** + * Key Length (in bytes) + * + * @var int + */ + protected $key_length = 32; // = 256 bits + + /** + * @see \phpseclib3\Crypt\Salsa20::crypt() + */ + const ENCRYPT = 0; + + /** + * @see \phpseclib3\Crypt\Salsa20::crypt() + */ + const DECRYPT = 1; + + /** + * Encryption buffer for continuous mode + * + * @var array + */ + protected $enbuffer; + + /** + * Decryption buffer for continuous mode + * + * @var array + */ + protected $debuffer; + + /** + * Counter + * + * @var int + */ + protected $counter = 0; + + /** + * Using Generated Poly1305 Key + * + * @var boolean + */ + protected $usingGeneratedPoly1305Key = false; + + /** + * Salsa20 uses a nonce + * + * @return bool + */ + public function usesNonce() + { + return true; + } + + /** + * Sets the key. + * + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); + } + + parent::setKey($key); + } + + /** + * Sets the nonce. + * + * @param string $nonce + */ + public function setNonce($nonce) + { + if (strlen($nonce) != 8) { + throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); + } + + $this->nonce = $nonce; + $this->changed = true; + $this->setEngine(); + } + + /** + * Sets the counter. + * + * @param int $counter + */ + public function setCounter($counter) + { + $this->counter = $counter; + $this->setEngine(); + } + + /** + * Creates a Poly1305 key using the method discussed in RFC8439 + * + * See https://tools.ietf.org/html/rfc8439#section-2.6.1 + */ + protected function createPoly1305Key() + { + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + $c = clone $this; + $c->setCounter(0); + $c->usePoly1305 = false; + $block = $c->encrypt(str_repeat("\0", 256)); + $this->setPoly1305Key(substr($block, 0, 32)); + + if ($this->counter == 0) { + $this->counter++; + } + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setNonce() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setNonce() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; + + $this->changed = $this->nonIVChanged = false; + + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + if ($this->usePoly1305 && !isset($this->poly1305Key)) { + $this->usingGeneratedPoly1305Key = true; + $this->createPoly1305Key(); + } + + $key = $this->key; + if (strlen($key) == 16) { + $constant = 'expand 16-byte k'; + $key .= $key; + } else { + $constant = 'expand 32-byte k'; + } + + $this->p1 = substr($constant, 0, 4) . + substr($key, 0, 16) . + substr($constant, 4, 4) . + $this->nonce . + "\0\0\0\0"; + $this->p2 = substr($constant, 8, 4) . + substr($key, 16, 16) . + substr($constant, 12, 4); + } + + /** + * Setup the key (expansion) + */ + protected function setupKey() + { + // Salsa20 does not utilize this method + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + $ciphertext = $this->crypt($plaintext, self::ENCRYPT); + if (isset($this->poly1305Key)) { + $this->newtag = $this->poly1305($ciphertext); + } + return $ciphertext; + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if (isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + $newtag = $this->poly1305($ciphertext); + if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + } + + return $this->crypt($ciphertext, self::DECRYPT); + } + + /** + * Encrypts a block + * + * @param string $in + */ + protected function encryptBlock($in) + { + // Salsa20 does not utilize this method + } + + /** + * Decrypts a block + * + * @param string $in + */ + protected function decryptBlock($in) + { + // Salsa20 does not utilize this method + } + + /** + * Encrypts or decrypts a message. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $text + * @param int $mode + * @return string $text + */ + private function crypt($text, $mode) + { + $this->setup(); + if (!$this->continuousBuffer) { + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $this->counter) . $this->p2; + return openssl_encrypt( + $text, + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + } + $i = $this->counter; + $blocks = str_split($text, 64); + foreach ($blocks as &$block) { + $block ^= static::salsa20($this->p1 . pack('V', $i++) . $this->p2); + } + + return implode('', $blocks); + } + + if ($mode == self::ENCRYPT) { + $buffer = &$this->enbuffer; + } else { + $buffer = &$this->debuffer; + } + if (!strlen($buffer['ciphertext'])) { + $ciphertext = ''; + } else { + $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text)); + $text = substr($text, strlen($ciphertext)); + if (!strlen($text)) { + return $ciphertext; + } + } + + $overflow = strlen($text) % 64; // & 0x3F + if ($overflow) { + $text2 = Strings::pop($text, $overflow); + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $buffer['counter']) . $this->p2; + // at this point $text should be a multiple of 64 + $buffer['counter'] += (strlen($text) >> 6) + 1; // ie. divide by 64 + $encrypted = openssl_encrypt( + $text . str_repeat("\0", 64), + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + $temp = Strings::pop($encrypted, 64); + } else { + $blocks = str_split($text, 64); + if (strlen($text)) { + foreach ($blocks as &$block) { + $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + } + $encrypted = implode('', $blocks); + $temp = static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + $ciphertext .= $encrypted . ($text2 ^ $temp); + $buffer['ciphertext'] = substr($temp, $overflow); + } elseif (!strlen($buffer['ciphertext'])) { + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $buffer['counter']) . $this->p2; + $buffer['counter'] += (strlen($text) >> 6); + $ciphertext .= openssl_encrypt( + $text, + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + } else { + $blocks = str_split($text, 64); + foreach ($blocks as &$block) { + $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + $ciphertext .= implode('', $blocks); + } + } + + return $ciphertext; + } + + /** + * Left Rotate + * + * @param int $x + * @param int $n + * @return int + */ + protected static function leftRotate($x, $n) + { + if (PHP_INT_SIZE == 8) { + $r1 = $x << $n; + $r1 &= 0xFFFFFFFF; + $r2 = ($x & 0xFFFFFFFF) >> (32 - $n); + } else { + $x = (int) $x; + $r1 = $x << $n; + $r2 = $x >> (32 - $n); + $r2 &= (1 << $n) - 1; + } + return $r1 | $r2; + } + + /** + * The quarterround function + * + * @param int $a + * @param int $b + * @param int $c + * @param int $d + */ + protected static function quarterRound(&$a, &$b, &$c, &$d) + { + $b ^= self::leftRotate($a + $d, 7); + $c ^= self::leftRotate($b + $a, 9); + $d ^= self::leftRotate($c + $b, 13); + $a ^= self::leftRotate($d + $c, 18); + } + + /** + * The doubleround function + * + * @param int $x0 (by reference) + * @param int $x1 (by reference) + * @param int $x2 (by reference) + * @param int $x3 (by reference) + * @param int $x4 (by reference) + * @param int $x5 (by reference) + * @param int $x6 (by reference) + * @param int $x7 (by reference) + * @param int $x8 (by reference) + * @param int $x9 (by reference) + * @param int $x10 (by reference) + * @param int $x11 (by reference) + * @param int $x12 (by reference) + * @param int $x13 (by reference) + * @param int $x14 (by reference) + * @param int $x15 (by reference) + */ + protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) + { + // columnRound + static::quarterRound($x0, $x4, $x8, $x12); + static::quarterRound($x5, $x9, $x13, $x1); + static::quarterRound($x10, $x14, $x2, $x6); + static::quarterRound($x15, $x3, $x7, $x11); + // rowRound + static::quarterRound($x0, $x1, $x2, $x3); + static::quarterRound($x5, $x6, $x7, $x4); + static::quarterRound($x10, $x11, $x8, $x9); + static::quarterRound($x15, $x12, $x13, $x14); + } + + /** + * The Salsa20 hash function function + * + * @param string $x + */ + protected static function salsa20($x) + { + $z = $x = unpack('V*', $x); + for ($i = 0; $i < 10; $i++) { + static::doubleRound($z[1], $z[2], $z[3], $z[4], $z[5], $z[6], $z[7], $z[8], $z[9], $z[10], $z[11], $z[12], $z[13], $z[14], $z[15], $z[16]); + } + + for ($i = 1; $i <= 16; $i++) { + $x[$i] += $z[$i]; + } + + return pack('V*', ...$x); + } + + /** + * Calculates Poly1305 MAC + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $ciphertext + * @return string + */ + protected function poly1305($ciphertext) + { + if (!$this->usingGeneratedPoly1305Key) { + return parent::poly1305($this->aad . $ciphertext); + } else { + /* + sodium_crypto_aead_chacha20poly1305_encrypt does not calculate the poly1305 tag + the same way sodium_crypto_aead_chacha20poly1305_ietf_encrypt does. you can see + how the latter encrypts it in Salsa20::encrypt(). here's how the former encrypts + it: + + $this->newtag = $this->poly1305( + $this->aad . + pack('V', strlen($this->aad)) . "\0\0\0\0" . + $ciphertext . + pack('V', strlen($ciphertext)) . "\0\0\0\0" + ); + + phpseclib opts to use the IETF construction, even when the nonce is 64-bits + instead of 96-bits + */ + return parent::poly1305( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + pack('V', strlen($this->aad)) . "\0\0\0\0" . + pack('V', strlen($ciphertext)) . "\0\0\0\0" + ); + } + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php similarity index 60% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php index a2c41668a..1ff5ed02b 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php @@ -12,7 +12,7 @@ * setKey('abcdefghijklmnopqrstuvwx'); * @@ -26,22 +26,18 @@ * ?> * * - * @category Crypt - * @package TripleDES * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; /** * Pure-PHP implementation of Triple DES. * - * @package TripleDES * @author Jim Wigginton - * @access public */ class TripleDES extends DES { @@ -55,161 +51,148 @@ class TripleDES extends DES /** * Encrypt / decrypt using outer chaining * - * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC. + * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC. */ - const MODE_CBC3 = Base::MODE_CBC; + const MODE_CBC3 = self::MODE_CBC; /** * Key Length (in bytes) * - * @see \phpseclib\Crypt\TripleDES::setKeyLength() + * @see \phpseclib3\Crypt\TripleDES::setKeyLength() * @var int - * @access private */ - var $key_length = 24; - - /** - * The default salt used by setPassword() - * - * @see \phpseclib\Crypt\Base::password_default_salt - * @see \phpseclib\Crypt\Base::setPassword() - * @var string - * @access private - */ - var $password_default_salt = 'phpseclib'; + protected $key_length = 24; /** * The mcrypt specific name of the cipher * - * @see \phpseclib\Crypt\DES::cipher_name_mcrypt - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt + * @see \phpseclib3\Crypt\DES::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt * @var string - * @access private */ - var $cipher_name_mcrypt = 'tripledes'; + protected $cipher_name_mcrypt = 'tripledes'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib\Crypt\Base::cfb_init_len + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len * @var int - * @access private */ - var $cfb_init_len = 750; + protected $cfb_init_len = 750; /** * max possible size of $key * * @see self::setKey() - * @see \phpseclib\Crypt\DES::setKey() + * @see \phpseclib3\Crypt\DES::setKey() * @var string - * @access private */ - var $key_length_max = 24; + protected $key_length_max = 24; /** * Internal flag whether using self::MODE_3CBC or not * * @var bool - * @access private */ - var $mode_3cbc; + private $mode_3cbc; /** - * The \phpseclib\Crypt\DES objects + * The \phpseclib3\Crypt\DES objects * * Used only if $mode_3cbc === true * * @var array - * @access private */ - var $des; + private $des; /** * Default Constructor. * - * Determines whether or not the mcrypt extension should be used. + * Determines whether or not the mcrypt or OpenSSL extensions should be used. * * $mode could be: * - * - \phpseclib\Crypt\Base::MODE_ECB + * - ecb * - * - \phpseclib\Crypt\Base::MODE_CBC + * - cbc * - * - \phpseclib\Crypt\Base::MODE_CTR + * - ctr * - * - \phpseclib\Crypt\Base::MODE_CFB + * - cfb * - * - \phpseclib\Crypt\Base::MODE_OFB + * - ofb * - * - \phpseclib\Crypt\TripleDES::MODE_3CBC + * - 3cbc * - * If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used. + * - cbc3 (same as cbc) * - * @see \phpseclib\Crypt\DES::__construct() - * @see \phpseclib\Crypt\Base::__construct() - * @param int $mode - * @access public + * @see \phpseclib3\Crypt\DES::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param string $mode */ - function __construct($mode = Base::MODE_CBC) + public function __construct($mode) { - switch ($mode) { + switch (strtolower($mode)) { // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC // and additional flag us internally as 3CBC - case self::MODE_3CBC: - parent::__construct(Base::MODE_CBC); + case '3cbc': + parent::__construct('cbc'); $this->mode_3cbc = true; // This three $des'es will do the 3CBC work (if $key > 64bits) - $this->des = array( - new DES(Base::MODE_CBC), - new DES(Base::MODE_CBC), - new DES(Base::MODE_CBC), - ); + $this->des = [ + new DES('cbc'), + new DES('cbc'), + new DES('cbc'), + ]; - // we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects + // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects $this->des[0]->disablePadding(); $this->des[1]->disablePadding(); $this->des[2]->disablePadding(); break; + case 'cbc3': + $mode = 'cbc'; + // fall-through // If not 3CBC, we init as usual default: parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } } } /** * Test for engine validity * - * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine() + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * - * @see \phpseclib\Crypt\Base::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @param int $engine - * @access public * @return bool */ - function isValidEngine($engine) + protected function isValidEngineHelper($engine) { if ($engine == self::ENGINE_OPENSSL) { $this->cipher_name_openssl_ecb = 'des-ede3'; - $mode = $this->_openssl_translate_mode(); + $mode = $this->openssl_translate_mode(); $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; } - return parent::isValidEngine($engine); + return parent::isValidEngineHelper($engine); } /** - * Sets the initialization vector. (optional) + * Sets the initialization vector. * - * SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used. If not explicitly set, it'll be assumed - * to be all zero's. + * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used. * - * @see \phpseclib\Crypt\Base::setIV() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::setIV() * @param string $iv */ - function setIV($iv) + public function setIV($iv) { parent::setIV($iv); if ($this->mode_3cbc) { @@ -222,24 +205,22 @@ class TripleDES extends DES /** * Sets the key length. * - * Valid key lengths are 64, 128 and 192 + * Valid key lengths are 128 and 192 bits. * - * @see \phpseclib\Crypt\Base:setKeyLength() - * @access public + * If you want to use a 64-bit key use DES.php + * + * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength() + * @throws \LengthException if the key length is invalid * @param int $length */ - function setKeyLength($length) + public function setKeyLength($length) { - $length >>= 3; - switch (true) { - case $length <= 8: - $this->key_length = 8; - break; - case $length <= 16: - $this->key_length = 16; + switch ($length) { + case 128: + case 192: break; default: - $this->key_length = 24; + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); } parent::setKeyLength($length); @@ -248,38 +229,40 @@ class TripleDES extends DES /** * Sets the key. * - * Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or - * 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate. + * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys. * * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * - * If the key is not explicitly set, it'll be assumed to be all null bytes. - * - * @access public - * @see \phpseclib\Crypt\DES::setKey() - * @see \phpseclib\Crypt\Base::setKey() + * @see \phpseclib3\Crypt\DES::setKey() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @throws \LengthException if the key length is invalid * @param string $key */ - function setKey($key) + public function setKey($key) { - $length = $this->explicit_key_length ? $this->key_length : strlen($key); - if ($length > 8) { - $key = str_pad(substr($key, 0, 24), 24, chr(0)); - // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this: - // http://php.net/function.mcrypt-encrypt#47973 - $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24); - } else { - $key = str_pad($key, 8, chr(0)); + if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { + throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); } - parent::setKey($key); - // And in case of self::MODE_3CBC: - // if key <= 64bits we not need the 3 $des to work, - // because we will then act as regular DES-CBC with just a <= 64bit key. - // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des. - if ($this->mode_3cbc && $length > 8) { - $this->des[0]->setKey(substr($key, 0, 8)); - $this->des[1]->setKey(substr($key, 8, 8)); + switch (strlen($key)) { + case 16: + $key .= substr($key, 0, 8); + break; + case 24: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); + } + + // copied from self::setKey() + $this->key = $key; + $this->key_length = strlen($key); + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + + if ($this->mode_3cbc) { + $this->des[0]->setKey(substr($key, 0, 8)); + $this->des[1]->setKey(substr($key, 8, 8)); $this->des[2]->setKey(substr($key, 16, 8)); } } @@ -287,12 +270,11 @@ class TripleDES extends DES /** * Encrypts a message. * - * @see \phpseclib\Crypt\Base::encrypt() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @param string $plaintext * @return string $cipertext */ - function encrypt($plaintext) + public function encrypt($plaintext) { // parent::en/decrypt() is able to do all the work for all modes and keylengths, // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits @@ -302,7 +284,7 @@ class TripleDES extends DES return $this->des[2]->encrypt( $this->des[1]->decrypt( $this->des[0]->encrypt( - $this->_pad($plaintext) + $this->pad($plaintext) ) ) ); @@ -314,15 +296,14 @@ class TripleDES extends DES /** * Decrypts a message. * - * @see \phpseclib\Crypt\Base::decrypt() - * @access public + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() * @param string $ciphertext * @return string $plaintext */ - function decrypt($ciphertext) + public function decrypt($ciphertext) { if ($this->mode_3cbc && strlen($this->key) > 8) { - return $this->_unpad( + return $this->unpad( $this->des[0]->decrypt( $this->des[1]->encrypt( $this->des[2]->decrypt( @@ -365,16 +346,15 @@ class TripleDES extends DES * outputs. The reason is due to the fact that the initialization vector's change after every encryption / * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. * - * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\DES() object changes after each + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * however, they are also less intuitive and more likely to cause you problems. * - * @see \phpseclib\Crypt\Base::enableContinuousBuffer() + * @see \phpseclib3\Crypt\Common\SymmetricKey::enableContinuousBuffer() * @see self::disableContinuousBuffer() - * @access public */ - function enableContinuousBuffer() + public function enableContinuousBuffer() { parent::enableContinuousBuffer(); if ($this->mode_3cbc) { @@ -389,11 +369,10 @@ class TripleDES extends DES * * The default behavior. * - * @see \phpseclib\Crypt\Base::disableContinuousBuffer() + * @see \phpseclib3\Crypt\Common\SymmetricKey::disableContinuousBuffer() * @see self::enableContinuousBuffer() - * @access public */ - function disableContinuousBuffer() + public function disableContinuousBuffer() { parent::disableContinuousBuffer(); if ($this->mode_3cbc) { @@ -406,11 +385,10 @@ class TripleDES extends DES /** * Creates the key schedule * - * @see \phpseclib\Crypt\DES::_setupKey() - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() */ - function _setupKey() + protected function setupKey() { switch (true) { // if $key <= 64bits we configure our internal pure-php cipher engine @@ -425,29 +403,27 @@ class TripleDES extends DES // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. if ($this->mode_3cbc) { - $this->des[0]->_setupKey(); - $this->des[1]->_setupKey(); - $this->des[2]->_setupKey(); + $this->des[0]->setupKey(); + $this->des[1]->setupKey(); + $this->des[2]->setupKey(); // because $des[0-2] will, now, do all the work we can return here - // not need unnecessary stress parent::_setupKey() with our, now unused, $key. + // not need unnecessary stress parent::setupKey() with our, now unused, $key. return; } } // setup our key - parent::_setupKey(); + parent::setupKey(); } /** * Sets the internal crypt engine * - * @see \phpseclib\Crypt\Base::__construct() - * @see \phpseclib\Crypt\Base::setPreferredEngine() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setPreferredEngine() * @param int $engine - * @access public - * @return int */ - function setPreferredEngine($engine) + public function setPreferredEngine($engine) { if ($this->mode_3cbc) { $this->des[0]->setPreferredEngine($engine); @@ -455,6 +431,6 @@ class TripleDES extends DES $this->des[2]->setPreferredEngine($engine); } - return parent::setPreferredEngine($engine); + parent::setPreferredEngine($engine); } } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php similarity index 72% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php index 70980a2ff..bf765632a 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php @@ -16,7 +16,7 @@ * setKey('12345678901234567890123456789012'); * @@ -26,8 +26,6 @@ * ?> * * - * @category Crypt - * @package Twofish * @author Jim Wigginton * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton @@ -35,43 +33,41 @@ * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Crypt; +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; /** * Pure-PHP implementation of Twofish. * - * @package Twofish * @author Jim Wigginton * @author Hans-Juergen Petrich - * @access public */ -class Twofish extends Base +class Twofish extends BlockCipher { /** * The mcrypt specific name of the cipher * - * @see \phpseclib\Crypt\Base::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt * @var string - * @access private */ - var $cipher_name_mcrypt = 'twofish'; + protected $cipher_name_mcrypt = 'twofish'; /** * Optimizing value while CFB-encrypting * - * @see \phpseclib\Crypt\Base::cfb_init_len + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len * @var int - * @access private */ - var $cfb_init_len = 800; + protected $cfb_init_len = 800; /** * Q-Table * * @var array - * @access private */ - var $q0 = array( + private static $q0 = [ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, @@ -104,15 +100,14 @@ class Twofish extends Base 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 - ); + ]; /** * Q-Table * * @var array - * @access private */ - var $q1 = array( + private static $q1 = [ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, @@ -145,15 +140,14 @@ class Twofish extends Base 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 - ); + ]; /** * M-Table * * @var array - * @access private */ - var $m0 = array( + private static $m0 = [ 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, @@ -186,15 +180,14 @@ class Twofish extends Base 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 - ); + ]; /** * M-Table * * @var array - * @access private */ - var $m1 = array( + private static $m1 = [ 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, @@ -227,15 +220,14 @@ class Twofish extends Base 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 - ); + ]; /** * M-Table * * @var array - * @access private */ - var $m2 = array( + private static $m2 = [ 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, @@ -268,15 +260,14 @@ class Twofish extends Base 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF - ); + ]; /** * M-Table * * @var array - * @access private */ - var $m3 = array( + private static $m3 = [ 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, @@ -309,120 +300,164 @@ class Twofish extends Base 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 - ); + ]; /** * The Key Schedule Array * * @var array - * @access private */ - var $K = array(); + private $K = []; /** * The Key depended S-Table 0 * * @var array - * @access private */ - var $S0 = array(); + private $S0 = []; /** * The Key depended S-Table 1 * * @var array - * @access private */ - var $S1 = array(); + private $S1 = []; /** * The Key depended S-Table 2 * * @var array - * @access private */ - var $S2 = array(); + private $S2 = []; /** * The Key depended S-Table 3 * * @var array - * @access private */ - var $S3 = array(); + private $S3 = []; /** * Holds the last used key * * @var array - * @access private */ - var $kl; + private $kl; /** * The Key Length (in bytes) * * @see Crypt_Twofish::setKeyLength() * @var int - * @access private */ - var $key_length = 16; + protected $key_length = 16; + + /** + * Default Constructor. + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Initialize Static Variables + */ + protected static function initialize_static_variables() + { + if (is_float(self::$m3[0])) { + self::$m0 = array_map('intval', self::$m0); + self::$m1 = array_map('intval', self::$m1); + self::$m2 = array_map('intval', self::$m2); + self::$m3 = array_map('intval', self::$m3); + self::$q0 = array_map('intval', self::$q0); + self::$q1 = array_map('intval', self::$q1); + } + + parent::initialize_static_variables(); + } /** * Sets the key length. * * Valid key lengths are 128, 192 or 256 bits * - * @access public * @param int $length */ - function setKeyLength($length) + public function setKeyLength($length) { - switch (true) { - case $length <= 128: - $this->key_length = 16; - break; - case $length <= 192: - $this->key_length = 24; + switch ($length) { + case 128: + case 192: + case 256: break; default: - $this->key_length = 32; + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); } parent::setKeyLength($length); } + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKey($key); + } + /** * Setup the key (expansion) * - * @see \phpseclib\Crypt\Base::_setupKey() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() */ - function _setupKey() + protected function setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key']) { // already expanded return; } - $this->kl = array('key' => $this->key); + $this->kl = ['key' => $this->key]; /* Key expanding and generating the key-depended s-boxes */ $le_longs = unpack('V*', $this->key); $key = unpack('C*', $this->key); - $m0 = $this->m0; - $m1 = $this->m1; - $m2 = $this->m2; - $m3 = $this->m3; - $q0 = $this->q0; - $q1 = $this->q1; + $m0 = self::$m0; + $m1 = self::$m1; + $m2 = self::$m2; + $m3 = self::$m3; + $q0 = self::$q0; + $q1 = self::$q1; - $K = $S0 = $S1 = $S2 = $S3 = array(); + $K = $S0 = $S1 = $S2 = $S3 = []; switch (strlen($this->key)) { case 16: - list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]); - list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]); - for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[3], $le_longs[4]); + for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^ @@ -432,9 +467,9 @@ class Twofish extends Base $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); - $A = $this->safe_intval($A + $B); + $A = self::safe_intval($A + $B); $K[] = $A; - $A = $this->safe_intval($A + $B); + $A = self::safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { @@ -445,10 +480,10 @@ class Twofish extends Base } break; case 24: - list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]); - list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]); - list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]); - for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { + list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[5], $le_longs[6]); + for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ @@ -458,9 +493,9 @@ class Twofish extends Base $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); - $A = $this->safe_intval($A + $B); + $A = self::safe_intval($A + $B); $K[] = $A; - $A = $this->safe_intval($A + $B); + $A = self::safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { @@ -471,11 +506,11 @@ class Twofish extends Base } break; default: // 32 - list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]); - list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]); - list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]); - list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]); - for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) { + list($sf, $se, $sd, $sc) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[5], $le_longs[6]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[7], $le_longs[8]); + for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ @@ -485,9 +520,9 @@ class Twofish extends Base $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); - $A = $this->safe_intval($A + $B); + $A = self::safe_intval($A + $B); $K[] = $A; - $A = $this->safe_intval($A + $B); + $A = self::safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { @@ -508,12 +543,11 @@ class Twofish extends Base /** * _mdsrem function using by the twofish cipher algorithm * - * @access private * @param string $A * @param string $B * @return array */ - function _mdsrem($A, $B) + private function mdsrem($A, $B) { // No gain by unrolling this loop. for ($i = 0; $i < 8; ++$i) { @@ -522,45 +556,44 @@ class Twofish extends Base // Shift the others up. $B = ($B << 8) | (0xff & ($A >> 24)); - $A<<= 8; + $A <<= 8; $u = $t << 1; // Subtract the modular polynomial on overflow. if ($t & 0x80) { - $u^= 0x14d; + $u ^= 0x14d; } // Remove t * (a * x^2 + 1). $B ^= $t ^ ($u << 16); // Form u = a*t + t/a = t*(a + 1/a). - $u^= 0x7fffffff & ($t >> 1); + $u ^= 0x7fffffff & ($t >> 1); // Add the modular polynomial on underflow. if ($t & 0x01) { - $u^= 0xa6 ; + $u ^= 0xa6 ; } // Remove t * (a + 1/a) * (x^3 + x). - $B^= ($u << 24) | ($u << 8); + $B ^= ($u << 24) | ($u << 8); } - return array( + return [ 0xff & $B >> 24, 0xff & $B >> 16, 0xff & $B >> 8, - 0xff & $B); + 0xff & $B]; } /** * Encrypts a block * - * @access private * @param string $in * @return string */ - function _encryptBlock($in) + protected function encryptBlock($in) { $S0 = $this->S0; $S1 = $this->S1; @@ -584,9 +617,9 @@ class Twofish extends Base $S1[ $R1 & 0xff] ^ $S2[($R1 >> 8) & 0xff] ^ $S3[($R1 >> 16) & 0xff]; - $R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]); + $R2 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); - $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); $t0 = $S0[ $R2 & 0xff] ^ $S1[($R2 >> 8) & 0xff] ^ @@ -596,9 +629,9 @@ class Twofish extends Base $S1[ $R3 & 0xff] ^ $S2[($R3 >> 8) & 0xff] ^ $S3[($R3 >> 16) & 0xff]; - $R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]); + $R0 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); - $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); } // @codingStandardsIgnoreStart @@ -612,11 +645,10 @@ class Twofish extends Base /** * Decrypts a block * - * @access private * @param string $in * @return string */ - function _decryptBlock($in) + protected function decryptBlock($in) { $S0 = $this->S0; $S1 = $this->S1; @@ -640,9 +672,9 @@ class Twofish extends Base $S1[$R1 & 0xff] ^ $S2[$R1 >> 8 & 0xff] ^ $S3[$R1 >> 16 & 0xff]; - $R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R3 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; - $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]); + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); $t0 = $S0[$R2 & 0xff] ^ $S1[$R2 >> 8 & 0xff] ^ @@ -652,9 +684,9 @@ class Twofish extends Base $S1[$R3 & 0xff] ^ $S2[$R3 >> 8 & 0xff] ^ $S3[$R3 >> 16 & 0xff]; - $R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R1 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; - $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]); + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); } // @codingStandardsIgnoreStart @@ -668,149 +700,117 @@ class Twofish extends Base /** * Setup the performance-optimized function for de/encrypt() * - * @see \phpseclib\Crypt\Base::_setupInlineCrypt() - * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() */ - function _setupInlineCrypt() + protected function setupInlineCrypt() { - $lambda_functions =& self::_getLambdaFunctions(); - - // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one. - // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit) - $gen_hi_opt_code = (bool)(count($lambda_functions) < 10); - - // Generation of a unique hash for our generated code - $code_hash = "Crypt_Twofish, {$this->mode}"; - if ($gen_hi_opt_code) { - $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); - } - - $safeint = $this->safe_intval_inline(); - - if (!isset($lambda_functions[$code_hash])) { - switch (true) { - case $gen_hi_opt_code: - $K = $this->K; - $init_crypt = ' - static $S0, $S1, $S2, $S3; - if (!$S0) { - for ($i = 0; $i < 256; ++$i) { - $S0[] = (int)$self->S0[$i]; - $S1[] = (int)$self->S1[$i]; - $S2[] = (int)$self->S2[$i]; - $S3[] = (int)$self->S3[$i]; - } - } - '; - break; - default: - $K = array(); - for ($i = 0; $i < 40; ++$i) { - $K[] = '$K_' . $i; - } - $init_crypt = ' - $S0 = $self->S0; - $S1 = $self->S1; - $S2 = $self->S2; - $S3 = $self->S3; - list(' . implode(',', $K) . ') = $self->K; - '; + $K = $this->K; + $init_crypt = ' + static $S0, $S1, $S2, $S3; + if (!$S0) { + for ($i = 0; $i < 256; ++$i) { + $S0[] = (int)$this->S0[$i]; + $S1[] = (int)$this->S1[$i]; + $S2[] = (int)$this->S2[$i]; + $S3[] = (int)$this->S3[$i]; + } } + '; - // Generating encrypt code: - $encrypt_block = ' - $in = unpack("V4", $in); - $R0 = '.$K[0].' ^ $in[1]; - $R1 = '.$K[1].' ^ $in[2]; - $R2 = '.$K[2].' ^ $in[3]; - $R3 = '.$K[3].' ^ $in[4]; - '; - for ($ki = 7, $i = 0; $i < 8; ++$i) { - $encrypt_block.= ' - $t0 = $S0[ $R0 & 0xff] ^ - $S1[($R0 >> 8) & 0xff] ^ - $S2[($R0 >> 16) & 0xff] ^ - $S3[($R0 >> 24) & 0xff]; - $t1 = $S0[($R1 >> 24) & 0xff] ^ - $S1[ $R1 & 0xff] ^ - $S2[($R1 >> 8) & 0xff] ^ - $S3[($R1 >> 16) & 0xff]; + $safeint = self::safe_intval_inline(); + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("V4", $in); + $R0 = ' . $K[0] . ' ^ $in[1]; + $R1 = ' . $K[1] . ' ^ $in[2]; + $R2 = ' . $K[2] . ' ^ $in[3]; + $R3 = ' . $K[3] . ' ^ $in[4]; + '; + for ($ki = 7, $i = 0; $i < 8; ++$i) { + $encrypt_block .= ' + $t0 = $S0[ $R0 & 0xff] ^ + $S1[($R0 >> 8) & 0xff] ^ + $S2[($R0 >> 16) & 0xff] ^ + $S3[($R0 >> 24) & 0xff]; + $t1 = $S0[($R1 >> 24) & 0xff] ^ + $S1[ $R1 & 0xff] ^ + $S2[($R1 >> 8) & 0xff] ^ + $S3[($R1 >> 16) & 0xff]; $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . '; - $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); - $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; - $t0 = $S0[ $R2 & 0xff] ^ - $S1[($R2 >> 8) & 0xff] ^ - $S2[($R2 >> 16) & 0xff] ^ - $S3[($R2 >> 24) & 0xff]; - $t1 = $S0[($R3 >> 24) & 0xff] ^ - $S1[ $R3 & 0xff] ^ - $S2[($R3 >> 8) & 0xff] ^ - $S3[($R3 >> 16) & 0xff]; - $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; - $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); - $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; - '; - } - $encrypt_block.= ' - $in = pack("V4", ' . $K[4] . ' ^ $R2, - ' . $K[5] . ' ^ $R3, - ' . $K[6] . ' ^ $R0, - ' . $K[7] . ' ^ $R1); + $t0 = $S0[ $R2 & 0xff] ^ + $S1[($R2 >> 8) & 0xff] ^ + $S2[($R2 >> 16) & 0xff] ^ + $S3[($R2 >> 24) & 0xff]; + $t1 = $S0[($R3 >> 24) & 0xff] ^ + $S1[ $R3 & 0xff] ^ + $S2[($R3 >> 8) & 0xff] ^ + $S3[($R3 >> 16) & 0xff]; + $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; + $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; '; - - // Generating decrypt code: - $decrypt_block = ' - $in = unpack("V4", $in); - $R0 = '.$K[4].' ^ $in[1]; - $R1 = '.$K[5].' ^ $in[2]; - $R2 = '.$K[6].' ^ $in[3]; - $R3 = '.$K[7].' ^ $in[4]; - '; - for ($ki = 40, $i = 0; $i < 8; ++$i) { - $decrypt_block.= ' - $t0 = $S0[$R0 & 0xff] ^ - $S1[$R0 >> 8 & 0xff] ^ - $S2[$R0 >> 16 & 0xff] ^ - $S3[$R0 >> 24 & 0xff]; - $t1 = $S0[$R1 >> 24 & 0xff] ^ - $S1[$R1 & 0xff] ^ - $S2[$R1 >> 8 & 0xff] ^ - $S3[$R1 >> 16 & 0xff]; - $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; - $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; - $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; - - $t0 = $S0[$R2 & 0xff] ^ - $S1[$R2 >> 8 & 0xff] ^ - $S2[$R2 >> 16 & 0xff] ^ - $S3[$R2 >> 24 & 0xff]; - $t1 = $S0[$R3 >> 24 & 0xff] ^ - $S1[$R3 & 0xff] ^ - $S2[$R3 >> 8 & 0xff] ^ - $S3[$R3 >> 16 & 0xff]; - $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; - $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; - $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . '; - '; - } - $decrypt_block.= ' - $in = pack("V4", ' . $K[0] . ' ^ $R2, - ' . $K[1] . ' ^ $R3, - ' . $K[2] . ' ^ $R0, - ' . $K[3] . ' ^ $R1); - '; - - $lambda_functions[$code_hash] = $this->_createInlineCryptFunction( - array( - 'init_crypt' => $init_crypt, - 'init_encrypt' => '', - 'init_decrypt' => '', - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ) - ); } - $this->inline_crypt = $lambda_functions[$code_hash]; + $encrypt_block .= ' + $in = pack("V4", ' . $K[4] . ' ^ $R2, + ' . $K[5] . ' ^ $R3, + ' . $K[6] . ' ^ $R0, + ' . $K[7] . ' ^ $R1); + '; + + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("V4", $in); + $R0 = ' . $K[4] . ' ^ $in[1]; + $R1 = ' . $K[5] . ' ^ $in[2]; + $R2 = ' . $K[6] . ' ^ $in[3]; + $R3 = ' . $K[7] . ' ^ $in[4]; + '; + for ($ki = 40, $i = 0; $i < 8; ++$i) { + $decrypt_block .= ' + $t0 = $S0[$R0 & 0xff] ^ + $S1[$R0 >> 8 & 0xff] ^ + $S2[$R0 >> 16 & 0xff] ^ + $S3[$R0 >> 24 & 0xff]; + $t1 = $S0[$R1 >> 24 & 0xff] ^ + $S1[$R1 & 0xff] ^ + $S2[$R1 >> 8 & 0xff] ^ + $S3[$R1 >> 16 & 0xff]; + $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; + + $t0 = $S0[$R2 & 0xff] ^ + $S1[$R2 >> 8 & 0xff] ^ + $S2[$R2 >> 16 & 0xff] ^ + $S3[$R2 >> 24 & 0xff]; + $t1 = $S0[$R3 >> 24 & 0xff] ^ + $S1[$R3 & 0xff] ^ + $S2[$R3 >> 8 & 0xff] ^ + $S3[$R3 >> 16 & 0xff]; + $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; + '; + } + $decrypt_block .= ' + $in = pack("V4", ' . $K[0] . ' ^ $R2, + ' . $K[1] . ' ^ $R3, + ' . $K[2] . ' ^ $R0, + ' . $K[3] . ' ^ $R1); + '; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php new file mode 100644 index 000000000..1aabcae09 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadConfigurationException + * + * @author Jim Wigginton + */ +class BadConfigurationException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php new file mode 100644 index 000000000..88331dce0 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadDecryptionException + * + * @author Jim Wigginton + */ +class BadDecryptionException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php new file mode 100644 index 000000000..87689b224 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadModeException + * + * @author Jim Wigginton + */ +class BadModeException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php new file mode 100644 index 000000000..6aaccbad6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * ConnectionClosedException + * + * @author Jim Wigginton + */ +class ConnectionClosedException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php new file mode 100644 index 000000000..66e727091 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * FileNotFoundException + * + * @author Jim Wigginton + */ +class FileNotFoundException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php new file mode 100644 index 000000000..23c38fb02 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * InconsistentSetupException + * + * @author Jim Wigginton + */ +class InconsistentSetupException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php new file mode 100644 index 000000000..4f4114d70 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * InsufficientSetupException + * + * @author Jim Wigginton + */ +class InsufficientSetupException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php new file mode 100644 index 000000000..7ec2fe9b9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * NoKeyLoadedException + * + * @author Jim Wigginton + */ +class NoKeyLoadedException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php new file mode 100644 index 000000000..b3ea8f384 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * NoSupportedAlgorithmsException + * + * @author Jim Wigginton + */ +class NoSupportedAlgorithmsException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php new file mode 100644 index 000000000..bfa005b4f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnableToConnectException + * + * @author Jim Wigginton + */ +class UnableToConnectException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php new file mode 100644 index 000000000..210a9a5ce --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedAlgorithmException + * + * @author Jim Wigginton + */ +class UnsupportedAlgorithmException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php new file mode 100644 index 000000000..99152152c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedCurveException + * + * @author Jim Wigginton + */ +class UnsupportedCurveException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php new file mode 100644 index 000000000..e207d7e21 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedFormatException + * + * @author Jim Wigginton + */ +class UnsupportedFormatException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php new file mode 100644 index 000000000..9a1154445 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedOperationException + * + * @author Jim Wigginton + */ +class UnsupportedOperationException extends \RuntimeException +{ +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php similarity index 84% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php index b6874d357..5803a372d 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php @@ -5,27 +5,23 @@ * * PHP version 5 * - * If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back. + * If you call read() in \phpseclib3\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back. * They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a * {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what - * color to display them in, etc. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator. + * color to display them in, etc. \phpseclib3\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator. * - * @category File - * @package ANSI * @author Jim Wigginton * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\File; +namespace phpseclib3\File; /** * Pure-PHP ANSI Decoder * - * @package ANSI * @author Jim Wigginton - * @access public */ class ANSI { @@ -33,137 +29,120 @@ class ANSI * Max Width * * @var int - * @access private */ - var $max_x; + private $max_x; /** * Max Height * * @var int - * @access private */ - var $max_y; + private $max_y; /** * Max History * * @var int - * @access private */ - var $max_history; + private $max_history; /** * History * * @var array - * @access private */ - var $history; + private $history; /** * History Attributes * * @var array - * @access private */ - var $history_attrs; + private $history_attrs; /** * Current Column * * @var int - * @access private */ - var $x; + private $x; /** * Current Row * * @var int - * @access private */ - var $y; + private $y; /** * Old Column * * @var int - * @access private */ - var $old_x; + private $old_x; /** * Old Row * * @var int - * @access private */ - var $old_y; + private $old_y; /** * An empty attribute cell * * @var object - * @access private */ - var $base_attr_cell; + private $base_attr_cell; /** * The current attribute cell * * @var object - * @access private */ - var $attr_cell; + private $attr_cell; /** * An empty attribute row * * @var array - * @access private */ - var $attr_row; + private $attr_row; /** * The current screen text * - * @var array - * @access private + * @var list */ - var $screen; + private $screen; /** * The current screen attributes * * @var array - * @access private */ - var $attrs; + private $attrs; /** * Current ANSI code * * @var string - * @access private */ - var $ansi; + private $ansi; /** * Tokenization * * @var array - * @access private */ - var $tokenization; + private $tokenization; /** * Default Constructor. * - * @return \phpseclib\File\ANSI - * @access public + * @return \phpseclib3\File\ANSI */ - function __construct() + public function __construct() { $attr_cell = new \stdClass(); $attr_cell->bold = false; @@ -186,14 +165,13 @@ class ANSI * * @param int $x * @param int $y - * @access public */ - function setDimensions($x, $y) + public function setDimensions($x, $y) { $this->max_x = $x - 1; $this->max_y = $y - 1; $this->x = $this->y = 0; - $this->history = $this->history_attrs = array(); + $this->history = $this->history_attrs = []; $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell); $this->screen = array_fill(0, $this->max_y + 1, ''); $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row); @@ -204,9 +182,8 @@ class ANSI * Set the number of lines that should be logged past the terminal height * * @param int $history - * @access public */ - function setHistory($history) + public function setHistory($history) { $this->max_history = $history; } @@ -215,9 +192,8 @@ class ANSI * Load a string * * @param string $source - * @access public */ - function loadString($source) + public function loadString($source) { $this->setDimensions($this->max_x + 1, $this->max_y + 1); $this->appendString($source); @@ -227,14 +203,13 @@ class ANSI * Appdend a string * * @param string $source - * @access public */ - function appendString($source) + public function appendString($source) { - $this->tokenization = array(''); + $this->tokenization = ['']; for ($i = 0; $i < strlen($source); $i++) { if (strlen($this->ansi)) { - $this->ansi.= $source[$i]; + $this->ansi .= $source[$i]; $chr = ord($source[$i]); // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements // single character CSI's not currently supported @@ -268,6 +243,7 @@ class ANSI array_shift($this->history); array_shift($this->history_attrs); } + // fall-through case "\x1B[K": // Clear screen from cursor right $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); @@ -282,28 +258,28 @@ class ANSI case "\x1B(B": // set united states g0 character set break; case "\x1BE": // Move to next line - $this->_newLine(); + $this->newLine(); $this->x = 0; break; default: switch (true) { case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines $this->old_y = $this->y; - $this->y+= $match[1]; + $this->y += (int) $match[1]; break; case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h $this->old_x = $this->x; $this->old_y = $this->y; $this->x = $match[2] - 1; - $this->y = $match[1] - 1; + $this->y = (int) $match[1] - 1; break; case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines $this->old_x = $this->x; - $this->x+= $match[1]; + $this->x += $match[1]; break; case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines $this->old_x = $this->x; - $this->x-= $match[1]; + $this->x -= $match[1]; if ($this->x < 0) { $this->x = 0; } @@ -376,13 +352,13 @@ class ANSI continue; } - $this->tokenization[count($this->tokenization) - 1].= $source[$i]; + $this->tokenization[count($this->tokenization) - 1] .= $source[$i]; switch ($source[$i]) { case "\r": $this->x = 0; break; case "\n": - $this->_newLine(); + $this->newLine(); break; case "\x08": // backspace if ($this->x) { @@ -403,7 +379,7 @@ class ANSI //if (!strlen($this->tokenization[count($this->tokenization) - 1])) { // array_pop($this->tokenization); //} - $this->ansi.= "\x1B"; + $this->ansi .= "\x1B"; break; default: $this->attrs[$this->y][$this->x] = clone $this->attr_cell; @@ -419,7 +395,7 @@ class ANSI if ($this->x > $this->max_x) { $this->x = 0; - $this->_newLine(); + $this->newLine(); } else { $this->x++; } @@ -432,19 +408,18 @@ class ANSI * * Also update the $this->screen and $this->history buffers * - * @access private */ - function _newLine() + private function newLine() { //if ($this->y < $this->max_y) { // $this->y++; //} while ($this->y >= $this->max_y) { - $this->history = array_merge($this->history, array(array_shift($this->screen))); + $this->history = array_merge($this->history, [array_shift($this->screen)]); $this->screen[] = ''; - $this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs))); + $this->history_attrs = array_merge($this->history_attrs, [array_shift($this->attrs)]); $this->attrs[] = $this->attr_row; if (count($this->history) >= $this->max_history) { @@ -460,10 +435,12 @@ class ANSI /** * Returns the current coordinate without preformating * - * @access private + * @param \stdClass $last_attr + * @param \stdClass $cur_attr + * @param string $char * @return string */ - function _processCoordinate($last_attr, $cur_attr, $char) + private function processCoordinate(\stdClass $last_attr, \stdClass $cur_attr, $char) { $output = ''; @@ -471,7 +448,7 @@ class ANSI $close = $open = ''; if ($last_attr->foreground != $cur_attr->foreground) { if ($cur_attr->foreground != 'white') { - $open.= ''; + $open .= ''; } if ($last_attr->foreground != 'white') { $close = '' . $close; @@ -479,7 +456,7 @@ class ANSI } if ($last_attr->background != $cur_attr->background) { if ($cur_attr->background != 'black') { - $open.= ''; + $open .= ''; } if ($last_attr->background != 'black') { $close = '' . $close; @@ -487,29 +464,29 @@ class ANSI } if ($last_attr->bold != $cur_attr->bold) { if ($cur_attr->bold) { - $open.= ''; + $open .= ''; } else { $close = '' . $close; } } if ($last_attr->underline != $cur_attr->underline) { if ($cur_attr->underline) { - $open.= ''; + $open .= ''; } else { $close = '' . $close; } } if ($last_attr->blink != $cur_attr->blink) { if ($cur_attr->blink) { - $open.= ''; + $open .= ''; } else { $close = '' . $close; } } - $output.= $close . $open; + $output .= $close . $open; } - $output.= htmlspecialchars($char); + $output .= htmlspecialchars($char); return $output; } @@ -517,59 +494,56 @@ class ANSI /** * Returns the current screen without preformating * - * @access private * @return string */ - function _getScreen() + private function getScreenHelper() { $output = ''; $last_attr = $this->base_attr_cell; for ($i = 0; $i <= $this->max_y; $i++) { for ($j = 0; $j <= $this->max_x; $j++) { $cur_attr = $this->attrs[$i][$j]; - $output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); + $output .= $this->processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); $last_attr = $this->attrs[$i][$j]; } - $output.= "\r\n"; + $output .= "\r\n"; } $output = substr($output, 0, -2); // close any remaining open tags - $output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, ''); + $output .= $this->processCoordinate($last_attr, $this->base_attr_cell, ''); return rtrim($output); } /** * Returns the current screen * - * @access public * @return string */ - function getScreen() + public function getScreen() { - return '
' . $this->_getScreen() . '
'; + return '
' . $this->getScreenHelper() . '
'; } /** * Returns the current screen and the x previous lines * - * @access public * @return string */ - function getHistory() + public function getHistory() { $scrollback = ''; $last_attr = $this->base_attr_cell; for ($i = 0; $i < count($this->history); $i++) { for ($j = 0; $j <= $this->max_x + 1; $j++) { $cur_attr = $this->history_attrs[$i][$j]; - $scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); + $scrollback .= $this->processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); $last_attr = $this->history_attrs[$i][$j]; } - $scrollback.= "\r\n"; + $scrollback .= "\r\n"; } $base_attr_cell = $this->base_attr_cell; $this->base_attr_cell = $last_attr; - $scrollback.= $this->_getScreen(); + $scrollback .= $this->getScreen(); $this->base_attr_cell = $base_attr_cell; return '
' . $scrollback . '
'; diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php similarity index 78% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php index fb2d64485..3096ff1a1 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -9,52 +9,38 @@ * utilized scheme is DER or the "Distinguished Encoding Rules". PEM's are base64 encoded * DER blobs. * - * \phpseclib\File\ASN1 decodes and encodes DER formatted messages and places them in a semantic context. + * \phpseclib3\File\ASN1 decodes and encodes DER formatted messages and places them in a semantic context. * * Uses the 1988 ASN.1 syntax. * - * @category File - * @package ASN1 * @author Jim Wigginton * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\File; +namespace phpseclib3\File; -use phpseclib\File\ASN1\Element; -use phpseclib\Math\BigInteger; -use DateTime; -use DateTimeZone; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\File\ASN1\Element; +use phpseclib3\Math\BigInteger; /** * Pure-PHP ASN.1 Parser * - * @package ASN1 * @author Jim Wigginton - * @access public */ -class ASN1 +abstract class ASN1 { - /**#@+ - * Tag Classes - * - * @access private - * @link http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 - */ + // Tag Classes + // http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 const CLASS_UNIVERSAL = 0; const CLASS_APPLICATION = 1; const CLASS_CONTEXT_SPECIFIC = 2; const CLASS_PRIVATE = 3; - /**#@-*/ - /**#@+ - * Tag Classes - * - * @access private - * @link http://www.obj-sys.com/asn1tutorial/node124.html - */ + // Tag Classes + // http://www.obj-sys.com/asn1tutorial/node124.html const TYPE_BOOLEAN = 1; const TYPE_INTEGER = 2; const TYPE_BIT_STRING = 3; @@ -70,13 +56,9 @@ class ASN1 //const TYPE_RELATIVE_OID = 13; const TYPE_SEQUENCE = 16; // SEQUENCE OF const TYPE_SET = 17; // SET OF - /**#@-*/ - /**#@+ - * More Tag Classes - * - * @access private - * @link http://www.obj-sys.com/asn1tutorial/node10.html - */ + + // More Tag Classes + // http://www.obj-sys.com/asn1tutorial/node10.html const TYPE_NUMERIC_STRING = 18; const TYPE_PRINTABLE_STRING = 19; const TYPE_TELETEX_STRING = 20; // T61String @@ -90,47 +72,34 @@ class ASN1 const TYPE_UNIVERSAL_STRING = 28; //const TYPE_CHARACTER_STRING = 29; const TYPE_BMP_STRING = 30; - /**#@-*/ - /**#@+ - * Tag Aliases - * - * These tags are kinda place holders for other tags. - * - * @access private - */ + // Tag Aliases + // These tags are kinda place holders for other tags. const TYPE_CHOICE = -1; const TYPE_ANY = -2; - /**#@-*/ /** - * ASN.1 object identifier + * ASN.1 object identifiers * * @var array - * @access private * @link http://en.wikipedia.org/wiki/Object_identifier */ - var $oids = array(); + private static $oids = []; + + /** + * ASN.1 object identifier reverse mapping + * + * @var array + */ + private static $reverseOIDs = []; /** * Default date format * * @var string - * @access private * @link http://php.net/class.datetime */ - var $format = 'D, d M Y H:i:s O'; - - /** - * Default date format - * - * @var array - * @access private - * @see self::setTimeFormat() - * @see self::asn1map() - * @link http://php.net/class.datetime - */ - var $encoded; + private static $format = 'D, d M Y H:i:s O'; /** * Filters @@ -138,22 +107,40 @@ class ASN1 * If the mapping type is self::TYPE_ANY what do we actually encode it as? * * @var array - * @access private - * @see self::_encode_der() + * @see self::encode_der() */ - var $filters; + private static $filters; + + /** + * Current Location of most recent ASN.1 encode process + * + * Useful for debug purposes + * + * @var array + * @see self::encode_der() + */ + private static $location; + + /** + * DER Encoded String + * + * In case we need to create ASN1\Element object's.. + * + * @var string + * @see self::decodeDER() + */ + private static $encoded; /** * Type mapping table for the ANY type. * - * Structured or unknown types are mapped to a \phpseclib\File\ASN1\Element. + * Structured or unknown types are mapped to a \phpseclib3\File\ASN1\Element. * Unambiguous types get the direct mapping (int/real/bool). * Others are mapped as a choice, with an extra indexing level. * * @var array - * @access public */ - var $ANYmap = array( + const ANY_MAP = [ self::TYPE_BOOLEAN => true, self::TYPE_INTEGER => true, self::TYPE_BIT_STRING => 'bitString', @@ -176,7 +163,7 @@ class ASN1 self::TYPE_UNIVERSAL_STRING => 'universalString', //self::TYPE_CHARACTER_STRING => 'characterString', self::TYPE_BMP_STRING => 'bmpString' - ); + ]; /** * String type to character size mapping table. @@ -185,9 +172,8 @@ class ASN1 * size == 0 indicates variable length encoding. * * @var array - * @access public */ - var $stringTypeSize = array( + const STRING_TYPE_SIZE = [ self::TYPE_UTF8_STRING => 0, self::TYPE_BMP_STRING => 2, self::TYPE_UNIVERSAL_STRING => 4, @@ -195,26 +181,30 @@ class ASN1 self::TYPE_TELETEX_STRING => 1, self::TYPE_IA5_STRING => 1, self::TYPE_VISIBLE_STRING => 1, - ); + ]; /** * Parse BER-encoding * * Serves a similar purpose to openssl's asn1parse * - * @param string $encoded - * @return array - * @access public + * @param Element|string $encoded + * @return ?array */ - function decodeBER($encoded) + public static function decodeBER($encoded) { if ($encoded instanceof Element) { $encoded = $encoded->element; } - $this->encoded = $encoded; - // encapsulate in an array for BC with the old decodeBER - return array($this->_decode_ber($encoded)); + self::$encoded = $encoded; + + $decoded = self::decode_ber($encoded); + if ($decoded === false) { + return null; + } + + return [$decoded]; } /** @@ -227,12 +217,11 @@ class ASN1 * @param string $encoded * @param int $start * @param int $encoded_pos - * @return array - * @access private + * @return array|bool */ - function _decode_ber($encoded, $start = 0, $encoded_pos = 0) + private static function decode_ber($encoded, $start = 0, $encoded_pos = 0) { - $current = array('start' => $start); + $current = ['start' => $start]; if (!isset($encoded[$encoded_pos])) { return false; @@ -263,7 +252,7 @@ class ASN1 } while ($loop); } - $start+= $startOffset; + $start += $startOffset; // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 if (!isset($encoded[$encoded_pos])) { @@ -278,15 +267,16 @@ class ASN1 } elseif ($length & 0x80) { // definite length, long form // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only // support it up to four. - $length&= 0x7F; + $length &= 0x7F; $temp = substr($encoded, $encoded_pos, $length); $encoded_pos += $length; // tags of indefinte length don't really have a header length; this length includes the tag - $current+= array('headerlength' => $length + 2); - $start+= $length; + $current += ['headerlength' => $length + 2]; + $start += $length; extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); + /** @var integer $length */ } else { - $current+= array('headerlength' => 2); + $current += ['headerlength' => 2]; } if ($length > (strlen($encoded) - $encoded_pos)) { @@ -313,36 +303,36 @@ class ASN1 case self::CLASS_PRIVATE: case self::CLASS_CONTEXT_SPECIFIC: if (!$constructed) { - return array( + return [ 'type' => $class, 'constant' => $tag, 'content' => $content, 'length' => $length + $start - $current['start'] - ); + ] + $current; } - $newcontent = array(); + $newcontent = []; $remainingLength = $length; while ($remainingLength > 0) { - $temp = $this->_decode_ber($content, $start, $content_pos); + $temp = self::decode_ber($content, $start, $content_pos); if ($temp === false) { break; } $length = $temp['length']; // end-of-content octets - see paragraph 8.1.5 if (substr($content, $content_pos + $length, 2) == "\0\0") { - $length+= 2; - $start+= $length; + $length += 2; + $start += $length; $newcontent[] = $temp; break; } - $start+= $length; - $remainingLength-= $length; + $start += $length; + $remainingLength -= $length; $newcontent[] = $temp; $content_pos += $length; } - return array( + return [ 'type' => $class, 'constant' => $tag, // the array encapsulation is for BC with the old format @@ -351,10 +341,10 @@ class ASN1 // the absence of $content['headerlength'] is how we know if something is indefinite or not. // technically, it could be defined to be 2 and then another indicator could be used but whatever. 'length' => $start - $current['start'] - ) + $current; + ] + $current; } - $current+= array('type' => $tag); + $current += ['type' => $tag]; // decode UNIVERSAL tags switch ($tag) { @@ -381,18 +371,18 @@ class ASN1 if (!$constructed) { $current['content'] = substr($content, $content_pos); } else { - $temp = $this->_decode_ber($content, $start, $content_pos); + $temp = self::decode_ber($content, $start, $content_pos); if ($temp === false) { return false; } - $length-= (strlen($content) - $content_pos); + $length -= (strlen($content) - $content_pos); $last = count($temp) - 1; for ($i = 0; $i < $last; $i++) { // all subtags should be bit strings if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { return false; } - $current['content'].= substr($temp[$i]['content'], 1); + $current['content'] .= substr($temp[$i]['content'], 1); } // all subtags should be bit strings if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { @@ -408,7 +398,7 @@ class ASN1 $current['content'] = ''; $length = 0; while (substr($content, $content_pos, 2) != "\0\0") { - $temp = $this->_decode_ber($content, $length + $start, $content_pos); + $temp = self::decode_ber($content, $length + $start, $content_pos); if ($temp === false) { return false; } @@ -417,11 +407,11 @@ class ASN1 if ($temp['type'] != self::TYPE_OCTET_STRING) { return false; } - $current['content'].= $temp['content']; - $length+= $temp['length']; + $current['content'] .= $temp['content']; + $length += $temp['length']; } if (substr($content, $content_pos, 2) == "\0\0") { - $length+= 2; // +2 for the EOC + $length += 2; // +2 for the EOC } } break; @@ -437,7 +427,7 @@ class ASN1 return false; } $offset = 0; - $current['content'] = array(); + $current['content'] = []; $content_len = strlen($content); while ($content_pos < $content_len) { // if indefinite length construction was used and we have an end-of-content string next @@ -446,20 +436,20 @@ class ASN1 $length = $offset + 2; // +2 for the EOC break 2; } - $temp = $this->_decode_ber($content, $start + $offset, $content_pos); + $temp = self::decode_ber($content, $start + $offset, $content_pos); if ($temp === false) { return false; } $content_pos += $temp['length']; $current['content'][] = $temp; - $offset+= $temp['length']; + $offset += $temp['length']; } break; case self::TYPE_OBJECT_IDENTIFIER: if ($constructed) { return false; } - $current['content'] = $this->_decodeOID(substr($content, $content_pos)); + $current['content'] = self::decodeOID(substr($content, $content_pos)); if ($current['content'] === false) { return false; } @@ -502,16 +492,16 @@ class ASN1 if ($constructed) { return false; } - $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag); + $current['content'] = self::decodeTime(substr($content, $content_pos), $tag); break; default: return false; } - $start+= $length; + $start += $length; // ie. length is the length of the full TLV encoding - it's not just the length of the value - return $current + array('length' => $start - $current['start']); + return $current + ['length' => $start - $current['start']]; } /** @@ -524,15 +514,10 @@ class ASN1 * @param array $decoded * @param array $mapping * @param array $special - * @return array - * @access public + * @return array|bool|Element|string|null */ - function asn1map($decoded, $mapping, $special = array()) + public static function asn1map(array $decoded, $mapping, $special = []) { - if (!is_array($decoded)) { - return false; - } - if (isset($mapping['explicit']) && is_array($decoded['content'])) { $decoded = $decoded['content'][0]; } @@ -540,12 +525,13 @@ class ASN1 switch (true) { case $mapping['type'] == self::TYPE_ANY: $intype = $decoded['type']; - if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || (ord($this->encoded[$decoded['start']]) & 0x20)) { - return new Element(substr($this->encoded, $decoded['start'], $decoded['length'])); + // !isset(self::ANY_MAP[$intype]) produces a fatal error on PHP 5.6 + if (isset($decoded['constant']) || !array_key_exists($intype, self::ANY_MAP) || (ord(self::$encoded[$decoded['start']]) & 0x20)) { + return new Element(substr(self::$encoded, $decoded['start'], $decoded['length'])); } - $inmap = $this->ANYmap[$intype]; + $inmap = self::ANY_MAP[$intype]; if (is_string($inmap)) { - return array($inmap => $this->asn1map($decoded, array('type' => $intype) + $mapping, $special)); + return [$inmap => self::asn1map($decoded, ['type' => $intype] + $mapping, $special)]; } break; case $mapping['type'] == self::TYPE_CHOICE: @@ -553,19 +539,19 @@ class ASN1 switch (true) { case isset($option['constant']) && $option['constant'] == $decoded['constant']: case !isset($option['constant']) && $option['type'] == $decoded['type']: - $value = $this->asn1map($decoded, $option, $special); + $value = self::asn1map($decoded, $option, $special); break; case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE: - $v = $this->asn1map($decoded, $option, $special); + $v = self::asn1map($decoded, $option, $special); if (isset($v)) { $value = $v; } } if (isset($value)) { if (isset($special[$key])) { - $value = call_user_func($special[$key], $value); + $value = $special[$key]($value); } - return array($key => $value); + return [$key => $value]; } } return null; @@ -591,13 +577,13 @@ class ASN1 switch ($decoded['type']) { case self::TYPE_SEQUENCE: - $map = array(); + $map = []; // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $child = $mapping['children']; foreach ($decoded['content'] as $content) { - if (($map[] = $this->asn1map($content, $child, $special)) === null) { + if (($map[] = self::asn1map($content, $child, $special)) === null) { return null; } } @@ -633,43 +619,43 @@ class ASN1 $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; } else { // Can only match if no constant expected and type matches or is generic. - $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false; + $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; } } } if ($maymatch) { // Attempt submapping. - $candidate = $this->asn1map($temp, $child, $special); + $candidate = self::asn1map($temp, $child, $special); $maymatch = $candidate !== null; } if ($maymatch) { // Got the match: use it. if (isset($special[$key])) { - $candidate = call_user_func($special[$key], $candidate); + $candidate = $special[$key]($candidate); } $map[$key] = $candidate; $i++; } elseif (isset($child['default'])) { - $map[$key] = $child['default']; // Use default. + $map[$key] = $child['default']; } elseif (!isset($child['optional'])) { return null; // Syntax error. } } // Fail mapping if all input items have not been consumed. - return $i < $n ? null: $map; + return $i < $n ? null : $map; // the main diff between sets and sequences is the encapsulation of the foreach in another for loop case self::TYPE_SET: - $map = array(); + $map = []; // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $child = $mapping['children']; foreach ($decoded['content'] as $content) { - if (($map[] = $this->asn1map($content, $child, $special)) === null) { + if (($map[] = self::asn1map($content, $child, $special)) === null) { return null; } } @@ -705,13 +691,13 @@ class ASN1 $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; } else { // Can only match if no constant expected and type matches or is generic. - $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false; + $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; } } if ($maymatch) { // Attempt submapping. - $candidate = $this->asn1map($temp, $child, $special); + $candidate = self::asn1map($temp, $child, $special); $maymatch = $candidate !== null; } @@ -721,7 +707,7 @@ class ASN1 // Got the match: use it. if (isset($special[$key])) { - $candidate = call_user_func($special[$key], $candidate); + $candidate = $special[$key]($candidate); } $map[$key] = $candidate; break; @@ -739,7 +725,7 @@ class ASN1 } return $map; case self::TYPE_OBJECT_IDENTIFIER: - return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content']; + return isset(self::$oids[$decoded['content']]) ? self::$oids[$decoded['content']] : $decoded['content']; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: // for explicitly tagged optional stuff @@ -750,9 +736,9 @@ class ASN1 // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist // in the wild that OpenSSL decodes without issue so we'll support them as well if (!is_object($decoded['content'])) { - $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']); + $decoded['content'] = self::decodeTime($decoded['content'], $decoded['type']); } - return $decoded['content'] ? $decoded['content']->format($this->format) : false; + return $decoded['content'] ? $decoded['content']->format(self::$format) : false; case self::TYPE_BIT_STRING: if (isset($mapping['mapping'])) { $offset = ord($decoded['content'][0]); @@ -765,7 +751,7 @@ class ASN1 therefore ensure that different semantics are not associated with such values which differ only in the number of trailing 0 bits." */ - $bits = count($mapping['mapping']) == $size ? array() : array_fill(0, count($mapping['mapping']) - $size, false); + $bits = count($mapping['mapping']) == $size ? [] : array_fill(0, count($mapping['mapping']) - $size, false); for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) { $current = ord($decoded['content'][$i]); for ($j = $offset; $j < 8; $j++) { @@ -773,7 +759,7 @@ class ASN1 } $offset = 0; } - $values = array(); + $values = []; $map = array_reverse($mapping['mapping']); foreach ($map as $i => $value) { if ($bits[$i]) { @@ -782,12 +768,12 @@ class ASN1 } return $values; } + // fall-through case self::TYPE_OCTET_STRING: - return base64_encode($decoded['content']); + return $decoded['content']; case self::TYPE_NULL: return ''; case self::TYPE_BOOLEAN: - return $decoded['content']; case self::TYPE_NUMERIC_STRING: case self::TYPE_PRINTABLE_STRING: case self::TYPE_TELETEX_STRING: @@ -816,6 +802,26 @@ class ASN1 } } + /** + * DER-decode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @param string $string + * @return int + */ + public static function decodeLength(&$string) + { + $length = ord(Strings::shift($string)); + if ($length & 0x80) { // definite length, long form + $length &= 0x7F; + $temp = Strings::shift($string, $length); + list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); + } + return $length; + } + /** * ASN.1 Encode * @@ -824,29 +830,27 @@ class ASN1 * * "Special" mappings can be applied via $special. * - * @param string $source - * @param string $mapping + * @param Element|string|array $source + * @param array $mapping * @param array $special * @return string - * @access public */ - function encodeDER($source, $mapping, $special = array()) + public static function encodeDER($source, $mapping, $special = []) { - $this->location = array(); - return $this->_encode_der($source, $mapping, null, $special); + self::$location = []; + return self::encode_der($source, $mapping, null, $special); } /** * ASN.1 Encode (Helper function) * - * @param string $source - * @param string $mapping + * @param Element|string|array|null $source + * @param array $mapping * @param int $idx * @param array $special * @return string - * @access private */ - function _encode_der($source, $mapping, $idx = null, $special = array()) + private static function encode_der($source, array $mapping, $idx = null, array $special = []) { if ($source instanceof Element) { return $source->element; @@ -859,9 +863,9 @@ class ASN1 if (isset($idx)) { if (isset($special[$idx])) { - $source = call_user_func($special[$idx], $source); + $source = $special[$idx]($source); } - $this->location[] = $idx; + self::$location[] = $idx; } $tag = $mapping['type']; @@ -869,19 +873,19 @@ class ASN1 switch ($tag) { case self::TYPE_SET: // Children order is not important, thus process in sequence. case self::TYPE_SEQUENCE: - $tag|= 0x20; // set the constructed bit + $tag |= 0x20; // set the constructed bit // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { - $value = array(); + $value = []; $child = $mapping['children']; foreach ($source as $content) { - $temp = $this->_encode_der($content, $child, null, $special); + $temp = self::encode_der($content, $child, null, $special); if ($temp === false) { return false; } - $value[]= $temp; + $value[] = $temp; } /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared as octet strings with the shorter components being padded at their trailing end with 0-octets. @@ -904,7 +908,7 @@ class ASN1 continue; } - $temp = $this->_encode_der($source[$key], $child, $key, $special); + $temp = self::encode_der($source[$key], $child, $key, $special); if ($temp === false) { return false; } @@ -928,13 +932,13 @@ class ASN1 */ if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); - $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp; + $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; } else { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); $temp = $subtag . substr($temp, 1); } } - $value.= $temp; + $value .= $temp; } break; case self::TYPE_CHOICE: @@ -945,7 +949,7 @@ class ASN1 continue; } - $temp = $this->_encode_der($source[$key], $child, $key, $special); + $temp = self::encode_der($source[$key], $child, $key, $special); if ($temp === false) { return false; } @@ -962,7 +966,7 @@ class ASN1 if (isset($child['constant'])) { if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); - $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp; + $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; } else { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); $temp = $subtag . substr($temp, 1); @@ -971,7 +975,7 @@ class ASN1 } if (isset($idx)) { - array_pop($this->location); + array_pop(self::$location); } if ($temp && isset($mapping['cast'])) { @@ -1001,11 +1005,11 @@ class ASN1 case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y'; - $format.= 'mdHis'; + $format .= 'mdHis'; // if $source does _not_ include timezone information within it then assume that the timezone is GMT - $date = new DateTime($source, new DateTimeZone('GMT')); + $date = new \DateTime($source, new \DateTimeZone('GMT')); // if $source _does_ include timezone information within it then convert the time to GMT - $date->setTimezone(new DateTimeZone('GMT')); + $date->setTimezone(new \DateTimeZone('GMT')); $value = $date->format($format) . 'Z'; break; case self::TYPE_BIT_STRING: @@ -1035,46 +1039,47 @@ class ASN1 $bits = implode('', array_pad($bits, $size + $offset + 1, 0)); $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' '))); foreach ($bytes as $byte) { - $value.= chr(bindec($byte)); + $value .= chr(bindec($byte)); } break; } + // fall-through case self::TYPE_OCTET_STRING: /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ - $value = base64_decode($source); + $value = $source; break; case self::TYPE_OBJECT_IDENTIFIER: - $value = $this->_encodeOID($source); + $value = self::encodeOID($source); break; case self::TYPE_ANY: - $loc = $this->location; + $loc = self::$location; if (isset($idx)) { - array_pop($this->location); + array_pop(self::$location); } switch (true) { case !isset($source): - return $this->_encode_der(null, array('type' => self::TYPE_NULL) + $mapping, null, $special); + return self::encode_der(null, ['type' => self::TYPE_NULL] + $mapping, null, $special); case is_int($source): case $source instanceof BigInteger: - return $this->_encode_der($source, array('type' => self::TYPE_INTEGER) + $mapping, null, $special); + return self::encode_der($source, ['type' => self::TYPE_INTEGER] + $mapping, null, $special); case is_float($source): - return $this->_encode_der($source, array('type' => self::TYPE_REAL) + $mapping, null, $special); + return self::encode_der($source, ['type' => self::TYPE_REAL] + $mapping, null, $special); case is_bool($source): - return $this->_encode_der($source, array('type' => self::TYPE_BOOLEAN) + $mapping, null, $special); + return self::encode_der($source, ['type' => self::TYPE_BOOLEAN] + $mapping, null, $special); case is_array($source) && count($source) == 1: $typename = implode('', array_keys($source)); - $outtype = array_search($typename, $this->ANYmap, true); + $outtype = array_search($typename, self::ANY_MAP, true); if ($outtype !== false) { - return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, null, $special); + return self::encode_der($source[$typename], ['type' => $outtype] + $mapping, null, $special); } } - $filters = $this->filters; + $filters = self::$filters; foreach ($loc as $part) { if (!isset($filters[$part])) { $filters = false; @@ -1083,10 +1088,9 @@ class ASN1 $filters = $filters[$part]; } if ($filters === false) { - user_error('No filters defined for ' . implode('/', $loc)); - return false; + throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); } - return $this->_encode_der($source, $filters + $mapping, null, $special); + return self::encode_der($source, $filters + $mapping, null, $special); case self::TYPE_NULL: $value = ''; break; @@ -1107,44 +1111,23 @@ class ASN1 $value = $source ? "\xFF" : "\x00"; break; default: - user_error('Mapping provides no type definition for ' . implode('/', $this->location)); - return false; + throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); } if (isset($idx)) { - array_pop($this->location); + array_pop(self::$location); } if (isset($mapping['cast'])) { if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) { - $value = chr($tag) . $this->_encodeLength(strlen($value)) . $value; + $value = chr($tag) . self::encodeLength(strlen($value)) . $value; $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; } else { $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; } } - return chr($tag) . $this->_encodeLength(strlen($value)) . $value; - } - - /** - * DER-encode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @access private - * @param int $length - * @return string - */ - function _encodeLength($length) - { - if ($length <= 0x7F) { - return chr($length); - } - - $temp = ltrim(pack('N', $length), chr(0)); - return pack('Ca*', 0x80 | strlen($temp), $temp); + return chr($tag) . self::encodeLength(strlen($value)) . $value; } /** @@ -1152,18 +1135,17 @@ class ASN1 * * Called by _decode_ber() * - * @access private * @param string $content * @return string */ - function _decodeOID($content) + public static function decodeOID($content) { static $eighty; if (!$eighty) { $eighty = new BigInteger(80); } - $oid = array(); + $oid = []; $pos = 0; $len = strlen($content); @@ -1205,11 +1187,10 @@ class ASN1 * * Called by _encode_der() * - * @access private * @param string $source * @return string */ - function _encodeOID($source) + public static function encodeOID($source) { static $mask, $zero, $forty; if (!$mask) { @@ -1218,11 +1199,15 @@ class ASN1 $forty = new BigInteger(40); } - $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids); - if ($oid === false) { - user_error('Invalid OID'); - return false; + if (!preg_match('#(?:\d+\.)+#', $source)) { + $oid = isset(self::$reverseOIDs[$source]) ? self::$reverseOIDs[$source] : false; + } else { + $oid = $source; } + if ($oid === false) { + throw new \RuntimeException('Invalid OID'); + } + $parts = explode('.', $oid); $part1 = array_shift($parts); $part2 = array_shift($parts); @@ -1248,7 +1233,7 @@ class ASN1 } $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F); } - $value.= $temp; + $value .= $temp; } return $value; @@ -1259,12 +1244,11 @@ class ASN1 * * Called by _decode_ber() and in the case of implicit tags asn1map(). * - * @access private * @param string $content * @param int $tag - * @return string + * @return \DateTime|false */ - function _decodeTime($content, $tag) + private static function decodeTime($content, $tag) { /* UTCTime: http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 @@ -1286,7 +1270,7 @@ class ASN1 $prefix = substr($content, 0, 2) >= 50 ? '19' : '20'; $content = $prefix . $content; } elseif (strpos($content, '.') !== false) { - $format.= '.u'; + $format .= '.u'; } if ($content[strlen($content) - 1] == 'Z') { @@ -1294,12 +1278,12 @@ class ASN1 } if (strpos($content, '-') !== false || strpos($content, '+') !== false) { - $format.= 'O'; + $format .= 'O'; } // error supression isn't necessary as of PHP 7.0: // http://php.net/manual/en/migration70.other-changes.php - return @DateTime::createFromFormat($format, $content); + return @\DateTime::createFromFormat($format, $content); } /** @@ -1307,55 +1291,38 @@ class ASN1 * * Sets the time / date format for asn1map(). * - * @access public * @param string $format */ - function setTimeFormat($format) + public static function setTimeFormat($format) { - $this->format = $format; + self::$format = $format; } /** * Load OIDs * * Load the relevant OIDs for a particular ASN.1 semantic mapping. + * Previously loaded OIDs are retained. * - * @access public * @param array $oids */ - function loadOIDs($oids) + public static function loadOIDs(array $oids) { - $this->oids = $oids; + self::$reverseOIDs += $oids; + self::$oids = array_flip(self::$reverseOIDs); } /** - * Load filters + * Set filters * - * See \phpseclib\File\X509, etc, for an example. + * See \phpseclib3\File\X509, etc, for an example. + * Previously loaded filters are not retained. * - * @access public * @param array $filters */ - function loadFilters($filters) + public static function setFilters(array $filters) { - $this->filters = $filters; - } - - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - * @access private - */ - function _string_shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; + self::$filters = $filters; } /** @@ -1368,15 +1335,15 @@ class ASN1 * @param int $from * @param int $to * @return string - * @access public */ - function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) + public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) { - if (!isset($this->stringTypeSize[$from]) || !isset($this->stringTypeSize[$to])) { + // isset(self::STRING_TYPE_SIZE[$from] returns a fatal error on PHP 5.6 + if (!array_key_exists($from, self::STRING_TYPE_SIZE) || !array_key_exists($to, self::STRING_TYPE_SIZE)) { return false; } - $insize = $this->stringTypeSize[$from]; - $outsize = $this->stringTypeSize[$to]; + $insize = self::STRING_TYPE_SIZE[$from]; + $outsize = self::STRING_TYPE_SIZE[$to]; $inlength = strlen($in); $out = ''; @@ -1391,8 +1358,10 @@ class ASN1 case $insize == 4: $c = ($c << 8) | ord($in[$i++]); $c = ($c << 8) | ord($in[$i++]); + // fall-through case $insize == 2: $c = ($c << 8) | ord($in[$i++]); + // fall-through case $insize == 1: break; case ($c & 0x80) == 0x00: @@ -1421,9 +1390,11 @@ class ASN1 $c >>= 8; $v .= chr($c & 0xFF); $c >>= 8; + // fall-through case $outsize == 2: $v .= chr($c & 0xFF); $c >>= 8; + // fall-through case $outsize == 1: $v .= chr($c & 0xFF); $c >>= 8; @@ -1431,23 +1402,28 @@ class ASN1 return false; } break; - case ($c & 0x80000000) != 0: + case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0: return false; case $c >= 0x04000000: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x04000000; + // fall-through case $c >= 0x00200000: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x00200000; + // fall-through case $c >= 0x00010000: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x00010000; + // fall-through case $c >= 0x00000800: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x00000800; + // fall-through case $c >= 0x00000080: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x000000C0; + // fall-through default: $v .= chr($c); break; @@ -1456,4 +1432,77 @@ class ASN1 } return $out; } + + /** + * Extract raw BER from Base64 encoding + * + * @param string $str + * @return string + */ + public static function extractBER($str) + { + /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them + * above and beyond the ceritificate. + * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: + * + * Bag Attributes + * localKeyID: 01 00 00 00 + * subject=/O=organization/OU=org unit/CN=common name + * issuer=/O=organization/CN=common name + */ + if (strlen($str) > ini_get('pcre.backtrack_limit')) { + $temp = $str; + } else { + $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1); + } + // remove new lines + $temp = str_replace(["\r", "\n", ' '], '', $temp); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; + return $temp != false ? $temp : $str; + } + + /** + * DER-encode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @param int $length + * @return string + */ + public static function encodeLength($length) + { + if ($length <= 0x7F) { + return chr($length); + } + + $temp = ltrim(pack('N', $length), chr(0)); + return pack('Ca*', 0x80 | strlen($temp), $temp); + } + + /** + * Returns the OID corresponding to a name + * + * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if + * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version + * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able + * to work from version to version. + * + * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that + * what's being passed to it already is an OID and return that instead. A few examples. + * + * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' + * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' + * getOID('zzz') == 'zzz' + * + * @param string $name + * @return string + */ + public static function getOID($name) + { + return isset(self::$reverseOIDs[$name]) ? self::$reverseOIDs[$name] : $name; + } } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php similarity index 58% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php index 68246e2b5..6540b4210 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php @@ -1,27 +1,25 @@ * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\File\ASN1; +namespace phpseclib3\File\ASN1; /** - * ASN.1 Element + * ASN.1 Raw Element * - * Bypass normal encoding rules in phpseclib\File\ASN1::encodeDER() + * An ASN.1 ANY mapping will return an ASN1\Element object. Use of this object + * will also bypass the normal encoding rules in ASN1::encodeDER() * - * @package ASN1 * @author Jim Wigginton - * @access public */ class Element { @@ -29,18 +27,16 @@ class Element * Raw element value * * @var string - * @access private */ - var $element; + public $element; /** * Constructor * * @param string $encoded - * @return \phpseclib\File\ASN1\Element - * @access public + * @return \phpseclib3\File\ASN1\Element */ - function __construct($encoded) + public function __construct($encoded) { $this->element = $encoded; } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php new file mode 100644 index 000000000..1cbc5a594 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AccessDescription + * + * @author Jim Wigginton + */ +abstract class AccessDescription +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'accessMethod' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'accessLocation' => GeneralName::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php new file mode 100644 index 000000000..04183a13b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AdministrationDomainName + * + * @author Jim Wigginton + */ +abstract class AdministrationDomainName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 2, + 'children' => [ + 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php new file mode 100644 index 000000000..0da7eb102 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AlgorithmIdentifier + * + * @author Jim Wigginton + */ +abstract class AlgorithmIdentifier +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'algorithm' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php new file mode 100644 index 000000000..d96c170be --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AnotherName + * + * @author Jim Wigginton + */ +abstract class AnotherName +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type-id' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'value' => [ + 'type' => ASN1::TYPE_ANY, + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php new file mode 100644 index 000000000..38a6aeefa --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Attribute + * + * @author Jim Wigginton + */ +abstract class Attribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => AttributeType::MAP, + 'value' => [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => AttributeValue::MAP + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php new file mode 100644 index 000000000..5cbc2bcc2 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeType + * + * @author Jim Wigginton + */ +abstract class AttributeType +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php new file mode 100644 index 000000000..fe414f16b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeTypeAndValue + * + * @author Jim Wigginton + */ +abstract class AttributeTypeAndValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => AttributeType::MAP, + 'value' => AttributeValue::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php new file mode 100644 index 000000000..3b3b6d2ed --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeValue + * + * @author Jim Wigginton + */ +abstract class AttributeValue +{ + const MAP = ['type' => ASN1::TYPE_ANY]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php new file mode 100644 index 000000000..cd53ecfaf --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Attributes + * + * @author Jim Wigginton + */ +abstract class Attributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => Attribute::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php new file mode 100644 index 000000000..3e80a55d1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AuthorityInfoAccessSyntax + * + * @author Jim Wigginton + */ +abstract class AuthorityInfoAccessSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => AccessDescription::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php new file mode 100644 index 000000000..e7ec5b28c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AuthorityKeyIdentifier + * + * @author Jim Wigginton + */ +abstract class AuthorityKeyIdentifier +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyIdentifier' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + KeyIdentifier::MAP, + 'authorityCertIssuer' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP, + 'authorityCertSerialNumber' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + CertificateSerialNumber::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php new file mode 100644 index 000000000..e59668ab9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BaseDistance + * + * @author Jim Wigginton + */ +abstract class BaseDistance +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php new file mode 100644 index 000000000..587ef1b0e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BasicConstraints + * + * @author Jim Wigginton + */ +abstract class BasicConstraints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'cA' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ], + 'pathLenConstraint' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php new file mode 100644 index 000000000..e81bc78e8 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInDomainDefinedAttribute + * + * @author Jim Wigginton + */ +abstract class BuiltInDomainDefinedAttribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => ['type' => ASN1::TYPE_PRINTABLE_STRING], + 'value' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php new file mode 100644 index 000000000..471e88f92 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInDomainDefinedAttributes + * + * @author Jim Wigginton + */ +abstract class BuiltInDomainDefinedAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-domain-defined-attributes + 'children' => BuiltInDomainDefinedAttribute::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php new file mode 100644 index 000000000..752f400da --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php @@ -0,0 +1,67 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInStandardAttributes + * + * @author Jim Wigginton + */ +abstract class BuiltInStandardAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'country-name' => ['optional' => true] + CountryName::MAP, + 'administration-domain-name' => ['optional' => true] + AdministrationDomainName::MAP, + 'network-address' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + NetworkAddress::MAP, + 'terminal-identifier' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + TerminalIdentifier::MAP, + 'private-domain-name' => [ + 'constant' => 2, + 'optional' => true, + 'explicit' => true + ] + PrivateDomainName::MAP, + 'organization-name' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + OrganizationName::MAP, + 'numeric-user-identifier' => [ + 'constant' => 4, + 'optional' => true, + 'implicit' => true + ] + NumericUserIdentifier::MAP, + 'personal-name' => [ + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ] + PersonalName::MAP, + 'organizational-unit-names' => [ + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ] + OrganizationalUnitNames::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php new file mode 100644 index 000000000..56e58887e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CPSuri + * + * @author Jim Wigginton + */ +abstract class CPSuri +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php new file mode 100644 index 000000000..79860b2fd --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLDistributionPoints + * + * @author Jim Wigginton + */ +abstract class CRLDistributionPoints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => DistributionPoint::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php new file mode 100644 index 000000000..f6cb95672 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLNumber + * + * @author Jim Wigginton + */ +abstract class CRLNumber +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php new file mode 100644 index 000000000..d37365299 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLReason + * + * @author Jim Wigginton + */ +abstract class CRLReason +{ + const MAP = [ + 'type' => ASN1::TYPE_ENUMERATED, + 'mapping' => [ + 'unspecified', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + // Value 7 is not used. + 8 => 'removeFromCRL', + 'privilegeWithdrawn', + 'aACompromise' + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php new file mode 100644 index 000000000..d7e7776e8 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertPolicyId + * + * @author Jim Wigginton + */ +abstract class CertPolicyId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php new file mode 100644 index 000000000..01943a0d4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Certificate + * + * @author Jim Wigginton + */ +abstract class Certificate +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'tbsCertificate' => TBSCertificate::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php new file mode 100644 index 000000000..ccd68dded --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * CertificateIssuer + * + * @author Jim Wigginton + */ +abstract class CertificateIssuer +{ + const MAP = GeneralNames::MAP; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php new file mode 100644 index 000000000..d54ed6d96 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateList + * + * @author Jim Wigginton + */ +abstract class CertificateList +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'tbsCertList' => TBSCertList::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php new file mode 100644 index 000000000..ec0fa6b5d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificatePolicies + * + * @author Jim Wigginton + */ +abstract class CertificatePolicies +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => PolicyInformation::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php new file mode 100644 index 000000000..06ec944c4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateSerialNumber + * + * @author Jim Wigginton + */ +abstract class CertificateSerialNumber +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php new file mode 100644 index 000000000..2da70ed6a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificationRequest + * + * @author Jim Wigginton + */ +abstract class CertificationRequest +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'certificationRequestInfo' => CertificationRequestInfo::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php new file mode 100644 index 000000000..ce6dc8800 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificationRequestInfo + * + * @author Jim Wigginton + */ +abstract class CertificationRequestInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1'] + ], + 'subject' => Name::MAP, + 'subjectPKInfo' => SubjectPublicKeyInfo::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP, + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php new file mode 100644 index 000000000..5bf59bb89 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Characteristic_two + * + * @author Jim Wigginton + */ +abstract class Characteristic_two +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'm' => ['type' => ASN1::TYPE_INTEGER], // field size 2**m + 'basis' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php new file mode 100644 index 000000000..737d844d1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CountryName + * + * @author Jim Wigginton + */ +abstract class CountryName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 1, + 'children' => [ + 'x121-dcc-code' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'iso-3166-alpha2-code' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php new file mode 100644 index 000000000..621f10355 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Curve + * + * @author Jim Wigginton + */ +abstract class Curve +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'a' => FieldElement::MAP, + 'b' => FieldElement::MAP, + 'seed' => [ + 'type' => ASN1::TYPE_BIT_STRING, + 'optional' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php new file mode 100644 index 000000000..26863dbcf --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DHParameter + * + * @author Jim Wigginton + */ +abstract class DHParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'prime' => ['type' => ASN1::TYPE_INTEGER], + 'base' => ['type' => ASN1::TYPE_INTEGER], + 'privateValueLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php new file mode 100644 index 000000000..7af397bb0 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAParams + * + * @author Jim Wigginton + */ +abstract class DSAParams +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'p' => ['type' => ASN1::TYPE_INTEGER], + 'q' => ['type' => ASN1::TYPE_INTEGER], + 'g' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php new file mode 100644 index 000000000..d97cd023c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAPrivateKey + * + * @author Jim Wigginton + */ +abstract class DSAPrivateKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => ['type' => ASN1::TYPE_INTEGER], + 'p' => ['type' => ASN1::TYPE_INTEGER], + 'q' => ['type' => ASN1::TYPE_INTEGER], + 'g' => ['type' => ASN1::TYPE_INTEGER], + 'y' => ['type' => ASN1::TYPE_INTEGER], + 'x' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php new file mode 100644 index 000000000..f795747a2 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAPublicKey + * + * @author Jim Wigginton + */ +abstract class DSAPublicKey +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php new file mode 100644 index 000000000..b38ff3c44 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DigestInfo + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class DigestInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'digestAlgorithm' => AlgorithmIdentifier::MAP, + 'digest' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php new file mode 100644 index 000000000..45218e3e6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DirectoryString + * + * @author Jim Wigginton + */ +abstract class DirectoryString +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'teletexString' => ['type' => ASN1::TYPE_TELETEX_STRING], + 'printableString' => ['type' => ASN1::TYPE_PRINTABLE_STRING], + 'universalString' => ['type' => ASN1::TYPE_UNIVERSAL_STRING], + 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING], + 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php new file mode 100644 index 000000000..a13e6a64e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DisplayText + * + * @author Jim Wigginton + */ +abstract class DisplayText +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], + 'visibleString' => ['type' => ASN1::TYPE_VISIBLE_STRING], + 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING], + 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php new file mode 100644 index 000000000..4d9af6b59 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DistributionPoint + * + * @author Jim Wigginton + */ +abstract class DistributionPoint +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'distributionPoint' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + DistributionPointName::MAP, + 'reasons' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + ReasonFlags::MAP, + 'cRLIssuer' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php new file mode 100644 index 000000000..bc0cec8f7 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DistributionPointName + * + * @author Jim Wigginton + */ +abstract class DistributionPointName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'fullName' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP, + 'nameRelativeToCRLIssuer' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + RelativeDistinguishedName::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php new file mode 100644 index 000000000..2af740883 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DssSigValue + * + * @author Jim Wigginton + */ +abstract class DssSigValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'r' => ['type' => ASN1::TYPE_INTEGER], + 's' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php new file mode 100644 index 000000000..f25f6faaa --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECParameters + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * -- implicitCurve NULL + * -- specifiedCurve SpecifiedECDomain + * } + * -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. + * -- Details for SpecifiedECDomain can be found in [X9.62]. + * -- Any future additions to this CHOICE should be coordinated + * -- with ANSI X9. + * + * @author Jim Wigginton + */ +abstract class ECParameters +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'namedCurve' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'implicitCurve' => ['type' => ASN1::TYPE_NULL], + 'specifiedCurve' => SpecifiedECDomain::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php new file mode 100644 index 000000000..fb11db83f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECPoint + * + * @author Jim Wigginton + */ +abstract class ECPoint +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php new file mode 100644 index 000000000..7454f3874 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php @@ -0,0 +1,48 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECPrivateKey + * + * @author Jim Wigginton + */ +abstract class ECPrivateKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => [1 => 'ecPrivkeyVer1'] + ], + 'privateKey' => ['type' => ASN1::TYPE_OCTET_STRING], + 'parameters' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + ECParameters::MAP, + 'publicKey' => [ + 'type' => ASN1::TYPE_BIT_STRING, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php new file mode 100644 index 000000000..ea7dcf194 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EDIPartyName + * + * @author Jim Wigginton + */ +abstract class EDIPartyName +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'nameAssigner' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + DirectoryString::MAP, + // partyName is technically required but \phpseclib3\File\ASN1 doesn't currently support non-optional constants and + // setting it to optional gets the job done in any event. + 'partyName' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + DirectoryString::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php new file mode 100644 index 000000000..8ab9ff1eb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EcdsaSigValue + * + * @author Jim Wigginton + */ +abstract class EcdsaSigValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'r' => ['type' => ASN1::TYPE_INTEGER], + 's' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php new file mode 100644 index 000000000..8d8739e1c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EncryptedData + * + * @author Jim Wigginton + */ +abstract class EncryptedData +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php new file mode 100644 index 000000000..2c9356769 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EncryptedPrivateKeyInfo + * + * @author Jim Wigginton + */ +abstract class EncryptedPrivateKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'encryptionAlgorithm' => AlgorithmIdentifier::MAP, + 'encryptedData' => EncryptedData::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php new file mode 100644 index 000000000..f9bc5deff --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtKeyUsageSyntax + * + * @author Jim Wigginton + */ +abstract class ExtKeyUsageSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => KeyPurposeId::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php new file mode 100644 index 000000000..e32668fb5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php @@ -0,0 +1,43 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Extension + * + * A certificate using system MUST reject the certificate if it encounters + * a critical extension it does not recognize; however, a non-critical + * extension may be ignored if it is not recognized. + * + * http://tools.ietf.org/html/rfc5280#section-4.2 + * + * @author Jim Wigginton + */ +abstract class Extension +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'extnId' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'critical' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ], + 'extnValue' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php new file mode 100644 index 000000000..565b36d39 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtensionAttribute + * + * @author Jim Wigginton + */ +abstract class ExtensionAttribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'extension-attribute-type' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ], + 'extension-attribute-value' => [ + 'type' => ASN1::TYPE_ANY, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php new file mode 100644 index 000000000..a2e9bfaec --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtensionAttributes + * + * @author Jim Wigginton + */ +abstract class ExtensionAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => 256, // ub-extension-attributes + 'children' => ExtensionAttribute::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php new file mode 100644 index 000000000..5015c976c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Extensions + * + * @author Jim Wigginton + */ +abstract class Extensions +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + // technically, it's MAX, but we'll assume anything < 0 is MAX + 'max' => -1, + // if 'children' isn't an array then 'min' and 'max' must be defined + 'children' => Extension::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php new file mode 100644 index 000000000..31734078d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * FieldElement + * + * @author Jim Wigginton + */ +abstract class FieldElement +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php new file mode 100644 index 000000000..e32a9c03d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * FieldID + * + * @author Jim Wigginton + */ +abstract class FieldID +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'fieldType' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php new file mode 100644 index 000000000..57d86da85 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php @@ -0,0 +1,80 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralName + * + * @author Jim Wigginton + */ +abstract class GeneralName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'otherName' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + AnotherName::MAP, + 'rfc822Name' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ], + 'dNSName' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ], + 'x400Address' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ORAddress::MAP, + 'directoryName' => [ + 'constant' => 4, + 'optional' => true, + 'explicit' => true + ] + Name::MAP, + 'ediPartyName' => [ + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ] + EDIPartyName::MAP, + 'uniformResourceIdentifier' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ], + 'iPAddress' => [ + 'type' => ASN1::TYPE_OCTET_STRING, + 'constant' => 7, + 'optional' => true, + 'implicit' => true + ], + 'registeredID' => [ + 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, + 'constant' => 8, + 'optional' => true, + 'implicit' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php new file mode 100644 index 000000000..5d931532d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralNames + * + * @author Jim Wigginton + */ +abstract class GeneralNames +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => GeneralName::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php new file mode 100644 index 000000000..5388db559 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralSubtree + * + * @author Jim Wigginton + */ +abstract class GeneralSubtree +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'base' => GeneralName::MAP, + 'minimum' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'default' => '0' + ] + BaseDistance::MAP, + 'maximum' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + ] + BaseDistance::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php new file mode 100644 index 000000000..27548cfec --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralSubtrees + * + * @author Jim Wigginton + */ +abstract class GeneralSubtrees +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => GeneralSubtree::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php new file mode 100644 index 000000000..deb13cabe --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * HashAglorithm + * + * @author Jim Wigginton + */ +abstract class HashAlgorithm +{ + const MAP = AlgorithmIdentifier::MAP; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php new file mode 100644 index 000000000..88d6ff3ea --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * HoldInstructionCode + * + * @author Jim Wigginton + */ +abstract class HoldInstructionCode +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php new file mode 100644 index 000000000..f34b5f728 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * InvalidityDate + * + * @author Jim Wigginton + */ +abstract class InvalidityDate +{ + const MAP = ['type' => ASN1::TYPE_GENERALIZED_TIME]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php new file mode 100644 index 000000000..e9d032448 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * IssuerAltName + * + * @author Jim Wigginton + */ +abstract class IssuerAltName +{ + const MAP = GeneralNames::MAP; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php new file mode 100644 index 000000000..415996f52 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php @@ -0,0 +1,68 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * IssuingDistributionPoint + * + * @author Jim Wigginton + */ +abstract class IssuingDistributionPoint +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'distributionPoint' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + DistributionPointName::MAP, + 'onlyContainsUserCerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 1, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlyContainsCACerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 2, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlySomeReasons' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ReasonFlags::MAP, + 'indirectCRL' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 4, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlyContainsAttributeCerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 5, + 'optional' => true, + 'default' => false, + 'implicit' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php new file mode 100644 index 000000000..82a415199 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyIdentifier + * + * @author Jim Wigginton + */ +abstract class KeyIdentifier +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php new file mode 100644 index 000000000..b8509f196 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyPurposeId + * + * @author Jim Wigginton + */ +abstract class KeyPurposeId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php new file mode 100644 index 000000000..827ce0330 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyUsage + * + * @author Jim Wigginton + */ +abstract class KeyUsage +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'digitalSignature', + 'nonRepudiation', + 'keyEncipherment', + 'dataEncipherment', + 'keyAgreement', + 'keyCertSign', + 'cRLSign', + 'encipherOnly', + 'decipherOnly' + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php new file mode 100644 index 000000000..ea3f998b4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * MaskGenAglorithm + * + * @author Jim Wigginton + */ +abstract class MaskGenAlgorithm +{ + const MAP = AlgorithmIdentifier::MAP; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php new file mode 100644 index 000000000..a6a9009dc --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Name + * + * @author Jim Wigginton + */ +abstract class Name +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'rdnSequence' => RDNSequence::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php new file mode 100644 index 000000000..80486f94d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NameConstraints + * + * @author Jim Wigginton + */ +abstract class NameConstraints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'permittedSubtrees' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + GeneralSubtrees::MAP, + 'excludedSubtrees' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + GeneralSubtrees::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php new file mode 100644 index 000000000..6c68df002 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NetworkAddress + * + * @author Jim Wigginton + */ +abstract class NetworkAddress +{ + const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php new file mode 100644 index 000000000..9eec123a9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NoticeReference + * + * @author Jim Wigginton + */ +abstract class NoticeReference +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'organization' => DisplayText::MAP, + 'noticeNumbers' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 200, + 'children' => ['type' => ASN1::TYPE_INTEGER] + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php new file mode 100644 index 000000000..635a89dcb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NumericUserIdentifier + * + * @author Jim Wigginton + */ +abstract class NumericUserIdentifier +{ + const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php new file mode 100644 index 000000000..b853abe82 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ORAddress + * + * @author Jim Wigginton + */ +abstract class ORAddress +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'built-in-standard-attributes' => BuiltInStandardAttributes::MAP, + 'built-in-domain-defined-attributes' => ['optional' => true] + BuiltInDomainDefinedAttributes::MAP, + 'extension-attributes' => ['optional' => true] + ExtensionAttributes::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php new file mode 100644 index 000000000..59530248c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php @@ -0,0 +1,48 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OneAsymmetricKey + * + * @author Jim Wigginton + */ +abstract class OneAsymmetricKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1', 'v2'] + ], + 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, + 'privateKey' => PrivateKey::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP, + 'publicKey' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + PublicKey::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php new file mode 100644 index 000000000..b5cc9491a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OrganizationName + * + * @author Jim Wigginton + */ +abstract class OrganizationName +{ + const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php new file mode 100644 index 000000000..b3e57809b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OrganizationalUnitNames + * + * @author Jim Wigginton + */ +abstract class OrganizationalUnitNames +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-organizational-units + 'children' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php new file mode 100644 index 000000000..5d565605e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OtherPrimeInfo + * + * @author Jim Wigginton + */ +abstract class OtherPrimeInfo +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'prime' => ['type' => ASN1::TYPE_INTEGER], // ri + 'exponent' => ['type' => ASN1::TYPE_INTEGER], // di + 'coefficient' => ['type' => ASN1::TYPE_INTEGER] // ti + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php new file mode 100644 index 000000000..9802a8089 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OtherPrimeInfos + * + * @author Jim Wigginton + */ +abstract class OtherPrimeInfos +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => OtherPrimeInfo::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php new file mode 100644 index 000000000..8eb27cf62 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBEParameter + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBEParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], + 'iterationCount' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php new file mode 100644 index 000000000..bd31699ff --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBES2params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBES2params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyDerivationFunc' => AlgorithmIdentifier::MAP, + 'encryptionScheme' => AlgorithmIdentifier::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php new file mode 100644 index 000000000..2dafed9ca --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBKDF2params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBKDF2params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + // technically, this is a CHOICE in RFC2898 but the other "choice" is, currently, more of a placeholder + // in the RFC + 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], + 'iterationCount' => ['type' => ASN1::TYPE_INTEGER], + 'keyLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'prf' => AlgorithmIdentifier::MAP + ['optional' => true] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php new file mode 100644 index 000000000..91319f582 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBMAC1params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBMAC1params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyDerivationFunc' => AlgorithmIdentifier::MAP, + 'messageAuthScheme' => AlgorithmIdentifier::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php new file mode 100644 index 000000000..87d0862f5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PKCS9String + * + * @author Jim Wigginton + */ +abstract class PKCS9String +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], + 'directoryString' => DirectoryString::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php new file mode 100644 index 000000000..b8c8c02fd --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Pentanomial + * + * @author Jim Wigginton + */ +abstract class Pentanomial +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'k1' => ['type' => ASN1::TYPE_INTEGER], // k1 > 0 + 'k2' => ['type' => ASN1::TYPE_INTEGER], // k2 > k1 + 'k3' => ['type' => ASN1::TYPE_INTEGER], // k3 > h2 + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php new file mode 100644 index 000000000..14e2860e5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php @@ -0,0 +1,54 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PersonalName + * + * @author Jim Wigginton + */ +abstract class PersonalName +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'children' => [ + 'surname' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ], + 'given-name' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ], + 'initials' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ], + 'generation-qualifier' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php new file mode 100644 index 000000000..1625d199a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyInformation + * + * @author Jim Wigginton + */ +abstract class PolicyInformation +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'policyIdentifier' => CertPolicyId::MAP, + 'policyQualifiers' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 0, + 'max' => -1, + 'optional' => true, + 'children' => PolicyQualifierInfo::MAP + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php new file mode 100644 index 000000000..d30b85235 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyMappings + * + * @author Jim Wigginton + */ +abstract class PolicyMappings +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'issuerDomainPolicy' => CertPolicyId::MAP, + 'subjectDomainPolicy' => CertPolicyId::MAP + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php new file mode 100644 index 000000000..7b7cd6a76 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyQualifierId + * + * @author Jim Wigginton + */ +abstract class PolicyQualifierId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php new file mode 100644 index 000000000..d227702ef --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyQualifierInfo + * + * @author Jim Wigginton + */ +abstract class PolicyQualifierInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'policyQualifierId' => PolicyQualifierId::MAP, + 'qualifier' => ['type' => ASN1::TYPE_ANY] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php new file mode 100644 index 000000000..142b309e4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PostalAddress + * + * @author Jim Wigginton + */ +abstract class PostalAddress +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 1, + 'max' => -1, + 'children' => DirectoryString::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php new file mode 100644 index 000000000..774303448 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Prime_p + * + * @author Jim Wigginton + */ +abstract class Prime_p +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php new file mode 100644 index 000000000..195dcaa5e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateDomainName + * + * @author Jim Wigginton + */ +abstract class PrivateDomainName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php new file mode 100644 index 000000000..3c8959411 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKey + * + * @author Jim Wigginton + */ +abstract class PrivateKey +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php new file mode 100644 index 000000000..b440b78df --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKeyInfo + * + * @author Jim Wigginton + */ +abstract class PrivateKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1'] + ], + 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, + 'privateKey' => PrivateKey::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php new file mode 100644 index 000000000..5b87036e6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKeyUsagePeriod + * + * @author Jim Wigginton + */ +abstract class PrivateKeyUsagePeriod +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME], + 'notAfter' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php new file mode 100644 index 000000000..484092042 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKey + * + * @author Jim Wigginton + */ +abstract class PublicKey +{ + const MAP = ['type' => ASN1::TYPE_BIT_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php new file mode 100644 index 000000000..432581e48 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKeyAndChallenge + * + * @author Jim Wigginton + */ +abstract class PublicKeyAndChallenge +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'spki' => SubjectPublicKeyInfo::MAP, + 'challenge' => ['type' => ASN1::TYPE_IA5_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php new file mode 100644 index 000000000..b39a341f0 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKeyInfo + * + * this format is not formally defined anywhere but is none-the-less the form you + * get when you do "openssl rsa -in private.pem -outform PEM -pubout" + * + * @author Jim Wigginton + */ +abstract class PublicKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'publicKeyAlgorithm' => AlgorithmIdentifier::MAP, + 'publicKey' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php new file mode 100644 index 000000000..48649abd5 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RC2CBCParameter + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class RC2CBCParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'rc2ParametersVersion' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'iv' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php new file mode 100644 index 000000000..04b071c27 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RDNSequence + * + * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + * but they can be useful at times when either there is no unique attribute in the entry or you + * want to ensure that the entry's DN contains some useful identifying information. + * + * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + * + * @author Jim Wigginton + */ +abstract class RDNSequence +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + // RDNSequence does not define a min or a max, which means it doesn't have one + 'min' => 0, + 'max' => -1, + 'children' => RelativeDistinguishedName::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php new file mode 100644 index 000000000..8c19c658e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php @@ -0,0 +1,44 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSAPrivateKey + * + * @author Jim Wigginton + */ +abstract class RSAPrivateKey +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['two-prime', 'multi'] + ], + 'modulus' => ['type' => ASN1::TYPE_INTEGER], // n + 'publicExponent' => ['type' => ASN1::TYPE_INTEGER], // e + 'privateExponent' => ['type' => ASN1::TYPE_INTEGER], // d + 'prime1' => ['type' => ASN1::TYPE_INTEGER], // p + 'prime2' => ['type' => ASN1::TYPE_INTEGER], // q + 'exponent1' => ['type' => ASN1::TYPE_INTEGER], // d mod (p-1) + 'exponent2' => ['type' => ASN1::TYPE_INTEGER], // d mod (q-1) + 'coefficient' => ['type' => ASN1::TYPE_INTEGER], // (inverse of q) mod p + 'otherPrimeInfos' => OtherPrimeInfos::MAP + ['optional' => true] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php new file mode 100644 index 000000000..b14c32c42 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSAPublicKey + * + * @author Jim Wigginton + */ +abstract class RSAPublicKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'modulus' => ['type' => ASN1::TYPE_INTEGER], + 'publicExponent' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php new file mode 100644 index 000000000..1a784bf4d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php @@ -0,0 +1,58 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSASSA_PSS_params + * + * @author Jim Wigginton + */ +abstract class RSASSA_PSS_params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'hashAlgorithm' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + //'default' => 'sha1Identifier' + ] + HashAlgorithm::MAP, + 'maskGenAlgorithm' => [ + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + //'default' => 'mgf1SHA1Identifier' + ] + MaskGenAlgorithm::MAP, + 'saltLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'default' => 20 + ], + 'trailerField' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 3, + 'optional' => true, + 'explicit' => true, + 'default' => 1 + ] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php new file mode 100644 index 000000000..2e62fcdb3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ReasonFlags + * + * @author Jim Wigginton + */ +abstract class ReasonFlags +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'unused', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + 'privilegeWithdrawn', + 'aACompromise' + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php new file mode 100644 index 000000000..a0421f731 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RelativeDistinguishedName + * + * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + * but they can be useful at times when either there is no unique attribute in the entry or you + * want to ensure that the entry's DN contains some useful identifying information. + * + * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + * + * @author Jim Wigginton + */ +abstract class RelativeDistinguishedName +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => AttributeTypeAndValue::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php new file mode 100644 index 000000000..ff759eb73 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RevokedCertificate + * + * @author Jim Wigginton + */ +abstract class RevokedCertificate +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'userCertificate' => CertificateSerialNumber::MAP, + 'revocationDate' => Time::MAP, + 'crlEntryExtensions' => [ + 'optional' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php new file mode 100644 index 000000000..0f482a261 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SignedPublicKeyAndChallenge + * + * @author Jim Wigginton + */ +abstract class SignedPublicKeyAndChallenge +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'publicKeyAndChallenge' => PublicKeyAndChallenge::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php new file mode 100644 index 000000000..7408a5637 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SpecifiedECDomain + * + * @author Jim Wigginton + */ +abstract class SpecifiedECDomain +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => [1 => 'ecdpVer1', 'ecdpVer2', 'ecdpVer3'] + ], + 'fieldID' => FieldID::MAP, + 'curve' => Curve::MAP, + 'base' => ECPoint::MAP, + 'order' => ['type' => ASN1::TYPE_INTEGER], + 'cofactor' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'hash' => ['optional' => true] + HashAlgorithm::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php new file mode 100644 index 000000000..39138a94f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * SubjectAltName + * + * @author Jim Wigginton + */ +abstract class SubjectAltName +{ + const MAP = GeneralNames::MAP; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php new file mode 100644 index 000000000..f2e206f6a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectDirectoryAttributes + * + * @author Jim Wigginton + */ +abstract class SubjectDirectoryAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => Attribute::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php new file mode 100644 index 000000000..1ff241f71 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectInfoAccessSyntax + * + * @author Jim Wigginton + */ +abstract class SubjectInfoAccessSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => AccessDescription::MAP + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php new file mode 100644 index 000000000..0d53d5401 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectPublicKeyInfo + * + * @author Jim Wigginton + */ +abstract class SubjectPublicKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'algorithm' => AlgorithmIdentifier::MAP, + 'subjectPublicKey' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php new file mode 100644 index 000000000..49b3cfc57 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php @@ -0,0 +1,54 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TBSCertList + * + * @author Jim Wigginton + */ +abstract class TBSCertList +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1', 'v2', 'v3'], + 'optional' => true, + 'default' => 'v2' + ], + 'signature' => AlgorithmIdentifier::MAP, + 'issuer' => Name::MAP, + 'thisUpdate' => Time::MAP, + 'nextUpdate' => [ + 'optional' => true + ] + Time::MAP, + 'revokedCertificates' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 0, + 'max' => -1, + 'children' => RevokedCertificate::MAP + ], + 'crlExtensions' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php new file mode 100644 index 000000000..007360c97 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php @@ -0,0 +1,65 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TBSCertificate + * + * @author Jim Wigginton + */ +abstract class TBSCertificate +{ + // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + // technically, default implies optional, but we'll define it as being optional, none-the-less, just to + // reenforce that fact + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'mapping' => ['v1', 'v2', 'v3'], + 'default' => 'v1' + ], + 'serialNumber' => CertificateSerialNumber::MAP, + 'signature' => AlgorithmIdentifier::MAP, + 'issuer' => Name::MAP, + 'validity' => Validity::MAP, + 'subject' => Name::MAP, + 'subjectPublicKeyInfo' => SubjectPublicKeyInfo::MAP, + // implicit means that the T in the TLV structure is to be rewritten, regardless of the type + 'issuerUniqueID' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + UniqueIdentifier::MAP, + 'subjectUniqueID' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + UniqueIdentifier::MAP, + // doesn't use the EXPLICIT keyword but if + // it's not IMPLICIT, it's EXPLICIT + 'extensions' => [ + 'constant' => 3, + 'optional' => true, + 'explicit' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php new file mode 100644 index 000000000..7f6d9d2e9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TerminalIdentifier + * + * @author Jim Wigginton + */ +abstract class TerminalIdentifier +{ + const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php new file mode 100644 index 000000000..744ee7049 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Time + * + * @author Jim Wigginton + */ +abstract class Time +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'utcTime' => ['type' => ASN1::TYPE_UTC_TIME], + 'generalTime' => ['type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php new file mode 100644 index 000000000..33baa91e6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Trinomial + * + * @author Jim Wigginton + */ +abstract class Trinomial +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php new file mode 100644 index 000000000..f4c954bbc --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * UniqueIdentifier + * + * @author Jim Wigginton + */ +abstract class UniqueIdentifier +{ + const MAP = ['type' => ASN1::TYPE_BIT_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php new file mode 100644 index 000000000..98d527b7b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * UserNotice + * + * @author Jim Wigginton + */ +abstract class UserNotice +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'noticeRef' => [ + 'optional' => true, + 'implicit' => true + ] + NoticeReference::MAP, + 'explicitText' => [ + 'optional' => true, + 'implicit' => true + ] + DisplayText::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php new file mode 100644 index 000000000..8ef64cf5d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Validity + * + * @author Jim Wigginton + */ +abstract class Validity +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => Time::MAP, + 'notAfter' => Time::MAP + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php new file mode 100644 index 000000000..2ab157287 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_ca_policy_url + * + * @author Jim Wigginton + */ +abstract class netscape_ca_policy_url +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php new file mode 100644 index 000000000..49e8da4b9 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_cert_type + * + * mapping is from + * + * @author Jim Wigginton + */ +abstract class netscape_cert_type +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'SSLClient', + 'SSLServer', + 'Email', + 'ObjectSigning', + 'Reserved', + 'SSLCA', + 'EmailCA', + 'ObjectSigningCA' + ] + ]; +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php new file mode 100644 index 000000000..d3ff4ddfb --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_comment + * + * @author Jim Wigginton + */ +abstract class netscape_comment +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/X509.php similarity index 50% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/X509.php index 0da0b83cc..5e2f073f4 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/File/X509.php @@ -16,30 +16,33 @@ * be encoded. It can be encoded explicitly or left out all together. This would effect the signature value and thus may invalidate the * the certificate all together unless the certificate is re-signed. * - * @category File - * @package X509 * @author Jim Wigginton * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\File; +namespace phpseclib3\File; -use phpseclib\Crypt\Hash; -use phpseclib\Crypt\Random; -use phpseclib\Crypt\RSA; -use phpseclib\File\ASN1\Element; -use phpseclib\Math\BigInteger; -use DateTime; -use DateTimeZone; +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1\Element; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; /** * Pure-PHP X.509 Parser * - * @package X509 * @author Jim Wigginton - * @access public */ class X509 { @@ -48,59 +51,71 @@ class X509 * * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs * - * @access public */ const VALIDATE_SIGNATURE_BY_CA = 1; - /**#@+ - * @access public - * @see \phpseclib\File\X509::getDN() - */ /** * Return internal array representation + * + * @see \phpseclib3\File\X509::getDN() */ const DN_ARRAY = 0; /** * Return string + * + * @see \phpseclib3\File\X509::getDN() */ const DN_STRING = 1; /** * Return ASN.1 name string + * + * @see \phpseclib3\File\X509::getDN() */ const DN_ASN1 = 2; /** * Return OpenSSL compatible array + * + * @see \phpseclib3\File\X509::getDN() */ const DN_OPENSSL = 3; /** * Return canonical ASN.1 RDNs string + * + * @see \phpseclib3\File\X509::getDN() */ const DN_CANON = 4; /** * Return name hash for file indexing + * + * @see \phpseclib3\File\X509::getDN() */ const DN_HASH = 5; - /**#@-*/ - /**#@+ - * @access public - * @see \phpseclib\File\X509::saveX509() - * @see \phpseclib\File\X509::saveCSR() - * @see \phpseclib\File\X509::saveCRL() - */ /** * Save as PEM * * ie. a base64-encoded PEM with a header and a footer + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_PEM = 0; /** * Save as DER + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_DER = 1; /** * Save as a SPKAC * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + * * Only works on CSRs. Not currently supported. */ const FORMAT_SPKAC = 2; @@ -108,9 +123,12 @@ class X509 * Auto-detect the format * * Used only by the load*() functions + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_AUTO_DETECT = 3; - /**#@-*/ /** * Attribute value disposition. @@ -120,163 +138,71 @@ class X509 const ATTR_APPEND = -2; // Add a value. const ATTR_REPLACE = -3; // Clear first, then add a value. - /** - * ASN.1 syntax for X.509 certificates - * - * @var array - * @access private - */ - var $Certificate; - - /**#@+ - * ASN.1 syntax for various extensions - * - * @access private - */ - var $DirectoryString; - var $PKCS9String; - var $AttributeValue; - var $Extensions; - var $KeyUsage; - var $ExtKeyUsageSyntax; - var $BasicConstraints; - var $KeyIdentifier; - var $CRLDistributionPoints; - var $AuthorityKeyIdentifier; - var $CertificatePolicies; - var $AuthorityInfoAccessSyntax; - var $SubjectAltName; - var $SubjectDirectoryAttributes; - var $PrivateKeyUsagePeriod; - var $IssuerAltName; - var $PolicyMappings; - var $NameConstraints; - - var $CPSuri; - var $UserNotice; - - var $netscape_cert_type; - var $netscape_comment; - var $netscape_ca_policy_url; - - var $Name; - var $RelativeDistinguishedName; - var $CRLNumber; - var $CRLReason; - var $IssuingDistributionPoint; - var $InvalidityDate; - var $CertificateIssuer; - var $HoldInstructionCode; - var $SignedPublicKeyAndChallenge; - /**#@-*/ - - /**#@+ - * ASN.1 syntax for various DN attributes - * - * @access private - */ - var $PostalAddress; - /**#@-*/ - - /** - * ASN.1 syntax for Certificate Signing Requests (RFC2986) - * - * @var array - * @access private - */ - var $CertificationRequest; - - /** - * ASN.1 syntax for Certificate Revocation Lists (RFC5280) - * - * @var array - * @access private - */ - var $CertificateList; - /** * Distinguished Name * * @var array - * @access private */ - var $dn; + private $dn; /** * Public key * - * @var string - * @access private + * @var string|PublicKey */ - var $publicKey; + private $publicKey; /** * Private key * - * @var string - * @access private + * @var string|PrivateKey */ - var $privateKey; - - /** - * Object identifiers for X.509 certificates - * - * @var array - * @access private - * @link http://en.wikipedia.org/wiki/Object_identifier - */ - var $oids; + private $privateKey; /** * The certificate authorities * * @var array - * @access private */ - var $CAs; + private $CAs = []; /** * The currently loaded certificate * * @var array - * @access private */ - var $currentCert; + private $currentCert; /** * The signature subject * - * There's no guarantee \phpseclib\File\X509 is going to re-encode an X.509 cert in the same way it was originally + * There's no guarantee \phpseclib3\File\X509 is going to re-encode an X.509 cert in the same way it was originally * encoded so we take save the portion of the original cert that the signature would have made for. * * @var string - * @access private */ - var $signatureSubject; + private $signatureSubject; /** * Certificate Start Date * * @var string - * @access private */ - var $startDate; + private $startDate; /** * Certificate End Date * - * @var string - * @access private + * @var string|Element */ - var $endDate; + private $endDate; /** * Serial Number * * @var string - * @access private */ - var $serialNumber; + private $serialNumber; /** * Key Identifier @@ -285,1171 +211,213 @@ class X509 * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}. * * @var string - * @access private */ - var $currentKeyIdentifier; + private $currentKeyIdentifier; /** * CA Flag * * @var bool - * @access private */ - var $caFlag = false; + private $caFlag = false; /** * SPKAC Challenge * * @var string - * @access private */ - var $challenge; + private $challenge; + + /** + * @var array + */ + private $extensionValues = []; + + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = false; /** * Recursion Limit * * @var int - * @access private */ - static $recur_limit = 5; + private static $recur_limit = 5; /** * URL fetch flag * * @var bool - * @access private */ - static $disable_url_fetch = false; + private static $disable_url_fetch = false; + + /** + * @var array + */ + private static $extensions = []; + + /** + * @var ?array + */ + private $ipAddresses = null; + + /** + * @var ?array + */ + private $domains = null; /** * Default Constructor. * - * @return \phpseclib\File\X509 - * @access public + * @return \phpseclib3\File\X509 */ - function __construct() + public function __construct() { // Explicitly Tagged Module, 1988 Syntax // http://tools.ietf.org/html/rfc5280#appendix-A.1 - $this->DirectoryString = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'teletexString' => array('type' => ASN1::TYPE_TELETEX_STRING), - 'printableString' => array('type' => ASN1::TYPE_PRINTABLE_STRING), - 'universalString' => array('type' => ASN1::TYPE_UNIVERSAL_STRING), - 'utf8String' => array('type' => ASN1::TYPE_UTF8_STRING), - 'bmpString' => array('type' => ASN1::TYPE_BMP_STRING) - ) - ); - - $this->PKCS9String = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'ia5String' => array('type' => ASN1::TYPE_IA5_STRING), - 'directoryString' => $this->DirectoryString - ) - ); - - $this->AttributeValue = array('type' => ASN1::TYPE_ANY); - - $AttributeType = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); - - $AttributeTypeAndValue = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'type' => $AttributeType, - 'value'=> $this->AttributeValue - ) - ); - - /* - In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, - but they can be useful at times when either there is no unique attribute in the entry or you - want to ensure that the entry's DN contains some useful identifying information. - - - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName - */ - $this->RelativeDistinguishedName = array( - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => $AttributeTypeAndValue - ); - - // http://tools.ietf.org/html/rfc5280#section-4.1.2.4 - $RDNSequence = array( - 'type' => ASN1::TYPE_SEQUENCE, - // RDNSequence does not define a min or a max, which means it doesn't have one - 'min' => 0, - 'max' => -1, - 'children' => $this->RelativeDistinguishedName - ); - - $this->Name = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'rdnSequence' => $RDNSequence - ) - ); - - // http://tools.ietf.org/html/rfc5280#section-4.1.1.2 - $AlgorithmIdentifier = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'algorithm' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), - 'parameters' => array( - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ) - ) - ); - - /* - A certificate using system MUST reject the certificate if it encounters - a critical extension it does not recognize; however, a non-critical - extension may be ignored if it is not recognized. - - http://tools.ietf.org/html/rfc5280#section-4.2 - */ - $Extension = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'extnId' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), - 'critical' => array( - 'type' => ASN1::TYPE_BOOLEAN, - 'optional' => true, - 'default' => false - ), - 'extnValue' => array('type' => ASN1::TYPE_OCTET_STRING) - ) - ); - - $this->Extensions = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - // technically, it's MAX, but we'll assume anything < 0 is MAX - 'max' => -1, - // if 'children' isn't an array then 'min' and 'max' must be defined - 'children' => $Extension - ); - - $SubjectPublicKeyInfo = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'algorithm' => $AlgorithmIdentifier, - 'subjectPublicKey' => array('type' => ASN1::TYPE_BIT_STRING) - ) - ); - - $UniqueIdentifier = array('type' => ASN1::TYPE_BIT_STRING); - - $Time = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'utcTime' => array('type' => ASN1::TYPE_UTC_TIME), - 'generalTime' => array('type' => ASN1::TYPE_GENERALIZED_TIME) - ) - ); - - // http://tools.ietf.org/html/rfc5280#section-4.1.2.5 - $Validity = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'notBefore' => $Time, - 'notAfter' => $Time - ) - ); - - $CertificateSerialNumber = array('type' => ASN1::TYPE_INTEGER); - - $Version = array( - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => array('v1', 'v2', 'v3') - ); - - // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) - $TBSCertificate = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - // technically, default implies optional, but we'll define it as being optional, none-the-less, just to - // reenforce that fact - 'version' => array( - 'constant' => 0, - 'optional' => true, - 'explicit' => true, - 'default' => 'v1' - ) + $Version, - 'serialNumber' => $CertificateSerialNumber, - 'signature' => $AlgorithmIdentifier, - 'issuer' => $this->Name, - 'validity' => $Validity, - 'subject' => $this->Name, - 'subjectPublicKeyInfo' => $SubjectPublicKeyInfo, - // implicit means that the T in the TLV structure is to be rewritten, regardless of the type - 'issuerUniqueID' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $UniqueIdentifier, - 'subjectUniqueID' => array( - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ) + $UniqueIdentifier, - // doesn't use the EXPLICIT keyword but if - // it's not IMPLICIT, it's EXPLICIT - 'extensions' => array( - 'constant' => 3, - 'optional' => true, - 'explicit' => true - ) + $this->Extensions - ) - ); - - $this->Certificate = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'tbsCertificate' => $TBSCertificate, - 'signatureAlgorithm' => $AlgorithmIdentifier, - 'signature' => array('type' => ASN1::TYPE_BIT_STRING) - ) - ); - - $this->KeyUsage = array( - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => array( - 'digitalSignature', - 'nonRepudiation', - 'keyEncipherment', - 'dataEncipherment', - 'keyAgreement', - 'keyCertSign', - 'cRLSign', - 'encipherOnly', - 'decipherOnly' - ) - ); - - $this->BasicConstraints = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'cA' => array( - 'type' => ASN1::TYPE_BOOLEAN, - 'optional' => true, - 'default' => false - ), - 'pathLenConstraint' => array( - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ) - ) - ); - - $this->KeyIdentifier = array('type' => ASN1::TYPE_OCTET_STRING); - - $OrganizationalUnitNames = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 4, // ub-organizational-units - 'children' => array('type' => ASN1::TYPE_PRINTABLE_STRING) - ); - - $PersonalName = array( - 'type' => ASN1::TYPE_SET, - 'children' => array( - 'surname' => array( - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ), - 'given-name' => array( - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ), - 'initials' => array( - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ), - 'generation-qualifier' => array( - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ) - ) - ); - - $NumericUserIdentifier = array('type' => ASN1::TYPE_NUMERIC_STRING); - - $OrganizationName = array('type' => ASN1::TYPE_PRINTABLE_STRING); - - $PrivateDomainName = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'numeric' => array('type' => ASN1::TYPE_NUMERIC_STRING), - 'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING) - ) - ); - - $TerminalIdentifier = array('type' => ASN1::TYPE_PRINTABLE_STRING); - - $NetworkAddress = array('type' => ASN1::TYPE_NUMERIC_STRING); - - $AdministrationDomainName = array( - 'type' => ASN1::TYPE_CHOICE, - // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or - // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC - 'class' => ASN1::CLASS_APPLICATION, - 'cast' => 2, - 'children' => array( - 'numeric' => array('type' => ASN1::TYPE_NUMERIC_STRING), - 'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING) - ) - ); - - $CountryName = array( - 'type' => ASN1::TYPE_CHOICE, - // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or - // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC - 'class' => ASN1::CLASS_APPLICATION, - 'cast' => 1, - 'children' => array( - 'x121-dcc-code' => array('type' => ASN1::TYPE_NUMERIC_STRING), - 'iso-3166-alpha2-code' => array('type' => ASN1::TYPE_PRINTABLE_STRING) - ) - ); - - $AnotherName = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'type-id' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), - 'value' => array( - 'type' => ASN1::TYPE_ANY, - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ) - ) - ); - - $ExtensionAttribute = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'extension-attribute-type' => array( - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ), - 'extension-attribute-value' => array( - 'type' => ASN1::TYPE_ANY, - 'constant' => 1, - 'optional' => true, - 'explicit' => true - ) - ) - ); - - $ExtensionAttributes = array( - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => 256, // ub-extension-attributes - 'children' => $ExtensionAttribute - ); - - $BuiltInDomainDefinedAttribute = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'type' => array('type' => ASN1::TYPE_PRINTABLE_STRING), - 'value' => array('type' => ASN1::TYPE_PRINTABLE_STRING) - ) - ); - - $BuiltInDomainDefinedAttributes = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 4, // ub-domain-defined-attributes - 'children' => $BuiltInDomainDefinedAttribute - ); - - $BuiltInStandardAttributes = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'country-name' => array('optional' => true) + $CountryName, - 'administration-domain-name' => array('optional' => true) + $AdministrationDomainName, - 'network-address' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $NetworkAddress, - 'terminal-identifier' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $TerminalIdentifier, - 'private-domain-name' => array( - 'constant' => 2, - 'optional' => true, - 'explicit' => true - ) + $PrivateDomainName, - 'organization-name' => array( - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ) + $OrganizationName, - 'numeric-user-identifier' => array( - 'constant' => 4, - 'optional' => true, - 'implicit' => true - ) + $NumericUserIdentifier, - 'personal-name' => array( - 'constant' => 5, - 'optional' => true, - 'implicit' => true - ) + $PersonalName, - 'organizational-unit-names' => array( - 'constant' => 6, - 'optional' => true, - 'implicit' => true - ) + $OrganizationalUnitNames - ) - ); - - $ORAddress = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'built-in-standard-attributes' => $BuiltInStandardAttributes, - 'built-in-domain-defined-attributes' => array('optional' => true) + $BuiltInDomainDefinedAttributes, - 'extension-attributes' => array('optional' => true) + $ExtensionAttributes - ) - ); - - $EDIPartyName = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'nameAssigner' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $this->DirectoryString, - // partyName is technically required but \phpseclib\File\ASN1 doesn't currently support non-optional constants and - // setting it to optional gets the job done in any event. - 'partyName' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $this->DirectoryString - ) - ); - - $GeneralName = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'otherName' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $AnotherName, - 'rfc822Name' => array( - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ), - 'dNSName' => array( - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ), - 'x400Address' => array( - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ) + $ORAddress, - 'directoryName' => array( - 'constant' => 4, - 'optional' => true, - 'explicit' => true - ) + $this->Name, - 'ediPartyName' => array( - 'constant' => 5, - 'optional' => true, - 'implicit' => true - ) + $EDIPartyName, - 'uniformResourceIdentifier' => array( - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 6, - 'optional' => true, - 'implicit' => true - ), - 'iPAddress' => array( - 'type' => ASN1::TYPE_OCTET_STRING, - 'constant' => 7, - 'optional' => true, - 'implicit' => true - ), - 'registeredID' => array( - 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, - 'constant' => 8, - 'optional' => true, - 'implicit' => true - ) - ) - ); - - $GeneralNames = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $GeneralName - ); - - $this->IssuerAltName = $GeneralNames; - - $ReasonFlags = array( - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => array( - 'unused', - 'keyCompromise', - 'cACompromise', - 'affiliationChanged', - 'superseded', - 'cessationOfOperation', - 'certificateHold', - 'privilegeWithdrawn', - 'aACompromise' - ) - ); - - $DistributionPointName = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'fullName' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $GeneralNames, - 'nameRelativeToCRLIssuer' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $this->RelativeDistinguishedName - ) - ); - - $DistributionPoint = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'distributionPoint' => array( - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ) + $DistributionPointName, - 'reasons' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $ReasonFlags, - 'cRLIssuer' => array( - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ) + $GeneralNames - ) - ); - - $this->CRLDistributionPoints = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $DistributionPoint - ); - - $this->AuthorityKeyIdentifier = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'keyIdentifier' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $this->KeyIdentifier, - 'authorityCertIssuer' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $GeneralNames, - 'authorityCertSerialNumber' => array( - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ) + $CertificateSerialNumber - ) - ); - - $PolicyQualifierId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); - - $PolicyQualifierInfo = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'policyQualifierId' => $PolicyQualifierId, - 'qualifier' => array('type' => ASN1::TYPE_ANY) - ) - ); - - $CertPolicyId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); - - $PolicyInformation = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'policyIdentifier' => $CertPolicyId, - 'policyQualifiers' => array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 0, - 'max' => -1, - 'optional' => true, - 'children' => $PolicyQualifierInfo - ) - ) - ); - - $this->CertificatePolicies = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $PolicyInformation - ); - - $this->PolicyMappings = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'issuerDomainPolicy' => $CertPolicyId, - 'subjectDomainPolicy' => $CertPolicyId - ) - ) - ); - - $KeyPurposeId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); - - $this->ExtKeyUsageSyntax = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $KeyPurposeId - ); - - $AccessDescription = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'accessMethod' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER), - 'accessLocation' => $GeneralName - ) - ); - - $this->AuthorityInfoAccessSyntax = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $AccessDescription - ); - - $this->SubjectInfoAccessSyntax = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $AccessDescription - ); - - $this->SubjectAltName = $GeneralNames; - - $this->PrivateKeyUsagePeriod = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'notBefore' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true, - 'type' => ASN1::TYPE_GENERALIZED_TIME), - 'notAfter' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true, - 'type' => ASN1::TYPE_GENERALIZED_TIME) - ) - ); - - $BaseDistance = array('type' => ASN1::TYPE_INTEGER); - - $GeneralSubtree = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'base' => $GeneralName, - 'minimum' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true, - 'default' => new BigInteger(0) - ) + $BaseDistance, - 'maximum' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true, - ) + $BaseDistance - ) - ); - - $GeneralSubtrees = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $GeneralSubtree - ); - - $this->NameConstraints = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'permittedSubtrees' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $GeneralSubtrees, - 'excludedSubtrees' => array( - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ) + $GeneralSubtrees - ) - ); - - $this->CPSuri = array('type' => ASN1::TYPE_IA5_STRING); - - $DisplayText = array( - 'type' => ASN1::TYPE_CHOICE, - 'children' => array( - 'ia5String' => array('type' => ASN1::TYPE_IA5_STRING), - 'visibleString' => array('type' => ASN1::TYPE_VISIBLE_STRING), - 'bmpString' => array('type' => ASN1::TYPE_BMP_STRING), - 'utf8String' => array('type' => ASN1::TYPE_UTF8_STRING) - ) - ); - - $NoticeReference = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'organization' => $DisplayText, - 'noticeNumbers' => array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 200, - 'children' => array('type' => ASN1::TYPE_INTEGER) - ) - ) - ); - - $this->UserNotice = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'noticeRef' => array( - 'optional' => true, - 'implicit' => true - ) + $NoticeReference, - 'explicitText' => array( - 'optional' => true, - 'implicit' => true - ) + $DisplayText - ) - ); - - // mapping is from - $this->netscape_cert_type = array( - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => array( - 'SSLClient', - 'SSLServer', - 'Email', - 'ObjectSigning', - 'Reserved', - 'SSLCA', - 'EmailCA', - 'ObjectSigningCA' - ) - ); - - $this->netscape_comment = array('type' => ASN1::TYPE_IA5_STRING); - $this->netscape_ca_policy_url = array('type' => ASN1::TYPE_IA5_STRING); - - // attribute is used in RFC2986 but we're using the RFC5280 definition - - $Attribute = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'type' => $AttributeType, - 'value'=> array( - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => $this->AttributeValue - ) - ) - ); - - $this->SubjectDirectoryAttributes = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => $Attribute - ); - - // adapted from - - $Attributes = array( - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => $Attribute - ); - - $CertificationRequestInfo = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'version' => array( - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => array('v1') - ), - 'subject' => $this->Name, - 'subjectPKInfo' => $SubjectPublicKeyInfo, - 'attributes' => array( - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ) + $Attributes, - ) - ); - - $this->CertificationRequest = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'certificationRequestInfo' => $CertificationRequestInfo, - 'signatureAlgorithm' => $AlgorithmIdentifier, - 'signature' => array('type' => ASN1::TYPE_BIT_STRING) - ) - ); - - $RevokedCertificate = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'userCertificate' => $CertificateSerialNumber, - 'revocationDate' => $Time, - 'crlEntryExtensions' => array( - 'optional' => true - ) + $this->Extensions - ) - ); - - $TBSCertList = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'version' => array( - 'optional' => true, - 'default' => 'v1' - ) + $Version, - 'signature' => $AlgorithmIdentifier, - 'issuer' => $this->Name, - 'thisUpdate' => $Time, - 'nextUpdate' => array( - 'optional' => true - ) + $Time, - 'revokedCertificates' => array( - 'type' => ASN1::TYPE_SEQUENCE, - 'optional' => true, - 'min' => 0, - 'max' => -1, - 'children' => $RevokedCertificate - ), - 'crlExtensions' => array( - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ) + $this->Extensions - ) - ); - - $this->CertificateList = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'tbsCertList' => $TBSCertList, - 'signatureAlgorithm' => $AlgorithmIdentifier, - 'signature' => array('type' => ASN1::TYPE_BIT_STRING) - ) - ); - - $this->CRLNumber = array('type' => ASN1::TYPE_INTEGER); - - $this->CRLReason = array('type' => ASN1::TYPE_ENUMERATED, - 'mapping' => array( - 'unspecified', - 'keyCompromise', - 'cACompromise', - 'affiliationChanged', - 'superseded', - 'cessationOfOperation', - 'certificateHold', - // Value 7 is not used. - 8 => 'removeFromCRL', - 'privilegeWithdrawn', - 'aACompromise' - ) - ); - - $this->IssuingDistributionPoint = array('type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'distributionPoint' => array( - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ) + $DistributionPointName, - 'onlyContainsUserCerts' => array( - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 1, - 'optional' => true, - 'default' => false, - 'implicit' => true - ), - 'onlyContainsCACerts' => array( - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 2, - 'optional' => true, - 'default' => false, - 'implicit' => true - ), - 'onlySomeReasons' => array( - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ) + $ReasonFlags, - 'indirectCRL' => array( - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 4, - 'optional' => true, - 'default' => false, - 'implicit' => true - ), - 'onlyContainsAttributeCerts' => array( - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 5, - 'optional' => true, - 'default' => false, - 'implicit' => true - ) - ) - ); - - $this->InvalidityDate = array('type' => ASN1::TYPE_GENERALIZED_TIME); - - $this->CertificateIssuer = $GeneralNames; - - $this->HoldInstructionCode = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER); - - $PublicKeyAndChallenge = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'spki' => $SubjectPublicKeyInfo, - 'challenge' => array('type' => ASN1::TYPE_IA5_STRING) - ) - ); - - $this->SignedPublicKeyAndChallenge = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => array( - 'publicKeyAndChallenge' => $PublicKeyAndChallenge, - 'signatureAlgorithm' => $AlgorithmIdentifier, - 'signature' => array('type' => ASN1::TYPE_BIT_STRING) - ) - ); - - $this->PostalAddress = array( - 'type' => ASN1::TYPE_SEQUENCE, - 'optional' => true, - 'min' => 1, - 'max' => -1, - 'children' => $this->DirectoryString - ); - - // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 - $this->oids = array( - '1.3.6.1.5.5.7' => 'id-pkix', - '1.3.6.1.5.5.7.1' => 'id-pe', - '1.3.6.1.5.5.7.2' => 'id-qt', - '1.3.6.1.5.5.7.3' => 'id-kp', - '1.3.6.1.5.5.7.48' => 'id-ad', - '1.3.6.1.5.5.7.2.1' => 'id-qt-cps', - '1.3.6.1.5.5.7.2.2' => 'id-qt-unotice', - '1.3.6.1.5.5.7.48.1' =>'id-ad-ocsp', - '1.3.6.1.5.5.7.48.2' => 'id-ad-caIssuers', - '1.3.6.1.5.5.7.48.3' => 'id-ad-timeStamping', - '1.3.6.1.5.5.7.48.5' => 'id-ad-caRepository', - '2.5.4' => 'id-at', - '2.5.4.41' => 'id-at-name', - '2.5.4.4' => 'id-at-surname', - '2.5.4.42' => 'id-at-givenName', - '2.5.4.43' => 'id-at-initials', - '2.5.4.44' => 'id-at-generationQualifier', - '2.5.4.3' => 'id-at-commonName', - '2.5.4.7' => 'id-at-localityName', - '2.5.4.8' => 'id-at-stateOrProvinceName', - '2.5.4.10' => 'id-at-organizationName', - '2.5.4.11' => 'id-at-organizationalUnitName', - '2.5.4.12' => 'id-at-title', - '2.5.4.13' => 'id-at-description', - '2.5.4.46' => 'id-at-dnQualifier', - '2.5.4.6' => 'id-at-countryName', - '2.5.4.5' => 'id-at-serialNumber', - '2.5.4.65' => 'id-at-pseudonym', - '2.5.4.17' => 'id-at-postalCode', - '2.5.4.9' => 'id-at-streetAddress', - '2.5.4.45' => 'id-at-uniqueIdentifier', - '2.5.4.72' => 'id-at-role', - '2.5.4.16' => 'id-at-postalAddress', - - '0.9.2342.19200300.100.1.25' => 'id-domainComponent', - '1.2.840.113549.1.9' => 'pkcs-9', - '1.2.840.113549.1.9.1' => 'pkcs-9-at-emailAddress', - '2.5.29' => 'id-ce', - '2.5.29.35' => 'id-ce-authorityKeyIdentifier', - '2.5.29.14' => 'id-ce-subjectKeyIdentifier', - '2.5.29.15' => 'id-ce-keyUsage', - '2.5.29.16' => 'id-ce-privateKeyUsagePeriod', - '2.5.29.32' => 'id-ce-certificatePolicies', - '2.5.29.32.0' => 'anyPolicy', - - '2.5.29.33' => 'id-ce-policyMappings', - '2.5.29.17' => 'id-ce-subjectAltName', - '2.5.29.18' => 'id-ce-issuerAltName', - '2.5.29.9' => 'id-ce-subjectDirectoryAttributes', - '2.5.29.19' => 'id-ce-basicConstraints', - '2.5.29.30' => 'id-ce-nameConstraints', - '2.5.29.36' => 'id-ce-policyConstraints', - '2.5.29.31' => 'id-ce-cRLDistributionPoints', - '2.5.29.37' => 'id-ce-extKeyUsage', - '2.5.29.37.0' => 'anyExtendedKeyUsage', - '1.3.6.1.5.5.7.3.1' => 'id-kp-serverAuth', - '1.3.6.1.5.5.7.3.2' => 'id-kp-clientAuth', - '1.3.6.1.5.5.7.3.3' => 'id-kp-codeSigning', - '1.3.6.1.5.5.7.3.4' => 'id-kp-emailProtection', - '1.3.6.1.5.5.7.3.8' => 'id-kp-timeStamping', - '1.3.6.1.5.5.7.3.9' => 'id-kp-OCSPSigning', - '2.5.29.54' => 'id-ce-inhibitAnyPolicy', - '2.5.29.46' => 'id-ce-freshestCRL', - '1.3.6.1.5.5.7.1.1' => 'id-pe-authorityInfoAccess', - '1.3.6.1.5.5.7.1.11' => 'id-pe-subjectInfoAccess', - '2.5.29.20' => 'id-ce-cRLNumber', - '2.5.29.28' => 'id-ce-issuingDistributionPoint', - '2.5.29.27' => 'id-ce-deltaCRLIndicator', - '2.5.29.21' => 'id-ce-cRLReasons', - '2.5.29.29' => 'id-ce-certificateIssuer', - '2.5.29.23' => 'id-ce-holdInstructionCode', - '1.2.840.10040.2' => 'holdInstruction', - '1.2.840.10040.2.1' => 'id-holdinstruction-none', - '1.2.840.10040.2.2' => 'id-holdinstruction-callissuer', - '1.2.840.10040.2.3' => 'id-holdinstruction-reject', - '2.5.29.24' => 'id-ce-invalidityDate', - - '1.2.840.113549.2.2' => 'md2', - '1.2.840.113549.2.5' => 'md5', - '1.3.14.3.2.26' => 'id-sha1', - '1.2.840.10040.4.1' => 'id-dsa', - '1.2.840.10040.4.3' => 'id-dsa-with-sha1', - '1.2.840.113549.1.1' => 'pkcs-1', - '1.2.840.113549.1.1.1' => 'rsaEncryption', - '1.2.840.113549.1.1.2' => 'md2WithRSAEncryption', - '1.2.840.113549.1.1.4' => 'md5WithRSAEncryption', - '1.2.840.113549.1.1.5' => 'sha1WithRSAEncryption', - '1.2.840.10046.2.1' => 'dhpublicnumber', - '2.16.840.1.101.2.1.1.22' => 'id-keyExchangeAlgorithm', - '1.2.840.10045' => 'ansi-X9-62', - '1.2.840.10045.4' => 'id-ecSigType', - '1.2.840.10045.4.1' => 'ecdsa-with-SHA1', - '1.2.840.10045.1' => 'id-fieldType', - '1.2.840.10045.1.1' => 'prime-field', - '1.2.840.10045.1.2' => 'characteristic-two-field', - '1.2.840.10045.1.2.3' => 'id-characteristic-two-basis', - '1.2.840.10045.1.2.3.1' => 'gnBasis', - '1.2.840.10045.1.2.3.2' => 'tpBasis', - '1.2.840.10045.1.2.3.3' => 'ppBasis', - '1.2.840.10045.2' => 'id-publicKeyType', - '1.2.840.10045.2.1' => 'id-ecPublicKey', - '1.2.840.10045.3' => 'ellipticCurve', - '1.2.840.10045.3.0' => 'c-TwoCurve', - '1.2.840.10045.3.0.1' => 'c2pnb163v1', - '1.2.840.10045.3.0.2' => 'c2pnb163v2', - '1.2.840.10045.3.0.3' => 'c2pnb163v3', - '1.2.840.10045.3.0.4' => 'c2pnb176w1', - '1.2.840.10045.3.0.5' => 'c2pnb191v1', - '1.2.840.10045.3.0.6' => 'c2pnb191v2', - '1.2.840.10045.3.0.7' => 'c2pnb191v3', - '1.2.840.10045.3.0.8' => 'c2pnb191v4', - '1.2.840.10045.3.0.9' => 'c2pnb191v5', - '1.2.840.10045.3.0.10' => 'c2pnb208w1', - '1.2.840.10045.3.0.11' => 'c2pnb239v1', - '1.2.840.10045.3.0.12' => 'c2pnb239v2', - '1.2.840.10045.3.0.13' => 'c2pnb239v3', - '1.2.840.10045.3.0.14' => 'c2pnb239v4', - '1.2.840.10045.3.0.15' => 'c2pnb239v5', - '1.2.840.10045.3.0.16' => 'c2pnb272w1', - '1.2.840.10045.3.0.17' => 'c2pnb304w1', - '1.2.840.10045.3.0.18' => 'c2pnb359v1', - '1.2.840.10045.3.0.19' => 'c2pnb368w1', - '1.2.840.10045.3.0.20' => 'c2pnb431r1', - '1.2.840.10045.3.1' => 'primeCurve', - '1.2.840.10045.3.1.1' => 'prime192v1', - '1.2.840.10045.3.1.2' => 'prime192v2', - '1.2.840.10045.3.1.3' => 'prime192v3', - '1.2.840.10045.3.1.4' => 'prime239v1', - '1.2.840.10045.3.1.5' => 'prime239v2', - '1.2.840.10045.3.1.6' => 'prime239v3', - '1.2.840.10045.3.1.7' => 'prime256v1', - '1.2.840.113549.1.1.7' => 'id-RSAES-OAEP', - '1.2.840.113549.1.1.9' => 'id-pSpecified', - '1.2.840.113549.1.1.10' => 'id-RSASSA-PSS', - '1.2.840.113549.1.1.8' => 'id-mgf1', - '1.2.840.113549.1.1.14' => 'sha224WithRSAEncryption', - '1.2.840.113549.1.1.11' => 'sha256WithRSAEncryption', - '1.2.840.113549.1.1.12' => 'sha384WithRSAEncryption', - '1.2.840.113549.1.1.13' => 'sha512WithRSAEncryption', - '2.16.840.1.101.3.4.2.4' => 'id-sha224', - '2.16.840.1.101.3.4.2.1' => 'id-sha256', - '2.16.840.1.101.3.4.2.2' => 'id-sha384', - '2.16.840.1.101.3.4.2.3' => 'id-sha512', - '1.2.643.2.2.4' => 'id-GostR3411-94-with-GostR3410-94', - '1.2.643.2.2.3' => 'id-GostR3411-94-with-GostR3410-2001', - '1.2.643.2.2.20' => 'id-GostR3410-2001', - '1.2.643.2.2.19' => 'id-GostR3410-94', - // Netscape Object Identifiers from "Netscape Certificate Extensions" - '2.16.840.1.113730' => 'netscape', - '2.16.840.1.113730.1' => 'netscape-cert-extension', - '2.16.840.1.113730.1.1' => 'netscape-cert-type', - '2.16.840.1.113730.1.13' => 'netscape-comment', - '2.16.840.1.113730.1.8' => 'netscape-ca-policy-url', - // the following are X.509 extensions not supported by phpseclib - '1.3.6.1.5.5.7.1.12' => 'id-pe-logotype', - '1.2.840.113533.7.65.0' => 'entrustVersInfo', - '2.16.840.1.113733.1.6.9' => 'verisignPrivate', - // for Certificate Signing Requests - // see http://tools.ietf.org/html/rfc2985 - '1.2.840.113549.1.9.2' => 'pkcs-9-at-unstructuredName', // PKCS #9 unstructured name - '1.2.840.113549.1.9.7' => 'pkcs-9-at-challengePassword', // Challenge password for certificate revocations - '1.2.840.113549.1.9.14' => 'pkcs-9-at-extensionRequest' // Certificate extension request - ); + if (!self::$oidsLoaded) { + // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 + ASN1::loadOIDs([ + //'id-pkix' => '1.3.6.1.5.5.7', + //'id-pe' => '1.3.6.1.5.5.7.1', + //'id-qt' => '1.3.6.1.5.5.7.2', + //'id-kp' => '1.3.6.1.5.5.7.3', + //'id-ad' => '1.3.6.1.5.5.7.48', + 'id-qt-cps' => '1.3.6.1.5.5.7.2.1', + 'id-qt-unotice' => '1.3.6.1.5.5.7.2.2', + 'id-ad-ocsp' => '1.3.6.1.5.5.7.48.1', + 'id-ad-caIssuers' => '1.3.6.1.5.5.7.48.2', + 'id-ad-timeStamping' => '1.3.6.1.5.5.7.48.3', + 'id-ad-caRepository' => '1.3.6.1.5.5.7.48.5', + //'id-at' => '2.5.4', + 'id-at-name' => '2.5.4.41', + 'id-at-surname' => '2.5.4.4', + 'id-at-givenName' => '2.5.4.42', + 'id-at-initials' => '2.5.4.43', + 'id-at-generationQualifier' => '2.5.4.44', + 'id-at-commonName' => '2.5.4.3', + 'id-at-localityName' => '2.5.4.7', + 'id-at-stateOrProvinceName' => '2.5.4.8', + 'id-at-organizationName' => '2.5.4.10', + 'id-at-organizationalUnitName' => '2.5.4.11', + 'id-at-title' => '2.5.4.12', + 'id-at-description' => '2.5.4.13', + 'id-at-dnQualifier' => '2.5.4.46', + 'id-at-countryName' => '2.5.4.6', + 'id-at-serialNumber' => '2.5.4.5', + 'id-at-pseudonym' => '2.5.4.65', + 'id-at-postalCode' => '2.5.4.17', + 'id-at-streetAddress' => '2.5.4.9', + 'id-at-uniqueIdentifier' => '2.5.4.45', + 'id-at-role' => '2.5.4.72', + 'id-at-postalAddress' => '2.5.4.16', + 'jurisdictionOfIncorporationCountryName' => '1.3.6.1.4.1.311.60.2.1.3', + 'jurisdictionOfIncorporationStateOrProvinceName' => '1.3.6.1.4.1.311.60.2.1.2', + 'jurisdictionLocalityName' => '1.3.6.1.4.1.311.60.2.1.1', + 'id-at-businessCategory' => '2.5.4.15', + + //'id-domainComponent' => '0.9.2342.19200300.100.1.25', + //'pkcs-9' => '1.2.840.113549.1.9', + 'pkcs-9-at-emailAddress' => '1.2.840.113549.1.9.1', + //'id-ce' => '2.5.29', + 'id-ce-authorityKeyIdentifier' => '2.5.29.35', + 'id-ce-subjectKeyIdentifier' => '2.5.29.14', + 'id-ce-keyUsage' => '2.5.29.15', + 'id-ce-privateKeyUsagePeriod' => '2.5.29.16', + 'id-ce-certificatePolicies' => '2.5.29.32', + //'anyPolicy' => '2.5.29.32.0', + + 'id-ce-policyMappings' => '2.5.29.33', + + 'id-ce-subjectAltName' => '2.5.29.17', + 'id-ce-issuerAltName' => '2.5.29.18', + 'id-ce-subjectDirectoryAttributes' => '2.5.29.9', + 'id-ce-basicConstraints' => '2.5.29.19', + 'id-ce-nameConstraints' => '2.5.29.30', + 'id-ce-policyConstraints' => '2.5.29.36', + 'id-ce-cRLDistributionPoints' => '2.5.29.31', + 'id-ce-extKeyUsage' => '2.5.29.37', + //'anyExtendedKeyUsage' => '2.5.29.37.0', + 'id-kp-serverAuth' => '1.3.6.1.5.5.7.3.1', + 'id-kp-clientAuth' => '1.3.6.1.5.5.7.3.2', + 'id-kp-codeSigning' => '1.3.6.1.5.5.7.3.3', + 'id-kp-emailProtection' => '1.3.6.1.5.5.7.3.4', + 'id-kp-timeStamping' => '1.3.6.1.5.5.7.3.8', + 'id-kp-OCSPSigning' => '1.3.6.1.5.5.7.3.9', + 'id-ce-inhibitAnyPolicy' => '2.5.29.54', + 'id-ce-freshestCRL' => '2.5.29.46', + 'id-pe-authorityInfoAccess' => '1.3.6.1.5.5.7.1.1', + 'id-pe-subjectInfoAccess' => '1.3.6.1.5.5.7.1.11', + 'id-ce-cRLNumber' => '2.5.29.20', + 'id-ce-issuingDistributionPoint' => '2.5.29.28', + 'id-ce-deltaCRLIndicator' => '2.5.29.27', + 'id-ce-cRLReasons' => '2.5.29.21', + 'id-ce-certificateIssuer' => '2.5.29.29', + 'id-ce-holdInstructionCode' => '2.5.29.23', + //'holdInstruction' => '1.2.840.10040.2', + 'id-holdinstruction-none' => '1.2.840.10040.2.1', + 'id-holdinstruction-callissuer' => '1.2.840.10040.2.2', + 'id-holdinstruction-reject' => '1.2.840.10040.2.3', + 'id-ce-invalidityDate' => '2.5.29.24', + + 'rsaEncryption' => '1.2.840.113549.1.1.1', + 'md2WithRSAEncryption' => '1.2.840.113549.1.1.2', + 'md5WithRSAEncryption' => '1.2.840.113549.1.1.4', + 'sha1WithRSAEncryption' => '1.2.840.113549.1.1.5', + 'sha224WithRSAEncryption' => '1.2.840.113549.1.1.14', + 'sha256WithRSAEncryption' => '1.2.840.113549.1.1.11', + 'sha384WithRSAEncryption' => '1.2.840.113549.1.1.12', + 'sha512WithRSAEncryption' => '1.2.840.113549.1.1.13', + + 'id-ecPublicKey' => '1.2.840.10045.2.1', + 'ecdsa-with-SHA1' => '1.2.840.10045.4.1', + // from https://tools.ietf.org/html/rfc5758#section-3.2 + 'ecdsa-with-SHA224' => '1.2.840.10045.4.3.1', + 'ecdsa-with-SHA256' => '1.2.840.10045.4.3.2', + 'ecdsa-with-SHA384' => '1.2.840.10045.4.3.3', + 'ecdsa-with-SHA512' => '1.2.840.10045.4.3.4', + + 'id-dsa' => '1.2.840.10040.4.1', + 'id-dsa-with-sha1' => '1.2.840.10040.4.3', + // from https://tools.ietf.org/html/rfc5758#section-3.1 + 'id-dsa-with-sha224' => '2.16.840.1.101.3.4.3.1', + 'id-dsa-with-sha256' => '2.16.840.1.101.3.4.3.2', + + // from https://tools.ietf.org/html/rfc8410: + 'id-Ed25519' => '1.3.101.112', + 'id-Ed448' => '1.3.101.113', + + 'id-RSASSA-PSS' => '1.2.840.113549.1.1.10', + + //'id-sha224' => '2.16.840.1.101.3.4.2.4', + //'id-sha256' => '2.16.840.1.101.3.4.2.1', + //'id-sha384' => '2.16.840.1.101.3.4.2.2', + //'id-sha512' => '2.16.840.1.101.3.4.2.3', + //'id-GostR3411-94-with-GostR3410-94' => '1.2.643.2.2.4', + //'id-GostR3411-94-with-GostR3410-2001' => '1.2.643.2.2.3', + //'id-GostR3410-2001' => '1.2.643.2.2.20', + //'id-GostR3410-94' => '1.2.643.2.2.19', + // Netscape Object Identifiers from "Netscape Certificate Extensions" + 'netscape' => '2.16.840.1.113730', + 'netscape-cert-extension' => '2.16.840.1.113730.1', + 'netscape-cert-type' => '2.16.840.1.113730.1.1', + 'netscape-comment' => '2.16.840.1.113730.1.13', + 'netscape-ca-policy-url' => '2.16.840.1.113730.1.8', + // the following are X.509 extensions not supported by phpseclib + 'id-pe-logotype' => '1.3.6.1.5.5.7.1.12', + 'entrustVersInfo' => '1.2.840.113533.7.65.0', + 'verisignPrivate' => '2.16.840.1.113733.1.6.9', + // for Certificate Signing Requests + // see http://tools.ietf.org/html/rfc2985 + 'pkcs-9-at-unstructuredName' => '1.2.840.113549.1.9.2', // PKCS #9 unstructured name + 'pkcs-9-at-challengePassword' => '1.2.840.113549.1.9.7', // Challenge password for certificate revocations + 'pkcs-9-at-extensionRequest' => '1.2.840.113549.1.9.14' // Certificate extension request + ]); + } } /** @@ -1457,12 +425,11 @@ class X509 * * Returns an associative array describing the X.509 cert or a false if the cert failed to load * - * @param string $cert + * @param array|string $cert * @param int $mode - * @access public * @return mixed */ - function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) + public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($cert) && isset($cert['tbsCertificate'])) { unset($this->currentCert); @@ -1481,10 +448,8 @@ class X509 return $cert; } - $asn1 = new ASN1(); - if ($mode != self::FORMAT_DER) { - $newcert = $this->_extractBER($cert); + $newcert = ASN1::extractBER($cert); if ($mode == self::FORMAT_PEM && $cert == $newcert) { return false; } @@ -1496,11 +461,10 @@ class X509 return false; } - $asn1->loadOIDs($this->oids); - $decoded = $asn1->decodeBER($cert); + $decoded = ASN1::decodeBER($cert); - if (!empty($decoded)) { - $x509 = $asn1->asn1map($decoded[0], $this->Certificate); + if ($decoded) { + $x509 = ASN1::asn1map($decoded[0], Maps\Certificate::MAP); } if (!isset($x509) || $x509 === false) { $this->currentCert = false; @@ -1509,14 +473,18 @@ class X509 $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) { - $this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1); + if ($this->isSubArrayValid($x509, 'tbsCertificate/extensions')) { + $this->mapInExtensions($x509, 'tbsCertificate/extensions'); } - $this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1); - $this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1); + $this->mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence'); + $this->mapInDNs($x509, 'tbsCertificate/subject/rdnSequence'); - $key = &$x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']; - $key = $this->_reformatKey($x509['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $key); + $key = $x509['tbsCertificate']['subjectPublicKeyInfo']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; $this->currentCert = $x509; $this->dn = $x509['tbsCertificate']['subject']; @@ -1532,10 +500,9 @@ class X509 * * @param array $cert * @param int $format optional - * @access public * @return string */ - function saveX509($cert, $format = self::FORMAT_PEM) + public function saveX509(array $cert, $format = self::FORMAT_PEM) { if (!is_array($cert) || !isset($cert['tbsCertificate'])) { return false; @@ -1543,32 +510,22 @@ class X509 switch (true) { // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" - case !($algorithm = $this->_subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): + case !($algorithm = $this->subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): break; default: - switch ($algorithm) { - case 'rsaEncryption': - $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] - = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); - /* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier." - -- https://tools.ietf.org/html/rfc3279#section-2.3.1 - - given that and the fact that RSA keys appear ot be the only key type for which the parameters field can be blank, - it seems like perhaps the ASN.1 description ought not say the parameters field is OPTIONAL, but whatever. - */ - $cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = null; - // https://tools.ietf.org/html/rfc3279#section-2.2.1 - $cert['signatureAlgorithm']['parameters'] = null; - $cert['tbsCertificate']['signature']['parameters'] = null; - } + $cert['tbsCertificate']['subjectPublicKeyInfo'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])) + ); } - $asn1 = new ASN1(); - $asn1->loadOIDs($this->oids); + if ($algorithm == 'rsaEncryption') { + $cert['signatureAlgorithm']['parameters'] = null; + $cert['tbsCertificate']['signature']['parameters'] = null; + } - $filters = array(); - $type_utf8_string = array('type' => ASN1::TYPE_UTF8_STRING); + $filters = []; + $type_utf8_string = ['type' => ASN1::TYPE_UTF8_STRING]; $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string; $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string; $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string; @@ -1580,27 +537,31 @@ class X509 $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string; $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string; - /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib\File\ASN1::TYPE_IA5_STRING. - \phpseclib\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random + foreach (self::$extensions as $extension) { + $filters['tbsCertificate']['extensions'][] = $extension; + } + + /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib3\File\ASN1::TYPE_IA5_STRING. + \phpseclib3\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random characters. */ $filters['policyQualifiers']['qualifier'] - = array('type' => ASN1::TYPE_IA5_STRING); + = ['type' => ASN1::TYPE_IA5_STRING]; - $asn1->loadFilters($filters); + ASN1::setFilters($filters); - $this->_mapOutExtensions($cert, 'tbsCertificate/extensions', $asn1); - $this->_mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence', $asn1); - $this->_mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence', $asn1); + $this->mapOutExtensions($cert, 'tbsCertificate/extensions'); + $this->mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence'); + $this->mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence'); - $cert = $asn1->encodeDER($cert, $this->Certificate); + $cert = ASN1::encodeDER($cert, Maps\Certificate::MAP); switch ($format) { case self::FORMAT_DER: return $cert; // case self::FORMAT_PEM: default: - return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert), 64) . '-----END CERTIFICATE-----'; + return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Strings::base64_encode($cert), 64) . '-----END CERTIFICATE-----'; } } @@ -1610,27 +571,27 @@ class X509 * * @param array $root (by reference) * @param string $path - * @param object $asn1 - * @access private */ - function _mapInExtensions(&$root, $path, $asn1) + private function mapInExtensions(array &$root, $path) { - $extensions = &$this->_subArrayUnchecked($root, $path); + $extensions = &$this->subArrayUnchecked($root, $path); if ($extensions) { for ($i = 0; $i < count($extensions); $i++) { $id = $extensions[$i]['extnId']; $value = &$extensions[$i]['extnValue']; - $value = base64_decode($value); /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ - $map = $this->_getMapping($id); + $map = $this->getMapping($id); if (!is_bool($map)) { $decoder = $id == 'id-ce-nameConstraints' ? - array($this, '_decodeNameConstraintIP') : - array($this, '_decodeIP'); - $decoded = $asn1->decodeBER($value); - $mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => $decoder)); + [static::class, 'decodeNameConstraintIP'] : + [static::class, 'decodeIP']; + $decoded = ASN1::decodeBER($value); + if (!$decoded) { + continue; + } + $mapped = ASN1::asn1map($decoded[0], $map, ['iPAddress' => $decoder]); $value = $mapped === false ? $decoded[0] : $mapped; if ($id == 'id-ce-certificatePolicies') { @@ -1640,18 +601,19 @@ class X509 } for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; - $map = $this->_getMapping($subid); + $map = $this->getMapping($subid); $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; if ($map !== false) { - $decoded = $asn1->decodeBER($subvalue); - $mapped = $asn1->asn1map($decoded[0], $map); + $decoded = ASN1::decodeBER($subvalue); + if (!$decoded) { + continue; + } + $mapped = ASN1::asn1map($decoded[0], $map); $subvalue = $mapped === false ? $decoded[0] : $mapped; } } } } - } else { - $value = base64_encode($value); } } } @@ -1663,12 +625,28 @@ class X509 * * @param array $root (by reference) * @param string $path - * @param object $asn1 - * @access private */ - function _mapOutExtensions(&$root, $path, $asn1) + private function mapOutExtensions(array &$root, $path) { - $extensions = &$this->_subArray($root, $path); + $extensions = &$this->subArray($root, $path, !empty($this->extensionValues)); + + foreach ($this->extensionValues as $id => $data) { + extract($data); + $newext = [ + 'extnId' => $id, + 'extnValue' => $value, + 'critical' => $critical + ]; + if ($replace) { + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + $extensions[$key] = $newext; + continue 2; + } + } + } + $extensions[] = $newext; + } if (is_array($extensions)) { $size = count($extensions); @@ -1688,12 +666,12 @@ class X509 } for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; - $map = $this->_getMapping($subid); + $map = $this->getMapping($subid); $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; if ($map !== false) { - // by default \phpseclib\File\ASN1 will try to render qualifier as a \phpseclib\File\ASN1::TYPE_IA5_STRING since it's - // actual type is \phpseclib\File\ASN1::TYPE_ANY - $subvalue = new Element($asn1->encodeDER($subvalue, $map)); + // by default \phpseclib3\File\ASN1 will try to render qualifier as a \phpseclib3\File\ASN1::TYPE_IA5_STRING since it's + // actual type is \phpseclib3\File\ASN1::TYPE_ANY + $subvalue = new Element(ASN1::encodeDER($subvalue, $map)); } } } @@ -1709,15 +687,14 @@ class X509 /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ - $map = $this->_getMapping($id); + $map = $this->getMapping($id); if (is_bool($map)) { if (!$map) { - user_error($id . ' is not a currently supported extension'); + //user_error($id . ' is not a currently supported extension'); unset($extensions[$i]); } } else { - $temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP'))); - $value = base64_encode($temp); + $value = ASN1::encodeDER($value, $map, ['iPAddress' => [static::class, 'encodeIP']]); } } } @@ -1729,34 +706,35 @@ class X509 * * @param array $root (by reference) * @param string $path - * @param object $asn1 - * @access private */ - function _mapInAttributes(&$root, $path, $asn1) + private function mapInAttributes(&$root, $path) { - $attributes = &$this->_subArray($root, $path); + $attributes = &$this->subArray($root, $path); if (is_array($attributes)) { for ($i = 0; $i < count($attributes); $i++) { $id = $attributes[$i]['type']; /* $value contains the DER encoding of an ASN.1 value corresponding to the attribute type identified by type */ - $map = $this->_getMapping($id); + $map = $this->getMapping($id); if (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; for ($j = 0; $j < count($values); $j++) { - $value = $asn1->encodeDER($values[$j], $this->AttributeValue); - $decoded = $asn1->decodeBER($value); + $value = ASN1::encodeDER($values[$j], Maps\AttributeValue::MAP); + $decoded = ASN1::decodeBER($value); if (!is_bool($map)) { - $mapped = $asn1->asn1map($decoded[0], $map); + if (!$decoded) { + continue; + } + $mapped = ASN1::asn1map($decoded[0], $map); if ($mapped !== false) { $values[$j] = $mapped; } - if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) { - $this->_mapInExtensions($values, $j, $asn1); + if ($id == 'pkcs-9-at-extensionRequest' && $this->isSubArrayValid($values, $j)) { + $this->mapInExtensions($values, $j); } } elseif ($map) { - $values[$j] = base64_encode($value); + $values[$j] = $value; } } } @@ -1770,12 +748,10 @@ class X509 * * @param array $root (by reference) * @param string $path - * @param object $asn1 - * @access private */ - function _mapOutAttributes(&$root, $path, $asn1) + private function mapOutAttributes(&$root, $path) { - $attributes = &$this->_subArray($root, $path); + $attributes = &$this->subArray($root, $path); if (is_array($attributes)) { $size = count($attributes); @@ -1783,23 +759,26 @@ class X509 /* [value] contains the DER encoding of an ASN.1 value corresponding to the attribute type identified by type */ $id = $attributes[$i]['type']; - $map = $this->_getMapping($id); + $map = $this->getMapping($id); if ($map === false) { - user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); + //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); unset($attributes[$i]); } elseif (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; for ($j = 0; $j < count($values); $j++) { switch ($id) { case 'pkcs-9-at-extensionRequest': - $this->_mapOutExtensions($values, $j, $asn1); + $this->mapOutExtensions($values, $j); break; } if (!is_bool($map)) { - $temp = $asn1->encodeDER($values[$j], $map); - $decoded = $asn1->decodeBER($temp); - $values[$j] = $asn1->asn1map($decoded[0], $this->AttributeValue); + $temp = ASN1::encodeDER($values[$j], $map); + $decoded = ASN1::decodeBER($temp); + if (!$decoded) { + continue; + } + $values[$j] = ASN1::asn1map($decoded[0], Maps\AttributeValue::MAP); } } } @@ -1813,12 +792,10 @@ class X509 * * @param array $root (by reference) * @param string $path - * @param object $asn1 - * @access private */ - function _mapInDNs(&$root, $path, $asn1) + private function mapInDNs(array &$root, $path) { - $dns = &$this->_subArray($root, $path); + $dns = &$this->subArray($root, $path); if (is_array($dns)) { for ($i = 0; $i < count($dns); $i++) { @@ -1826,10 +803,13 @@ class X509 $type = $dns[$i][$j]['type']; $value = &$dns[$i][$j]['value']; if (is_object($value) && $value instanceof Element) { - $map = $this->_getMapping($type); + $map = $this->getMapping($type); if (!is_bool($map)) { - $decoded = $asn1->decodeBER($value); - $value = $asn1->asn1map($decoded[0], $map); + $decoded = ASN1::decodeBER($value); + if (!$decoded) { + continue; + } + $value = ASN1::asn1map($decoded[0], $map); } } } @@ -1843,12 +823,10 @@ class X509 * * @param array $root (by reference) * @param string $path - * @param object $asn1 - * @access private */ - function _mapOutDNs(&$root, $path, $asn1) + private function mapOutDNs(array &$root, $path) { - $dns = &$this->_subArray($root, $path); + $dns = &$this->subArray($root, $path); if (is_array($dns)) { $size = count($dns); @@ -1860,9 +838,9 @@ class X509 continue; } - $map = $this->_getMapping($type); + $map = $this->getMapping($type); if (!is_bool($map)) { - $value = new Element($asn1->encodeDER($value, $map)); + $value = new Element(ASN1::encodeDER($value, $map)); } } } @@ -1873,60 +851,61 @@ class X509 * Associate an extension ID to an extension mapping * * @param string $extnId - * @access private * @return mixed */ - function _getMapping($extnId) + private function getMapping($extnId) { - if (!is_string($extnId)) { // eg. if it's a \phpseclib\File\ASN1\Element object + if (!is_string($extnId)) { // eg. if it's a \phpseclib3\File\ASN1\Element object return true; } + if (isset(self::$extensions[$extnId])) { + return self::$extensions[$extnId]; + } + switch ($extnId) { case 'id-ce-keyUsage': - return $this->KeyUsage; + return Maps\KeyUsage::MAP; case 'id-ce-basicConstraints': - return $this->BasicConstraints; + return Maps\BasicConstraints::MAP; case 'id-ce-subjectKeyIdentifier': - return $this->KeyIdentifier; + return Maps\KeyIdentifier::MAP; case 'id-ce-cRLDistributionPoints': - return $this->CRLDistributionPoints; + return Maps\CRLDistributionPoints::MAP; case 'id-ce-authorityKeyIdentifier': - return $this->AuthorityKeyIdentifier; + return Maps\AuthorityKeyIdentifier::MAP; case 'id-ce-certificatePolicies': - return $this->CertificatePolicies; + return Maps\CertificatePolicies::MAP; case 'id-ce-extKeyUsage': - return $this->ExtKeyUsageSyntax; + return Maps\ExtKeyUsageSyntax::MAP; case 'id-pe-authorityInfoAccess': - return $this->AuthorityInfoAccessSyntax; - case 'id-pe-subjectInfoAccess': - return $this->SubjectInfoAccessSyntax; + return Maps\AuthorityInfoAccessSyntax::MAP; case 'id-ce-subjectAltName': - return $this->SubjectAltName; + return Maps\SubjectAltName::MAP; case 'id-ce-subjectDirectoryAttributes': - return $this->SubjectDirectoryAttributes; + return Maps\SubjectDirectoryAttributes::MAP; case 'id-ce-privateKeyUsagePeriod': - return $this->PrivateKeyUsagePeriod; + return Maps\PrivateKeyUsagePeriod::MAP; case 'id-ce-issuerAltName': - return $this->IssuerAltName; + return Maps\IssuerAltName::MAP; case 'id-ce-policyMappings': - return $this->PolicyMappings; + return Maps\PolicyMappings::MAP; case 'id-ce-nameConstraints': - return $this->NameConstraints; + return Maps\NameConstraints::MAP; case 'netscape-cert-type': - return $this->netscape_cert_type; + return Maps\netscape_cert_type::MAP; case 'netscape-comment': - return $this->netscape_comment; + return Maps\netscape_comment::MAP; case 'netscape-ca-policy-url': - return $this->netscape_ca_policy_url; + return Maps\netscape_ca_policy_url::MAP; // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets // back around to asn1map() and we don't want it decoded again. //case 'id-qt-cps': - // return $this->CPSuri; + // return Maps\CPSuri::MAP; case 'id-qt-unotice': - return $this->UserNotice; + return Maps\UserNotice::MAP; // the following OIDs are unsupported but we don't want them to give notices when calling saveX509(). case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt @@ -1947,31 +926,31 @@ class X509 // CSR attributes case 'pkcs-9-at-unstructuredName': - return $this->PKCS9String; + return Maps\PKCS9String::MAP; case 'pkcs-9-at-challengePassword': - return $this->DirectoryString; + return Maps\DirectoryString::MAP; case 'pkcs-9-at-extensionRequest': - return $this->Extensions; + return Maps\Extensions::MAP; // CRL extensions. case 'id-ce-cRLNumber': - return $this->CRLNumber; + return Maps\CRLNumber::MAP; case 'id-ce-deltaCRLIndicator': - return $this->CRLNumber; + return Maps\CRLNumber::MAP; case 'id-ce-issuingDistributionPoint': - return $this->IssuingDistributionPoint; + return Maps\IssuingDistributionPoint::MAP; case 'id-ce-freshestCRL': - return $this->CRLDistributionPoints; + return Maps\CRLDistributionPoints::MAP; case 'id-ce-cRLReasons': - return $this->CRLReason; + return Maps\CRLReason::MAP; case 'id-ce-invalidityDate': - return $this->InvalidityDate; + return Maps\InvalidityDate::MAP; case 'id-ce-certificateIssuer': - return $this->CertificateIssuer; + return Maps\CertificateIssuer::MAP; case 'id-ce-holdInstructionCode': - return $this->HoldInstructionCode; + return Maps\HoldInstructionCode::MAP; case 'id-at-postalAddress': - return $this->PostalAddress; + return Maps\PostalAddress::MAP; } return false; @@ -1981,10 +960,9 @@ class X509 * Load an X.509 certificate as a certificate authority * * @param string $cert - * @access public * @return bool */ - function loadCA($cert) + public function loadCA($cert) { $olddn = $this->dn; $oldcert = $this->currentCert; @@ -2048,10 +1026,9 @@ class X509 * not bar.foo.a.com. f*.com matches foo.com but not bar.com. * * @param string $url - * @access public * @return bool */ - function validateURL($url) + public function validateURL($url) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; @@ -2065,7 +1042,8 @@ class X509 if ($names = $this->getExtension('id-ce-subjectAltName')) { foreach ($names as $name) { foreach ($name as $key => $value) { - $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value); + $value = preg_quote($value); + $value = str_replace('\*', '[^.]*', $value); switch ($key) { case 'dNSName': /* From RFC2818 "HTTP over TLS": @@ -2095,8 +1073,8 @@ class X509 } if ($value = $this->getDNProp('id-at-commonName')) { - $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value[0]); - return preg_match('#^' . $value . '$#', $components['host']); + $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value[0]); + return preg_match('#^' . $value . '$#', $components['host']) === 1; } return false; @@ -2107,17 +1085,17 @@ class X509 * * If $date isn't defined it is assumed to be the current date. * - * @param \DateTime|string $date optional - * @access public + * @param \DateTimeInterface|string $date optional + * @return bool */ - function validateDate($date = null) + public function validateDate($date = null) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } if (!isset($date)) { - $date = new DateTime(null, new DateTimeZone(@date_default_timezone_get())); + $date = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); } $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore']; @@ -2127,29 +1105,22 @@ class X509 $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime']; if (is_string($date)) { - $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get())); + $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); } - $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get())); - $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get())); + $notBefore = new \DateTimeImmutable($notBefore, new \DateTimeZone(@date_default_timezone_get())); + $notAfter = new \DateTimeImmutable($notAfter, new \DateTimeZone(@date_default_timezone_get())); - switch (true) { - case $date < $notBefore: - case $date > $notAfter: - return false; - } - - return true; + return $date >= $notBefore && $date <= $notAfter; } /** * Fetches a URL * * @param string $url - * @access private * @return bool|string */ - static function _fetchURL($url) + private static function fetchURL($url) { if (self::$disable_url_fetch) { return false; @@ -2163,7 +1134,11 @@ class X509 if (!$fsock) { return false; } - fputs($fsock, "GET $parts[path] HTTP/1.0\r\n"); + $path = $parts['path']; + if (isset($parts['query'])) { + $path .= '?' . $parts['query']; + } + fputs($fsock, "GET $path HTTP/1.0\r\n"); fputs($fsock, "Host: $parts[host]\r\n\r\n"); $line = fgets($fsock, 1024); if (strlen($line) < 3) { @@ -2183,7 +1158,7 @@ class X509 if ($temp === false) { return false; } - $data.= $temp; + $data .= $temp; } break; @@ -2202,10 +1177,9 @@ class X509 * * @param bool $caonly * @param int $count - * @access private * @return bool */ - function _testForIntermediate($caonly, $count) + private function testForIntermediate($caonly, $count) { $opts = $this->getExtension('id-pe-authorityInfoAccess'); if (!is_array($opts)) { @@ -2227,7 +1201,7 @@ class X509 return false; } - $cert = static::_fetchURL($url); + $cert = static::fetchURL($url); if (!is_string($cert)) { return false; } @@ -2247,7 +1221,7 @@ class X509 return false; } - if (!$parent->_validateSignatureCountable($caonly, ++$count)) { + if (!$parent->validateSignatureCountable($caonly, ++$count)) { return false; } @@ -2269,12 +1243,11 @@ class X509 * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}. * * @param bool $caonly optional - * @access public * @return mixed */ - function validateSignature($caonly = true) + public function validateSignature($caonly = true) { - return $this->_validateSignatureCountable($caonly, 0); + return $this->validateSignatureCountable($caonly, 0); } /** @@ -2284,10 +1257,9 @@ class X509 * * @param bool $caonly * @param int $count - * @access private * @return mixed */ - function _validateSignatureCountable($caonly, $count) + private function validateSignatureCountable($caonly, $count) { if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { return null; @@ -2342,32 +1314,32 @@ class X509 } } if (count($this->CAs) == $i && $caonly) { - return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); } } elseif (!isset($signingCert) || $caonly) { - return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); } - return $this->_validateSignature( + return $this->validateSignatureHelper( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr($this->currentCert['signature'], 1), $this->signatureSubject ); case isset($this->currentCert['certificationRequestInfo']): - return $this->_validateSignature( + return $this->validateSignatureHelper( $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr($this->currentCert['signature'], 1), $this->signatureSubject ); case isset($this->currentCert['publicKeyAndChallenge']): - return $this->_validateSignature( + return $this->validateSignatureHelper( $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr($this->currentCert['signature'], 1), $this->signatureSubject ); case isset($this->currentCert['tbsCertList']): @@ -2395,11 +1367,11 @@ class X509 if (!isset($signingCert)) { return false; } - return $this->_validateSignature( + return $this->validateSignatureHelper( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr($this->currentCert['signature'], 1), $this->signatureSubject ); default: @@ -2410,24 +1382,28 @@ class X509 /** * Validates a signature * - * Returns true if the signature is verified, false if it is not correct or null on error + * Returns true if the signature is verified and false if it is not correct. + * If the algorithms are unsupposed an exception is thrown. * * @param string $publicKeyAlgorithm * @param string $publicKey * @param string $signatureAlgorithm * @param string $signature * @param string $signatureSubject - * @access private - * @return int + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return bool */ - function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) + private function validateSignatureHelper($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) { switch ($publicKeyAlgorithm) { + case 'id-RSASSA-PSS': + $key = RSA::loadFormat('PSS', $publicKey); + break; case 'rsaEncryption': - $rsa = new RSA(); - $rsa->loadKey($publicKey); - + $key = RSA::loadFormat('PKCS8', $publicKey); switch ($signatureAlgorithm) { + case 'id-RSASSA-PSS': + break; case 'md2WithRSAEncryption': case 'md5WithRSAEncryption': case 'sha1WithRSAEncryption': @@ -2435,21 +1411,51 @@ class X509 case 'sha256WithRSAEncryption': case 'sha384WithRSAEncryption': case 'sha512WithRSAEncryption': - $rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)); - $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); - if (!@$rsa->verify($signatureSubject, $signature)) { - return false; - } + $key = $key + ->withHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)) + ->withPadding(RSA::SIGNATURE_PKCS1); break; default: - return null; + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + case 'id-Ed25519': + case 'id-Ed448': + $key = EC::loadFormat('PKCS8', $publicKey); + break; + case 'id-ecPublicKey': + $key = EC::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'ecdsa-with-SHA1': + case 'ecdsa-with-SHA224': + case 'ecdsa-with-SHA256': + case 'ecdsa-with-SHA384': + case 'ecdsa-with-SHA512': + $key = $key + ->withHash(preg_replace('#^ecdsa-with-#', '', strtolower($signatureAlgorithm))); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + case 'id-dsa': + $key = DSA::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'id-dsa-with-sha1': + case 'id-dsa-with-sha224': + case 'id-dsa-with-sha256': + $key = $key + ->withHash(preg_replace('#^id-dsa-with-#', '', strtolower($signatureAlgorithm))); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } break; default: - return null; + throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); } - return true; + return $key->verify($signatureSubject, $signature); } /** @@ -2460,9 +1466,8 @@ class X509 * that we set a recursion limit. A negative number means that there is no recursion limit. * * @param int $count - * @access public */ - static function setRecurLimit($count) + public static function setRecurLimit($count) { self::$recur_limit = $count; } @@ -2470,9 +1475,8 @@ class X509 /** * Prevents URIs from being automatically retrieved * - * @access public */ - static function disableURLFetch() + public static function disableURLFetch() { self::$disable_url_fetch = true; } @@ -2480,51 +1484,23 @@ class X509 /** * Allows URIs to be automatically retrieved * - * @access public */ - static function enableURLFetch() + public static function enableURLFetch() { self::$disable_url_fetch = false; } - /** - * Reformat public keys - * - * Reformats a public key to a format supported by phpseclib (if applicable) - * - * @param string $algorithm - * @param string $key - * @access private - * @return string - */ - function _reformatKey($algorithm, $key) - { - switch ($algorithm) { - case 'rsaEncryption': - return - "-----BEGIN RSA PUBLIC KEY-----\r\n" . - // subjectPublicKey is stored as a bit string in X.509 certs. the first byte of a bit string represents how many bits - // in the last byte should be ignored. the following only supports non-zero stuff but as none of the X.509 certs Firefox - // uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do. - chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) . - '-----END RSA PUBLIC KEY-----'; - default: - return $key; - } - } - /** * Decodes an IP address * * Takes in a base64 encoded "blob" and returns a human readable IP address * * @param string $ip - * @access private * @return string */ - function _decodeIP($ip) + public static function decodeIP($ip) { - return inet_ntop(base64_decode($ip)); + return inet_ntop($ip); } /** @@ -2533,16 +1509,14 @@ class X509 * Takes in a base64 encoded "blob" and returns a human readable IP address / mask * * @param string $ip - * @access private * @return array */ - function _decodeNameConstraintIP($ip) + public static function decodeNameConstraintIP($ip) { - $ip = base64_decode($ip); $size = strlen($ip) >> 1; $mask = substr($ip, $size); $ip = substr($ip, 0, $size); - return array(inet_ntop($ip), inet_ntop($mask)); + return [inet_ntop($ip), inet_ntop($mask)]; } /** @@ -2551,26 +1525,38 @@ class X509 * Takes a human readable IP address into a base64-encoded "blob" * * @param string|array $ip - * @access private * @return string */ - function _encodeIP($ip) + public static function encodeIP($ip) { return is_string($ip) ? - base64_encode(inet_pton($ip)) : - base64_encode(inet_pton($ip[0]) . inet_pton($ip[1])); + inet_pton($ip) : + inet_pton($ip[0]) . inet_pton($ip[1]); } /** * "Normalizes" a Distinguished Name property * * @param string $propName - * @access private * @return mixed */ - function _translateDNProp($propName) + private function translateDNProp($propName) { switch (strtolower($propName)) { + case 'jurisdictionofincorporationcountryname': + case 'jurisdictioncountryname': + case 'jurisdictionc': + return 'jurisdictionOfIncorporationCountryName'; + case 'jurisdictionofincorporationstateorprovincename': + case 'jurisdictionstateorprovincename': + case 'jurisdictionst': + return 'jurisdictionOfIncorporationStateOrProvinceName'; + case 'jurisdictionlocalityname': + case 'jurisdictionl': + return 'jurisdictionLocalityName'; + case 'id-at-businesscategory': + case 'businesscategory': + return 'id-at-businessCategory'; case 'id-at-countryname': case 'countryname': case 'c': @@ -2659,29 +1645,28 @@ class X509 * @param string $propName * @param mixed $propValue * @param string $type optional - * @access public * @return bool */ - function setDNProp($propName, $propValue, $type = 'utf8String') + public function setDNProp($propName, $propValue, $type = 'utf8String') { if (empty($this->dn)) { - $this->dn = array('rdnSequence' => array()); + $this->dn = ['rdnSequence' => []]; } - if (($propName = $this->_translateDNProp($propName)) === false) { + if (($propName = $this->translateDNProp($propName)) === false) { return false; } foreach ((array) $propValue as $v) { if (!is_array($v) && isset($type)) { - $v = array($type => $v); + $v = [$type => $v]; } - $this->dn['rdnSequence'][] = array( - array( + $this->dn['rdnSequence'][] = [ + [ 'type' => $propName, - 'value'=> $v - ) - ); + 'value' => $v + ] + ]; } return true; @@ -2691,15 +1676,14 @@ class X509 * Remove Distinguished Name properties * * @param string $propName - * @access public */ - function removeDNProp($propName) + public function removeDNProp($propName) { if (empty($this->dn)) { return; } - if (($propName = $this->_translateDNProp($propName)) === false) { + if (($propName = $this->translateDNProp($propName)) === false) { return; } @@ -2725,9 +1709,8 @@ class X509 * @param array $dn optional * @param bool $withType optional * @return mixed - * @access public */ - function getDNProp($propName, $dn = null, $withType = false) + public function getDNProp($propName, array $dn = null, $withType = false) { if (!isset($dn)) { $dn = $this->dn; @@ -2737,27 +1720,25 @@ class X509 return false; } - if (($propName = $this->_translateDNProp($propName)) === false) { + if (($propName = $this->translateDNProp($propName)) === false) { return false; } - $asn1 = new ASN1(); - $asn1->loadOIDs($this->oids); - $filters = array(); - $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING); - $asn1->loadFilters($filters); - $this->_mapOutDNs($dn, 'rdnSequence', $asn1); + $filters = []; + $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); $dn = $dn['rdnSequence']; - $result = array(); + $result = []; for ($i = 0; $i < count($dn); $i++) { if ($dn[$i][0]['type'] == $propName) { $v = $dn[$i][0]['value']; if (!$withType) { if (is_array($v)) { foreach ($v as $type => $s) { - $type = array_search($type, $asn1->ANYmap, true); - if ($type !== false && isset($asn1->stringTypeSize[$type])) { - $s = $asn1->convert($s, $type); + $type = array_search($type, ASN1::ANY_MAP); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $s = ASN1::convert($s, $type); if ($s !== false) { $v = $s; break; @@ -2768,10 +1749,13 @@ class X509 $v = array_pop($v); // Always strip data type. } } elseif (is_object($v) && $v instanceof Element) { - $map = $this->_getMapping($propName); + $map = $this->getMapping($propName); if (!is_bool($map)) { - $decoded = $asn1->decodeBER($v); - $v = $asn1->asn1map($decoded[0], $map); + $decoded = ASN1::decodeBER($v); + if (!$decoded) { + return false; + } + $v = ASN1::asn1map($decoded[0], $map); } } } @@ -2788,10 +1772,9 @@ class X509 * @param mixed $dn * @param bool $merge optional * @param string $type optional - * @access public * @return bool */ - function setDN($dn, $merge = false, $type = 'utf8String') + public function setDN($dn, $merge = false, $type = 'utf8String') { if (!$merge) { $this->dn = null; @@ -2814,7 +1797,7 @@ class X509 // handles everything else $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE); - for ($i = 1; $i < count($results); $i+=2) { + for ($i = 1; $i < count($results); $i += 2) { $prop = trim($results[$i], ', =/'); $value = $results[$i + 1]; if (!$this->setDNProp($prop, $value, $type)) { @@ -2830,10 +1813,9 @@ class X509 * * @param mixed $format optional * @param array $dn optional - * @access public - * @return bool + * @return array|bool|string */ - function getDN($format = self::DN_ARRAY, $dn = null) + public function getDN($format = self::DN_ARRAY, array $dn = null) { if (!isset($dn)) { $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; @@ -2843,32 +1825,28 @@ class X509 case self::DN_ARRAY: return $dn; case self::DN_ASN1: - $asn1 = new ASN1(); - $asn1->loadOIDs($this->oids); - $filters = array(); - $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING); - $asn1->loadFilters($filters); - $this->_mapOutDNs($dn, 'rdnSequence', $asn1); - return $asn1->encodeDER($dn, $this->Name); + $filters = []; + $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + return ASN1::encodeDER($dn, Maps\Name::MAP); case self::DN_CANON: // No SEQUENCE around RDNs and all string values normalized as // trimmed lowercase UTF-8 with all spacing as one blank. // constructed RDNs will not be canonicalized - $asn1 = new ASN1(); - $asn1->loadOIDs($this->oids); - $filters = array(); - $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING); - $asn1->loadFilters($filters); + $filters = []; + $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); $result = ''; - $this->_mapOutDNs($dn, 'rdnSequence', $asn1); + $this->mapOutDNs($dn, 'rdnSequence'); foreach ($dn['rdnSequence'] as $rdn) { foreach ($rdn as $i => $attr) { $attr = &$rdn[$i]; if (is_array($attr['value'])) { foreach ($attr['value'] as $type => $v) { - $type = array_search($type, $asn1->ANYmap, true); - if ($type !== false && isset($asn1->stringTypeSize[$type])) { - $v = $asn1->convert($v, $type); + $type = array_search($type, ASN1::ANY_MAP, true); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $v = ASN1::convert($v, $type); if ($v !== false) { $v = preg_replace('/\s+/', ' ', $v); $attr['value'] = strtolower(trim($v)); @@ -2878,7 +1856,7 @@ class X509 } } } - $result .= $asn1->encodeDER($rdn, $this->RelativeDistinguishedName); + $result .= ASN1::encodeDER($rdn, Maps\RelativeDistinguishedName::MAP); } return $result; case self::DN_HASH: @@ -2886,20 +1864,18 @@ class X509 $hash = new Hash('sha1'); $hash = $hash->hash($dn); extract(unpack('Vhash', $hash)); - return strtolower(bin2hex(pack('N', $hash))); + return strtolower(Strings::bin2hex(pack('N', $hash))); } // Default is to return a string. $start = true; $output = ''; - $result = array(); - $asn1 = new ASN1(); - $asn1->loadOIDs($this->oids); - $filters = array(); - $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING); - $asn1->loadFilters($filters); - $this->_mapOutDNs($dn, 'rdnSequence', $asn1); + $result = []; + $filters = []; + $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); foreach ($dn['rdnSequence'] as $field) { $prop = $field[0]['type']; @@ -2942,13 +1918,13 @@ class X509 } if (!$start) { - $output.= $delim; + $output .= $delim; } if (is_array($value)) { foreach ($value as $type => $v) { - $type = array_search($type, $asn1->ANYmap, true); - if ($type !== false && isset($asn1->stringTypeSize[$type])) { - $v = $asn1->convert($v, $type); + $type = array_search($type, ASN1::ANY_MAP, true); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $v = ASN1::convert($v, $type); if ($v !== false) { $value = $v; break; @@ -2960,13 +1936,13 @@ class X509 } } elseif (is_object($value) && $value instanceof Element) { $callback = function ($x) { - return "\x" . bin2hex($x[0]); + return '\x' . bin2hex($x[0]); }; $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); } - $output.= $desc . '=' . $value; + $output .= $desc . '=' . $value; $result[$desc] = isset($result[$desc]) ? - array_merge((array) $result[$desc], array($value)) : + array_merge((array) $result[$desc], [$value]) : $value; $start = false; } @@ -2978,10 +1954,9 @@ class X509 * Get the Distinguished Name for a certificate/crl issuer * * @param int $format optional - * @access public * @return mixed */ - function getIssuerDN($format = self::DN_ARRAY) + public function getIssuerDN($format = self::DN_ARRAY) { switch (true) { case !isset($this->currentCert) || !is_array($this->currentCert): @@ -3000,10 +1975,9 @@ class X509 * Alias of getDN() * * @param int $format optional - * @access public * @return mixed */ - function getSubjectDN($format = self::DN_ARRAY) + public function getSubjectDN($format = self::DN_ARRAY) { switch (true) { case !empty($this->dn): @@ -3024,10 +1998,9 @@ class X509 * * @param string $propName * @param bool $withType optional - * @access public * @return mixed */ - function getIssuerDNProp($propName, $withType = false) + public function getIssuerDNProp($propName, $withType = false) { switch (true) { case !isset($this->currentCert) || !is_array($this->currentCert): @@ -3046,10 +2019,9 @@ class X509 * * @param string $propName * @param bool $withType optional - * @access public * @return mixed */ - function getSubjectDNProp($propName, $withType = false) + public function getSubjectDNProp($propName, $withType = false) { switch (true) { case !empty($this->dn): @@ -3068,19 +2040,15 @@ class X509 /** * Get the certificate chain for the current cert * - * @access public * @return mixed */ - function getChain() + public function getChain() { - $chain = array($this->currentCert); + $chain = [$this->currentCert]; if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } - if (empty($this->CAs)) { - return $chain; - } while (true) { $currentCert = $chain[count($chain) - 1]; for ($i = 0; $i < count($this->CAs); $i++) { @@ -3110,30 +2078,37 @@ class X509 return $chain; } + /** + * Returns the current cert + * + * @return array|bool + */ + public function &getCurrentCert() + { + return $this->currentCert; + } + /** * Set public key * - * Key needs to be a \phpseclib\Crypt\RSA object + * Key needs to be a \phpseclib3\Crypt\RSA object * - * @param object $key - * @access public - * @return bool + * @param PublicKey $key + * @return void */ - function setPublicKey($key) + public function setPublicKey(PublicKey $key) { - $key->setPublicKey(); $this->publicKey = $key; } /** * Set private key * - * Key needs to be a \phpseclib\Crypt\RSA object + * Key needs to be a \phpseclib3\Crypt\RSA object * - * @param object $key - * @access public + * @param PrivateKey $key */ - function setPrivateKey($key) + public function setPrivateKey(PrivateKey $key) { $this->privateKey = $key; } @@ -3144,9 +2119,8 @@ class X509 * Used for SPKAC CSR's * * @param string $challenge - * @access public */ - function setChallenge($challenge) + public function setChallenge($challenge) { $this->challenge = $challenge; } @@ -3154,20 +2128,24 @@ class X509 /** * Gets the public key * - * Returns a \phpseclib\Crypt\RSA object or a false. + * Returns a \phpseclib3\Crypt\RSA object or a false. * - * @access public * @return mixed */ - function getPublicKey() + public function getPublicKey() { if (isset($this->publicKey)) { return $this->publicKey; } if (isset($this->currentCert) && is_array($this->currentCert)) { - foreach (array('tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo') as $path) { - $keyinfo = $this->_subArray($this->currentCert, $path); + $paths = [ + 'tbsCertificate/subjectPublicKeyInfo', + 'certificationRequestInfo/subjectPKInfo', + 'publicKeyAndChallenge/spki' + ]; + foreach ($paths as $path) { + $keyinfo = $this->subArray($this->currentCert, $path); if (!empty($keyinfo)) { break; } @@ -3180,27 +2158,29 @@ class X509 $key = $keyinfo['subjectPublicKey']; switch ($keyinfo['algorithm']['algorithm']) { + case 'id-RSASSA-PSS': + return RSA::loadFormat('PSS', $key); case 'rsaEncryption': - $publicKey = new RSA(); - $publicKey->loadKey($key); - $publicKey->setPublicKey(); - break; - default: - return false; + return RSA::loadFormat('PKCS8', $key)->withPadding(RSA::SIGNATURE_PKCS1); + case 'id-ecPublicKey': + case 'id-Ed25519': + case 'id-Ed448': + return EC::loadFormat('PKCS8', $key); + case 'id-dsa': + return DSA::loadFormat('PKCS8', $key); } - return $publicKey; + return false; } /** * Load a Certificate Signing Request * - * @param string|array $csr + * @param string $csr * @param int $mode - * @access public * @return mixed */ - function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) + public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($csr) && isset($csr['certificationRequestInfo'])) { unset($this->currentCert); @@ -3217,10 +2197,8 @@ class X509 // see http://tools.ietf.org/html/rfc2986 - $asn1 = new ASN1(); - if ($mode != self::FORMAT_DER) { - $newcsr = $this->_extractBER($csr); + $newcsr = ASN1::extractBER($csr); if ($mode == self::FORMAT_PEM && $csr == $newcsr) { return false; } @@ -3233,44 +2211,39 @@ class X509 return false; } - $asn1->loadOIDs($this->oids); - $decoded = $asn1->decodeBER($csr); + $decoded = ASN1::decodeBER($csr); - if (empty($decoded)) { + if (!$decoded) { $this->currentCert = false; return false; } - $csr = $asn1->asn1map($decoded[0], $this->CertificationRequest); + $csr = ASN1::asn1map($decoded[0], Maps\CertificationRequest::MAP); if (!isset($csr) || $csr === false) { $this->currentCert = false; return false; } - $this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1); - $this->_mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1); + $this->mapInAttributes($csr, 'certificationRequestInfo/attributes'); + $this->mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); $this->dn = $csr['certificationRequestInfo']['subject']; $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $algorithm = &$csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm']; - $key = &$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']; - $key = $this->_reformatKey($algorithm, $key); - - switch ($algorithm) { - case 'rsaEncryption': - $this->publicKey = new RSA(); - $this->publicKey->loadKey($key); - $this->publicKey->setPublicKey(); - break; - default: - $this->publicKey = null; - } + $key = $csr['certificationRequestInfo']['subjectPKInfo']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; $this->currentKeyIdentifier = null; $this->currentCert = $csr; + $this->publicKey = null; + $this->publicKey = $this->getPublicKey(); + return $csr; } @@ -3279,50 +2252,40 @@ class X509 * * @param array $csr * @param int $format optional - * @access public * @return string */ - function saveCSR($csr, $format = self::FORMAT_PEM) + public function saveCSR(array $csr, $format = self::FORMAT_PEM) { if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { return false; } switch (true) { - case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): + case !($algorithm = $this->subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): break; default: - switch ($algorithm) { - case 'rsaEncryption': - $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] - = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']))); - $csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null; - $csr['signatureAlgorithm']['parameters'] = null; - $csr['certificationRequestInfo']['signature']['parameters'] = null; - } + $csr['certificationRequestInfo']['subjectPKInfo'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])) + ); } - $asn1 = new ASN1(); - - $asn1->loadOIDs($this->oids); - - $filters = array(); + $filters = []; $filters['certificationRequestInfo']['subject']['rdnSequence']['value'] - = array('type' => ASN1::TYPE_UTF8_STRING); + = ['type' => ASN1::TYPE_UTF8_STRING]; - $asn1->loadFilters($filters); + ASN1::setFilters($filters); - $this->_mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1); - $this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1); - $csr = $asn1->encodeDER($csr, $this->CertificationRequest); + $this->mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); + $this->mapOutAttributes($csr, 'certificationRequestInfo/attributes'); + $csr = ASN1::encodeDER($csr, Maps\CertificationRequest::MAP); switch ($format) { case self::FORMAT_DER: return $csr; // case self::FORMAT_PEM: default: - return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; + return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Strings::base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; } } @@ -3333,11 +2296,10 @@ class X509 * * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen * - * @param string|array $spkac - * @access public + * @param string $spkac * @return mixed */ - function loadSPKAC($spkac) + public function loadSPKAC($spkac) { if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) { unset($this->currentCert); @@ -3349,11 +2311,9 @@ class X509 // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge - $asn1 = new ASN1(); - // OpenSSL produces SPKAC's that are preceded by the string SPKAC= $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; if ($temp != false) { $spkac = $temp; } @@ -3364,74 +2324,63 @@ class X509 return false; } - $asn1->loadOIDs($this->oids); - $decoded = $asn1->decodeBER($spkac); + $decoded = ASN1::decodeBER($spkac); - if (empty($decoded)) { + if (!$decoded) { $this->currentCert = false; return false; } - $spkac = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge); + $spkac = ASN1::asn1map($decoded[0], Maps\SignedPublicKeyAndChallenge::MAP); - if (!isset($spkac) || $spkac === false) { + if (!isset($spkac) || !is_array($spkac)) { $this->currentCert = false; return false; } $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $algorithm = &$spkac['publicKeyAndChallenge']['spki']['algorithm']['algorithm']; - $key = &$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']; - $key = $this->_reformatKey($algorithm, $key); - - switch ($algorithm) { - case 'rsaEncryption': - $this->publicKey = new RSA(); - $this->publicKey->loadKey($key); - $this->publicKey->setPublicKey(); - break; - default: - $this->publicKey = null; - } + $key = $spkac['publicKeyAndChallenge']['spki']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; $this->currentKeyIdentifier = null; $this->currentCert = $spkac; + $this->publicKey = null; + $this->publicKey = $this->getPublicKey(); + return $spkac; } /** * Save a SPKAC CSR request * - * @param string|array $spkac + * @param array $spkac * @param int $format optional - * @access public * @return string */ - function saveSPKAC($spkac, $format = self::FORMAT_PEM) + public function saveSPKAC(array $spkac, $format = self::FORMAT_PEM) { if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { return false; } - $algorithm = $this->_subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); + $algorithm = $this->subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); switch (true) { case !$algorithm: case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): break; default: - switch ($algorithm) { - case 'rsaEncryption': - $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] - = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']))); - } + $spkac['publicKeyAndChallenge']['spki'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])) + ); } - $asn1 = new ASN1(); - - $asn1->loadOIDs($this->oids); - $spkac = $asn1->encodeDER($spkac, $this->SignedPublicKeyAndChallenge); + $spkac = ASN1::encodeDER($spkac, Maps\SignedPublicKeyAndChallenge::MAP); switch ($format) { case self::FORMAT_DER: @@ -3440,7 +2389,7 @@ class X509 default: // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much // no other SPKAC decoders phpseclib will use that same format - return 'SPKAC=' . base64_encode($spkac); + return 'SPKAC=' . Strings::base64_encode($spkac); } } @@ -3449,10 +2398,9 @@ class X509 * * @param string $crl * @param int $mode - * @access public * @return mixed */ - function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) + public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($crl) && isset($crl['tbsCertList'])) { $this->currentCert = $crl; @@ -3460,10 +2408,8 @@ class X509 return $crl; } - $asn1 = new ASN1(); - if ($mode != self::FORMAT_DER) { - $newcrl = $this->_extractBER($crl); + $newcrl = ASN1::extractBER($crl); if ($mode == self::FORMAT_PEM && $crl == $newcrl) { return false; } @@ -3476,15 +2422,14 @@ class X509 return false; } - $asn1->loadOIDs($this->oids); - $decoded = $asn1->decodeBER($crl); + $decoded = ASN1::decodeBER($crl); - if (empty($decoded)) { + if (!$decoded) { $this->currentCert = false; return false; } - $crl = $asn1->asn1map($decoded[0], $this->CertificateList); + $crl = ASN1::asn1map($decoded[0], Maps\CertificateList::MAP); if (!isset($crl) || $crl === false) { $this->currentCert = false; return false; @@ -3492,17 +2437,17 @@ class X509 $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - $this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1); - if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { - $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1); + $this->mapInDNs($crl, 'tbsCertList/issuer/rdnSequence'); + if ($this->isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { + $this->mapInExtensions($crl, 'tbsCertList/crlExtensions'); } - if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { - $rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); + if ($this->isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { + $rclist_ref = &$this->subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); if ($rclist_ref) { $rclist = $crl['tbsCertList']['revokedCertificates']; foreach ($rclist as $i => $extension) { - if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) { - $this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1); + if ($this->isSubArrayValid($rclist, "$i/crlEntryExtensions")) { + $this->mapInExtensions($rclist_ref, "$i/crlEntryExtensions"); } } } @@ -3519,56 +2464,51 @@ class X509 * * @param array $crl * @param int $format optional - * @access public * @return string */ - function saveCRL($crl, $format = self::FORMAT_PEM) + public function saveCRL(array $crl, $format = self::FORMAT_PEM) { if (!is_array($crl) || !isset($crl['tbsCertList'])) { return false; } - $asn1 = new ASN1(); - - $asn1->loadOIDs($this->oids); - - $filters = array(); + $filters = []; $filters['tbsCertList']['issuer']['rdnSequence']['value'] - = array('type' => ASN1::TYPE_UTF8_STRING); + = ['type' => ASN1::TYPE_UTF8_STRING]; $filters['tbsCertList']['signature']['parameters'] - = array('type' => ASN1::TYPE_UTF8_STRING); + = ['type' => ASN1::TYPE_UTF8_STRING]; $filters['signatureAlgorithm']['parameters'] - = array('type' => ASN1::TYPE_UTF8_STRING); + = ['type' => ASN1::TYPE_UTF8_STRING]; if (empty($crl['tbsCertList']['signature']['parameters'])) { $filters['tbsCertList']['signature']['parameters'] - = array('type' => ASN1::TYPE_NULL); + = ['type' => ASN1::TYPE_NULL]; } if (empty($crl['signatureAlgorithm']['parameters'])) { $filters['signatureAlgorithm']['parameters'] - = array('type' => ASN1::TYPE_NULL); + = ['type' => ASN1::TYPE_NULL]; } - $asn1->loadFilters($filters); + ASN1::setFilters($filters); - $this->_mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1); - $this->_mapOutExtensions($crl, 'tbsCertList/crlExtensions', $asn1); - $rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates'); + $this->mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence'); + $this->mapOutExtensions($crl, 'tbsCertList/crlExtensions'); + $rclist = &$this->subArray($crl, 'tbsCertList/revokedCertificates'); if (is_array($rclist)) { foreach ($rclist as $i => $extension) { - $this->_mapOutExtensions($rclist, "$i/crlEntryExtensions", $asn1); + $this->mapOutExtensions($rclist, "$i/crlEntryExtensions"); } } - $crl = $asn1->encodeDER($crl, $this->CertificateList); + $crl = ASN1::encodeDER($crl, Maps\CertificateList::MAP); switch ($format) { case self::FORMAT_DER: return $crl; // case self::FORMAT_PEM: default: - return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl), 64) . '-----END X509 CRL-----'; + return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Strings::base64_encode($crl), 64) . '-----END X509 CRL-----'; } } @@ -3581,20 +2521,19 @@ class X509 * by choosing utcTime iff year of date given is before 2050 and generalTime else. * * @param string $date in format date('D, d M Y H:i:s O') - * @access private - * @return array + * @return array|Element */ - function _timeField($date) + private function timeField($date) { if ($date instanceof Element) { return $date; } - $dateObj = new DateTime($date, new DateTimeZone('GMT')); + $dateObj = new \DateTimeImmutable($date, new \DateTimeZone('GMT')); $year = $dateObj->format('Y'); // the same way ASN1.php parses this if ($year < 2050) { - return array('utcTime' => $date); + return ['utcTime' => $date]; } else { - return array('generalTime' => $date); + return ['generalTime' => $date]; } } @@ -3605,35 +2544,32 @@ class X509 * $subject can be either an existing X.509 cert (if you want to resign it), * a CSR or something with the DN and public key explicitly set. * - * @param \phpseclib\File\X509 $issuer - * @param \phpseclib\File\X509 $subject - * @param string $signatureAlgorithm optional - * @access public * @return mixed */ - function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption') + public function sign(X509 $issuer, X509 $subject) { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { return false; } - if (isset($subject->publicKey) && !($subjectPublicKey = $subject->_formatSubjectPublicKey())) { + if (isset($subject->publicKey) && !($subjectPublicKey = $subject->formatSubjectPublicKey())) { return false; } $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) { $this->currentCert = $subject->currentCert; - $this->currentCert['tbsCertificate']['signature']['algorithm'] = $signatureAlgorithm; - $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + $this->currentCert['tbsCertificate']['signature'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; if (!empty($this->startDate)) { - $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->_timeField($this->startDate); + $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->timeField($this->startDate); } if (!empty($this->endDate)) { - $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->_timeField($this->endDate); + $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->timeField($this->endDate); } if (!empty($this->serialNumber)) { $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber; @@ -3655,10 +2591,10 @@ class X509 return false; } - $startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get())); + $startDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O'); - $endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get())); + $endDate = new \DateTimeImmutable('+1 year', new \DateTimeZone(@date_default_timezone_get())); $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O'); /* "The serial number MUST be a positive integer" @@ -3672,23 +2608,23 @@ class X509 $this->serialNumber : new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256); - $this->currentCert = array( + $this->currentCert = [ 'tbsCertificate' => - array( + [ 'version' => 'v3', 'serialNumber' => $serialNumber, // $this->setSerialNumber() - 'signature' => array('algorithm' => $signatureAlgorithm), + 'signature' => $signatureAlgorithm, 'issuer' => false, // this is going to be overwritten later - 'validity' => array( - 'notBefore' => $this->_timeField($startDate), // $this->setStartDate() - 'notAfter' => $this->_timeField($endDate) // $this->setEndDate() - ), + 'validity' => [ + 'notBefore' => $this->timeField($startDate), // $this->setStartDate() + 'notAfter' => $this->timeField($endDate) // $this->setEndDate() + ], 'subject' => $subject->dn, 'subjectPublicKeyInfo' => $subjectPublicKey - ), - 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), + ], + 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later - ); + ]; // Copy extensions from CSR. $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0); @@ -3701,14 +2637,14 @@ class X509 $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; if (isset($issuer->currentKeyIdentifier)) { - $this->setExtension('id-ce-authorityKeyIdentifier', array( + $this->setExtension('id-ce-authorityKeyIdentifier', [ //'authorityCertIssuer' => array( // array( // 'directoryName' => $issuer->dn // ) //), 'keyIdentifier' => $issuer->currentKeyIdentifier - )); + ]); //$extensions = &$this->currentCert['tbsCertificate']['extensions']; //if (isset($issuer->serialNumber)) { // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; @@ -3720,18 +2656,18 @@ class X509 $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier); } - $altName = array(); + $altName = []; if (isset($subject->domains) && count($subject->domains)) { - $altName = array_map(array('\phpseclib\File\X509', '_dnsName'), $subject->domains); + $altName = array_map(['\phpseclib3\File\X509', 'dnsName'], $subject->domains); } if (isset($subject->ipAddresses) && count($subject->ipAddresses)) { // should an IP address appear as the CN if no domain name is specified? idk //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1); - $ipAddresses = array(); + $ipAddresses = []; foreach ($subject->ipAddresses as $ipAddress) { - $encoded = $subject->_ipAddress($ipAddress); + $encoded = $subject->ipAddress($ipAddress); if ($encoded !== false) { $ipAddresses[] = $encoded; } @@ -3748,36 +2684,37 @@ class X509 if ($this->caFlag) { $keyUsage = $this->getExtension('id-ce-keyUsage'); if (!$keyUsage) { - $keyUsage = array(); + $keyUsage = []; } $this->setExtension( 'id-ce-keyUsage', - array_values(array_unique(array_merge($keyUsage, array('cRLSign', 'keyCertSign')))) + array_values(array_unique(array_merge($keyUsage, ['cRLSign', 'keyCertSign']))) ); $basicConstraints = $this->getExtension('id-ce-basicConstraints'); if (!$basicConstraints) { - $basicConstraints = array(); + $basicConstraints = []; } $this->setExtension( 'id-ce-basicConstraints', - array_unique(array_merge(array('cA' => true), $basicConstraints)), + array_merge(['cA' => true], $basicConstraints), true ); if (!isset($subject->currentKeyIdentifier)) { - $this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false); + $this->setExtension('id-ce-subjectKeyIdentifier', $this->computeKeyIdentifier($this->currentCert), false, false); } } // resync $this->signatureSubject - // save $tbsCertificate in case there are any \phpseclib\File\ASN1\Element objects in it + // save $tbsCertificate in case there are any \phpseclib3\File\ASN1\Element objects in it $tbsCertificate = $this->currentCert['tbsCertificate']; $this->loadX509($this->saveX509($this->currentCert)); - $result = $this->_sign($issuer->privateKey, $signatureAlgorithm); + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); $result['tbsCertificate'] = $tbsCertificate; $this->currentCert = $currentCert; @@ -3789,53 +2726,49 @@ class X509 /** * Sign a CSR * - * @access public * @return mixed */ - function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption') + public function signCSR() { if (!is_object($this->privateKey) || empty($this->dn)) { return false; } $origPublicKey = $this->publicKey; - $class = get_class($this->privateKey); - $this->publicKey = new $class(); - $this->publicKey->loadKey($this->privateKey->getPublicKey()); - $this->publicKey->setPublicKey(); - if (!($publicKey = $this->_formatSubjectPublicKey())) { - return false; - } + $this->publicKey = $this->privateKey->getPublicKey(); + $publicKey = $this->formatSubjectPublicKey(); $this->publicKey = $origPublicKey; $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) { - $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; if (!empty($this->dn)) { $this->currentCert['certificationRequestInfo']['subject'] = $this->dn; } $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey; } else { - $this->currentCert = array( + $this->currentCert = [ 'certificationRequestInfo' => - array( + [ 'version' => 'v1', 'subject' => $this->dn, 'subjectPKInfo' => $publicKey - ), - 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), + ], + 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later - ); + ]; } // resync $this->signatureSubject - // save $certificationRequestInfo in case there are any \phpseclib\File\ASN1\Element objects in it + // save $certificationRequestInfo in case there are any \phpseclib3\File\ASN1\Element objects in it $certificationRequestInfo = $this->currentCert['certificationRequestInfo']; $this->loadCSR($this->saveCSR($this->currentCert)); - $result = $this->_sign($this->privateKey, $signatureAlgorithm); + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); $result['certificationRequestInfo'] = $certificationRequestInfo; $this->currentCert = $currentCert; @@ -3847,41 +2780,35 @@ class X509 /** * Sign a SPKAC * - * @access public * @return mixed */ - function signSPKAC($signatureAlgorithm = 'sha1WithRSAEncryption') + public function signSPKAC() { if (!is_object($this->privateKey)) { return false; } $origPublicKey = $this->publicKey; - $class = get_class($this->privateKey); - $this->publicKey = new $class(); - $this->publicKey->loadKey($this->privateKey->getPublicKey()); - $this->publicKey->setPublicKey(); - $publicKey = $this->_formatSubjectPublicKey(); - if (!$publicKey) { - return false; - } + $this->publicKey = $this->privateKey->getPublicKey(); + $publicKey = $this->formatSubjectPublicKey(); $this->publicKey = $origPublicKey; $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); // re-signing a SPKAC seems silly but since everything else supports re-signing why not? if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) { - $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey; if (!empty($this->challenge)) { // the bitwise AND ensures that the output is a valid IA5String $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge)); } } else { - $this->currentCert = array( + $this->currentCert = [ 'publicKeyAndChallenge' => - array( + [ 'spki' => $publicKey, // quoting , // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified." @@ -3889,18 +2816,19 @@ class X509 // we could alternatively do this instead if we ignored the specs: // Random::string(8) & str_repeat("\x7F", 8) 'challenge' => !empty($this->challenge) ? $this->challenge : '' - ), - 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), + ], + 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later - ); + ]; } // resync $this->signatureSubject - // save $publicKeyAndChallenge in case there are any \phpseclib\File\ASN1\Element objects in it + // save $publicKeyAndChallenge in case there are any \phpseclib3\File\ASN1\Element objects in it $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge']; $this->loadSPKAC($this->saveSPKAC($this->currentCert)); - $result = $this->_sign($this->privateKey, $signatureAlgorithm); + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); $result['publicKeyAndChallenge'] = $publicKeyAndChallenge; $this->currentCert = $currentCert; @@ -3914,13 +2842,9 @@ class X509 * * $issuer's private key needs to be loaded. * - * @param \phpseclib\File\X509 $issuer - * @param \phpseclib\File\X509 $crl - * @param string $signatureAlgorithm optional - * @access public * @return mixed */ - function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption') + public function signCRL(X509 $issuer, X509 $crl) { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { return false; @@ -3928,34 +2852,35 @@ class X509 $currentCert = isset($this->currentCert) ? $this->currentCert : null; $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); - $thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get())); + $thisUpdate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O'); if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) { $this->currentCert = $crl->currentCert; - $this->currentCert['tbsCertList']['signature']['algorithm'] = $signatureAlgorithm; - $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm; + $this->currentCert['tbsCertList']['signature'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; } else { - $this->currentCert = array( + $this->currentCert = [ 'tbsCertList' => - array( + [ 'version' => 'v2', - 'signature' => array('algorithm' => $signatureAlgorithm), + 'signature' => $signatureAlgorithm, 'issuer' => false, // this is going to be overwritten later - 'thisUpdate' => $this->_timeField($thisUpdate) // $this->setStartDate() - ), - 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm), + 'thisUpdate' => $this->timeField($thisUpdate) // $this->setStartDate() + ], + 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later - ); + ]; } $tbsCertList = &$this->currentCert['tbsCertList']; $tbsCertList['issuer'] = $issuer->dn; - $tbsCertList['thisUpdate'] = $this->_timeField($thisUpdate); + $tbsCertList['thisUpdate'] = $this->timeField($thisUpdate); if (!empty($this->endDate)) { - $tbsCertList['nextUpdate'] = $this->_timeField($this->endDate); // $this->setEndDate() + $tbsCertList['nextUpdate'] = $this->timeField($this->endDate); // $this->setEndDate() } else { unset($tbsCertList['nextUpdate']); } @@ -4000,14 +2925,14 @@ class X509 } if (isset($issuer->currentKeyIdentifier)) { - $this->setExtension('id-ce-authorityKeyIdentifier', array( + $this->setExtension('id-ce-authorityKeyIdentifier', [ //'authorityCertIssuer' => array( - // array( + // ] // 'directoryName' => $issuer->dn - // ) + // ] //), 'keyIdentifier' => $issuer->currentKeyIdentifier - )); + ]); //$extensions = &$tbsCertList['crlExtensions']; //if (isset($issuer->serialNumber)) { // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; @@ -4029,11 +2954,12 @@ class X509 unset($tbsCertList); // resync $this->signatureSubject - // save $tbsCertList in case there are any \phpseclib\File\ASN1\Element objects in it + // save $tbsCertList in case there are any \phpseclib3\File\ASN1\Element objects in it $tbsCertList = $this->currentCert['tbsCertList']; $this->loadCRL($this->saveCRL($this->currentCert)); - $result = $this->_sign($issuer->privateKey, $signatureAlgorithm); + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); $result['tbsCertList'] = $tbsCertList; $this->currentCert = $currentCert; @@ -4043,45 +2969,74 @@ class X509 } /** - * X.509 certificate signing helper function. + * Identify signature algorithm from key settings * - * @param \phpseclib\File\X509 $key - * @param string $signatureAlgorithm - * @access public - * @return mixed + * @param PrivateKey $key + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return array */ - function _sign($key, $signatureAlgorithm) + private static function identifySignatureAlgorithm(PrivateKey $key) { if ($key instanceof RSA) { - switch ($signatureAlgorithm) { - case 'md2WithRSAEncryption': - case 'md5WithRSAEncryption': - case 'sha1WithRSAEncryption': - case 'sha224WithRSAEncryption': - case 'sha256WithRSAEncryption': - case 'sha384WithRSAEncryption': - case 'sha512WithRSAEncryption': - $key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)); - $key->setSignatureMode(RSA::SIGNATURE_PKCS1); - - $this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject)); - return $this->currentCert; + if ($key->getPadding() & RSA::SIGNATURE_PSS) { + $r = PSS::load($key->withPassword()->toString('PSS')); + return [ + 'algorithm' => 'id-RSASSA-PSS', + 'parameters' => PSS::savePSSParams($r) + ]; } + switch ($key->getHash()) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha224': + case 'sha256': + case 'sha384': + case 'sha512': + return ['algorithm' => $key->getHash() . 'WithRSAEncryption']; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for RSA are: md2, md5, sha1, sha224, sha256, sha384, sha512'); } - return false; + if ($key instanceof DSA) { + switch ($key->getHash()) { + case 'sha1': + case 'sha224': + case 'sha256': + return ['algorithm' => 'id-dsa-with-' . $key->getHash()]; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for DSA are: sha1, sha224, sha256'); + } + + if ($key instanceof EC) { + switch ($key->getCurve()) { + case 'Ed25519': + case 'Ed448': + return ['algorithm' => 'id-' . $key->getCurve()]; + } + switch ($key->getHash()) { + case 'sha1': + case 'sha224': + case 'sha256': + case 'sha384': + case 'sha512': + return ['algorithm' => 'ecdsa-with-' . strtoupper($key->getHash())]; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for EC are: sha1, sha224, sha256, sha384, sha512'); + } + + throw new UnsupportedAlgorithmException('The only supported public key classes are: RSA, DSA, EC'); } /** * Set certificate start date * - * @param string $date - * @access public + * @param \DateTimeInterface|string $date */ - function setStartDate($date) + public function setStartDate($date) { - if (!is_object($date) || !is_a($date, 'DateTime')) { - $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get())); + if (!is_object($date) || !($date instanceof \DateTimeInterface)) { + $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); } $this->startDate = $date->format('D, d M Y H:i:s O'); @@ -4090,10 +3045,9 @@ class X509 /** * Set certificate end date * - * @param string $date - * @access public + * @param \DateTimeInterface|string $date */ - function setEndDate($date) + public function setEndDate($date) { /* To indicate that a certificate has no well-defined expiration date, @@ -4102,14 +3056,13 @@ class X509 -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */ - if (strtolower($date) == 'lifetime') { + if (is_string($date) && strtolower($date) === 'lifetime') { $temp = '99991231235959Z'; - $asn1 = new ASN1(); - $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp; + $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . ASN1::encodeLength(strlen($temp)) . $temp; $this->endDate = new Element($temp); } else { - if (!is_object($date) || !is_a($date, 'DateTime')) { - $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get())); + if (!is_object($date) || !($date instanceof \DateTimeInterface)) { + $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); } $this->endDate = $date->format('D, d M Y H:i:s O'); @@ -4121,9 +3074,8 @@ class X509 * * @param string $serial * @param int $base optional - * @access public */ - function setSerialNumber($serial, $base = -256) + public function setSerialNumber($serial, $base = -256) { $this->serialNumber = new BigInteger($serial, $base); } @@ -4131,9 +3083,8 @@ class X509 /** * Turns the certificate into a certificate authority * - * @access public */ - function makeCA() + public function makeCA() { $this->caFlag = true; } @@ -4148,9 +3099,8 @@ class X509 * @param array $root * @param string $path * @return boolean - * @access private */ - function _isSubArrayValid($root, $path) + private function isSubArrayValid(array $root, $path) { if (!is_array($root)) { return false; @@ -4184,10 +3134,9 @@ class X509 * @param array $root * @param string $path absolute path with / as component separator * @param bool $create optional - * @access private * @return array|false */ - function &_subArrayUnchecked(&$root, $path, $create = false) + private function &subArrayUnchecked(array &$root, $path, $create = false) { $false = false; @@ -4197,7 +3146,7 @@ class X509 return $false; } - $root[$i] = array(); + $root[$i] = []; } $root = &$root[$i]; @@ -4212,10 +3161,9 @@ class X509 * @param array $root * @param string $path absolute path with / as component separator * @param bool $create optional - * @access private * @return array|false */ - function &_subArray(&$root, $path, $create = false) + private function &subArray(array &$root = null, $path, $create = false) { $false = false; @@ -4233,7 +3181,7 @@ class X509 return $false; } - $root[$i] = array(); + $root[$i] = []; } $root = &$root[$i]; @@ -4248,10 +3196,9 @@ class X509 * @param array $root * @param string $path optional absolute path with / as component separator * @param bool $create optional - * @access private * @return array|false */ - function &_extensions(&$root, $path = null, $create = false) + private function &extensions(array &$root = null, $path = null, $create = false) { if (!isset($root)) { $root = $this->currentCert; @@ -4269,7 +3216,7 @@ class X509 break; case isset($root['certificationRequestInfo']): $pth = 'certificationRequestInfo/attributes'; - $attributes = &$this->_subArray($root, $pth, $create); + $attributes = &$this->subArray($root, $pth, $create); if (is_array($attributes)) { foreach ($attributes as $key => $value) { @@ -4280,14 +3227,14 @@ class X509 } if ($create) { $key = count($attributes); - $attributes[] = array('type' => 'pkcs-9-at-extensionRequest', 'value' => array()); + $attributes[] = ['type' => 'pkcs-9-at-extensionRequest', 'value' => []]; $path = "$pth/$key/value/0"; } } break; } - $extensions = &$this->_subArray($root, $path, $create); + $extensions = &$this->subArray($root, $path, $create); if (!is_array($extensions)) { $false = false; @@ -4302,12 +3249,11 @@ class X509 * * @param string $id * @param string $path optional - * @access private * @return bool */ - function _removeExtension($id, $path = null) + private function removeExtensionHelper($id, $path = null) { - $extensions = &$this->_extensions($this->currentCert, $path); + $extensions = &$this->extensions($this->currentCert, $path); if (!is_array($extensions)) { return false; @@ -4337,12 +3283,11 @@ class X509 * @param string $id * @param array $cert optional * @param string $path optional - * @access private * @return mixed */ - function _getExtension($id, $cert = null, $path = null) + private function getExtensionHelper($id, array $cert = null, $path = null) { - $extensions = $this->_extensions($cert, $path); + $extensions = $this->extensions($cert, $path); if (!is_array($extensions)) { return false; @@ -4362,13 +3307,12 @@ class X509 * * @param array $cert optional * @param string $path optional - * @access private * @return array */ - function _getExtensions($cert = null, $path = null) + private function getExtensionsHelper(array $cert = null, $path = null) { - $exts = $this->_extensions($cert, $path); - $extensions = array(); + $exts = $this->extensions($cert, $path); + $extensions = []; if (is_array($exts)) { foreach ($exts as $extension) { @@ -4387,18 +3331,17 @@ class X509 * @param bool $critical optional * @param bool $replace optional * @param string $path optional - * @access private * @return bool */ - function _setExtension($id, $value, $critical = false, $replace = true, $path = null) + private function setExtensionHelper($id, $value, $critical = false, $replace = true, $path = null) { - $extensions = &$this->_extensions($this->currentCert, $path, true); + $extensions = &$this->extensions($this->currentCert, $path, true); if (!is_array($extensions)) { return false; } - $newext = array('extnId' => $id, 'critical' => $critical, 'extnValue' => $value); + $newext = ['extnId' => $id, 'critical' => $critical, 'extnValue' => $value]; foreach ($extensions as $key => $value) { if ($value['extnId'] == $id) { @@ -4419,12 +3362,11 @@ class X509 * Remove a certificate, CSR or CRL Extension * * @param string $id - * @access public * @return bool */ - function removeExtension($id) + public function removeExtension($id) { - return $this->_removeExtension($id); + return $this->removeExtensionHelper($id); } /** @@ -4434,24 +3376,24 @@ class X509 * * @param string $id * @param array $cert optional - * @access public + * @param string $path * @return mixed */ - function getExtension($id, $cert = null) + public function getExtension($id, array $cert = null, $path = null) { - return $this->_getExtension($id, $cert); + return $this->getExtensionHelper($id, $cert, $path); } /** * Returns a list of all extensions in use in certificate, CSR or CRL * * @param array $cert optional - * @access public + * @param string $path optional * @return array */ - function getExtensions($cert = null) + public function getExtensions(array $cert = null, $path = null) { - return $this->_getExtensions($cert); + return $this->getExtensionsHelper($cert, $path); } /** @@ -4461,12 +3403,11 @@ class X509 * @param mixed $value * @param bool $critical optional * @param bool $replace optional - * @access public * @return bool */ - function setExtension($id, $value, $critical = false, $replace = true) + public function setExtension($id, $value, $critical = false, $replace = true) { - return $this->_setExtension($id, $value, $critical, $replace); + return $this->setExtensionHelper($id, $value, $critical, $replace); } /** @@ -4474,12 +3415,11 @@ class X509 * * @param string $id * @param int $disposition optional - * @access public * @return bool */ - function removeAttribute($id, $disposition = self::ATTR_ALL) + public function removeAttribute($id, $disposition = self::ATTR_ALL) { - $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes'); + $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { return false; @@ -4525,16 +3465,15 @@ class X509 * @param string $id * @param int $disposition optional * @param array $csr optional - * @access public * @return mixed */ - function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null) + public function getAttribute($id, $disposition = self::ATTR_ALL, array $csr = null) { if (empty($csr)) { $csr = $this->currentCert; } - $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes'); + $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { return false; @@ -4565,17 +3504,16 @@ class X509 * Returns a list of all CSR attributes in use * * @param array $csr optional - * @access public * @return array */ - function getAttributes($csr = null) + public function getAttributes(array $csr = null) { if (empty($csr)) { $csr = $this->currentCert; } - $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes'); - $attrs = array(); + $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); + $attrs = []; if (is_array($attributes)) { foreach ($attributes as $attribute) { @@ -4591,13 +3529,12 @@ class X509 * * @param string $id * @param mixed $value - * @param bool $disposition optional - * @access public + * @param int $disposition optional * @return bool */ - function setAttribute($id, $value, $disposition = self::ATTR_ALL) + public function setAttribute($id, $value, $disposition = self::ATTR_ALL) { - $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes', true); + $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes', true); if (!is_array($attributes)) { return false; @@ -4606,6 +3543,7 @@ class X509 switch ($disposition) { case self::ATTR_REPLACE: $disposition = self::ATTR_APPEND; + // fall-through case self::ATTR_ALL: $this->removeAttribute($id); break; @@ -4635,7 +3573,7 @@ class X509 $attributes[$last]['value'][] = $value; break; default: - $attributes[] = array('type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value: array($value)); + $attributes[] = ['type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value : [$value]]; break; } @@ -4648,14 +3586,13 @@ class X509 * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions. * * @param string $value - * @access public */ - function setKeyIdentifier($value) + public function setKeyIdentifier($value) { if (empty($value)) { unset($this->currentKeyIdentifier); } else { - $this->currentKeyIdentifier = base64_encode($value); + $this->currentKeyIdentifier = $value; } } @@ -4667,17 +3604,16 @@ class X509 * recommended methods (4.2.1.2 RFC 3280). * Highly polymorphic: try to accept all possible forms of key: * - Key object - * - \phpseclib\File\X509 object with public or private key defined + * - \phpseclib3\File\X509 object with public or private key defined * - Certificate or CSR array - * - \phpseclib\File\ASN1\Element object + * - \phpseclib3\File\ASN1\Element object * - PEM or DER string * * @param mixed $key optional * @param int $method optional - * @access public * @return string binary key identifier */ - function computeKeyIdentifier($key = null, $method = 1) + public function computeKeyIdentifier($key = null, $method = 1) { if (is_null($key)) { $key = $this; @@ -4694,25 +3630,20 @@ class X509 return false; case $key instanceof Element: // Assume the element is a bitstring-packed key. - $asn1 = new ASN1(); - $decoded = $asn1->decodeBER($key->element); - if (empty($decoded)) { + $decoded = ASN1::decodeBER($key->element); + if (!$decoded) { return false; } - $raw = $asn1->asn1map($decoded[0], array('type' => ASN1::TYPE_BIT_STRING)); + $raw = ASN1::asn1map($decoded[0], ['type' => ASN1::TYPE_BIT_STRING]); if (empty($raw)) { return false; } - $raw = base64_decode($raw); // If the key is private, compute identifier from its corresponding public key. - $key = new RSA(); - if (!$key->loadKey($raw)) { - return false; // Not an unencrypted RSA key. - } - if ($key->getPrivateKey() !== false) { // If private. + $key = PublicKeyLoader::load($raw); + if ($key instanceof PrivateKey) { // If private. return $this->computeKeyIdentifier($key, $method); } - $key = $raw; // Is a public key. + $key = $raw; // Is a public key. break; case $key instanceof X509: if (isset($key->publicKey)) { @@ -4725,13 +3656,13 @@ class X509 return $this->computeKeyIdentifier($key->currentCert, $method); } return false; - default: // Should be a key object (i.e.: \phpseclib\Crypt\RSA). - $key = $key->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); + default: // Should be a key object (i.e.: \phpseclib3\Crypt\RSA). + $key = $key->getPublicKey(); break; } // If in PEM format, convert to binary. - $key = $this->_extractBER($key); + $key = ASN1::extractBER($key); // Now we have the key string: compute its sha-1 sum. $hash = new Hash('sha1'); @@ -4748,33 +3679,39 @@ class X509 /** * Format a public key as appropriate * - * @access private - * @return array + * @return array|false */ - function _formatSubjectPublicKey() + private function formatSubjectPublicKey() { - if ($this->publicKey instanceof RSA) { - // the following two return statements do the same thing. i dunno.. i just prefer the later for some reason. - // the former is a good example of how to do fuzzing on the public key - //return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey()))); - return array( - 'algorithm' => array('algorithm' => 'rsaEncryption'), - 'subjectPublicKey' => $this->publicKey->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1) - ); + $format = $this->publicKey instanceof RSA && ($this->publicKey->getPadding() & RSA::SIGNATURE_PSS) ? + 'PSS' : + 'PKCS8'; + + $publicKey = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->toString($format))); + + $decoded = ASN1::decodeBER($publicKey); + if (!$decoded) { + return false; + } + $mapped = ASN1::asn1map($decoded[0], Maps\SubjectPublicKeyInfo::MAP); + if (!is_array($mapped)) { + return false; } - return false; + $mapped['subjectPublicKey'] = $this->publicKey->toString($format); + + return $mapped; } /** * Set the domain name's which the cert is to be valid for * - * @access public - * @return array + * @param mixed ...$domains + * @return void */ - function setDomain() + public function setDomain(...$domains) { - $this->domains = func_get_args(); + $this->domains = $domains; $this->removeDNProp('id-at-commonName'); $this->setDNProp('id-at-commonName', $this->domains[0]); } @@ -4782,11 +3719,11 @@ class X509 /** * Set the IP Addresses's which the cert is to be valid for * - * @access public + * @param mixed[] ...$ipAddresses */ - function setIPAddress() + public function setIPAddress(...$ipAddresses) { - $this->ipAddresses = func_get_args(); + $this->ipAddresses = $ipAddresses; /* if (!isset($this->domains)) { $this->removeDNProp('id-at-commonName'); @@ -4798,13 +3735,12 @@ class X509 /** * Helper function to build domain array * - * @access private * @param string $domain * @return array */ - function _dnsName($domain) + private static function dnsName($domain) { - return array('dNSName' => $domain); + return ['dNSName' => $domain]; } /** @@ -4812,13 +3748,12 @@ class X509 * * (IPv6 is not currently supported) * - * @access private * @param string $address * @return array */ - function _iPAddress($address) + private function iPAddress($address) { - return array('iPAddress' => $address); + return ['iPAddress' => $address]; } /** @@ -4827,10 +3762,9 @@ class X509 * @param array $rclist * @param string $serial * @param bool $create optional - * @access private * @return int|false */ - function _revokedCertificate(&$rclist, $serial, $create = false) + private function revokedCertificate(array &$rclist, $serial, $create = false) { $serial = new BigInteger($serial); @@ -4845,9 +3779,9 @@ class X509 } $i = count($rclist); - $revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get())); - $rclist[] = array('userCertificate' => $serial, - 'revocationDate' => $this->_timeField($revocationDate->format('D, d M Y H:i:s O'))); + $revocationDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); + $rclist[] = ['userCertificate' => $serial, + 'revocationDate' => $this->timeField($revocationDate->format('D, d M Y H:i:s O'))]; return $i; } @@ -4856,17 +3790,16 @@ class X509 * * @param string $serial * @param string $date optional - * @access public * @return bool */ - function revoke($serial, $date = null) + public function revoke($serial, $date = null) { if (isset($this->currentCert['tbsCertList'])) { - if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { - if ($this->_revokedCertificate($rclist, $serial) === false) { // If not yet revoked - if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if ($this->revokedCertificate($rclist, $serial) === false) { // If not yet revoked + if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { if (!empty($date)) { - $rclist[$i]['revocationDate'] = $this->_timeField($date); + $rclist[$i]['revocationDate'] = $this->timeField($date); } return true; @@ -4882,13 +3815,12 @@ class X509 * Unrevoke a certificate. * * @param string $serial - * @access public * @return bool */ - function unrevoke($serial) + public function unrevoke($serial) { - if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { unset($rclist[$i]); $rclist = array_values($rclist); return true; @@ -4902,13 +3834,12 @@ class X509 * Get a revoked certificate. * * @param string $serial - * @access public * @return mixed */ - function getRevoked($serial) + public function getRevoked($serial) { - if (is_array($rclist = $this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { + if (is_array($rclist = $this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { return $rclist[$i]; } } @@ -4920,10 +3851,9 @@ class X509 * List revoked certificates * * @param array $crl optional - * @access public - * @return array + * @return array|bool */ - function listRevoked($crl = null) + public function listRevoked(array $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; @@ -4933,9 +3863,9 @@ class X509 return false; } - $result = array(); + $result = []; - if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { foreach ($rclist as $rc) { $result[] = $rc['userCertificate']->toString(); } @@ -4949,14 +3879,13 @@ class X509 * * @param string $serial * @param string $id - * @access public * @return bool */ - function removeRevokedCertificateExtension($serial, $id) + public function removeRevokedCertificateExtension($serial, $id) { - if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { - return $this->_removeExtension($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->removeExtensionHelper($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } @@ -4971,18 +3900,17 @@ class X509 * @param string $serial * @param string $id * @param array $crl optional - * @access public * @return mixed */ - function getRevokedCertificateExtension($serial, $id, $crl = null) + public function getRevokedCertificateExtension($serial, $id, array $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } - if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { - return $this->_getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } @@ -4994,18 +3922,17 @@ class X509 * * @param string $serial * @param array $crl optional - * @access public - * @return array + * @return array|bool */ - function getRevokedCertificateExtensions($serial, $crl = null) + public function getRevokedCertificateExtensions($serial, array $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } - if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) { - return $this->_getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } @@ -5020,15 +3947,14 @@ class X509 * @param mixed $value * @param bool $critical optional * @param bool $replace optional - * @access public * @return bool */ - function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) + public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) { if (isset($this->currentCert['tbsCertList'])) { - if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { - if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) { - return $this->_setExtension($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { + return $this->setExtensionHelper($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } } @@ -5037,61 +3963,44 @@ class X509 } /** - * Extract raw BER from Base64 encoding + * Register the mapping for a custom/unsupported extension. * - * @access private - * @param string $str - * @return string + * @param string $id + * @param array $mapping */ - function _extractBER($str) + public static function registerExtension($id, array $mapping) { - /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them - * above and beyond the ceritificate. - * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: - * - * Bag Attributes - * localKeyID: 01 00 00 00 - * subject=/O=organization/OU=org unit/CN=common name - * issuer=/O=organization/CN=common name - */ - if (strlen($str) > ini_get('pcre.backtrack_limit')) { - $temp = $str; - } else { - $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); - $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1); + if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { + throw new \RuntimeException( + 'Extension ' . $id . ' has already been defined with a different mapping.' + ); } - // remove new lines - $temp = str_replace(array("\r", "\n", ' '), '', $temp); - // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff - $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; - return $temp != false ? $temp : $str; + + self::$extensions[$id] = $mapping; } /** - * Returns the OID corresponding to a name + * Register the mapping for a custom/unsupported extension. * - * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if - * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version - * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able - * to work from version to version. + * @param string $id * - * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that - * what's being passed to it already is an OID and return that instead. A few examples. - * - * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' - * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' - * getOID('zzz') == 'zzz' - * - * @access public - * @return string + * @return array|null */ - function getOID($name) + public static function getRegisteredExtension($id) { - static $reverseMap; - if (!isset($reverseMap)) { - $reverseMap = array_flip($this->oids); - } - return isset($reverseMap[$name]) ? $reverseMap[$name] : $name; + return isset(self::$extensions[$id]) ? self::$extensions[$id] : null; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * @param mixed $value + * @param bool $critical + * @param bool $replace + */ + public function setExtensionValue($id, $value, $critical = false, $replace = false) + { + $this->extensionValues[$id] = compact('critical', 'replace', 'value'); } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php new file mode 100644 index 000000000..3f4dc2ed7 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -0,0 +1,893 @@ + + * add($b); + * + * echo $c->toString(); // outputs 5 + * ?> + * + * + * @author Jim Wigginton + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math; + +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger\Engines\Engine; +use UnexpectedValueException; + +/** + * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 + * numbers. + * + * @author Jim Wigginton + */ +class BigInteger implements \JsonSerializable +{ + /** + * Main Engine + * + * @var class-string + */ + private static $mainEngine; + + /** + * Selected Engines + * + * @var list + */ + private static $engines; + + /** + * The actual BigInteger object + * + * @var object + */ + private $value; + + /** + * Mode independent value used for serialization. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + */ + private $hex; + + /** + * Precision (used only for serialization) + * + * @see self::__sleep() + * @see self::__wakeup() + * @var int + */ + private $precision; + + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param string $main + * @param list $modexps optional + * @return void + */ + public static function setEngine($main, array $modexps = ['DefaultEngine']) + { + self::$engines = []; + + $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; + if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { + throw new \InvalidArgumentException("$main is not a valid engine"); + } + if (!$fqmain::isValidEngine()) { + throw new BadConfigurationException("$main is not setup correctly on this system"); + } + /** @var class-string $fqmain */ + self::$mainEngine = $fqmain; + + $found = false; + foreach ($modexps as $modexp) { + try { + $fqmain::setModExpEngine($modexp); + $found = true; + break; + } catch (\Exception $e) { + } + } + + if (!$found) { + throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); + } + + self::$engines = [$main, $modexp]; + } + + /** + * Returns the engine type + * + * @return string[] + */ + public static function getEngine() + { + self::initialize_static_variables(); + + return self::$engines; + } + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!isset(self::$mainEngine)) { + $engines = [ + ['GMP', ['DefaultEngine']], + ['PHP64', ['OpenSSL']], + ['BCMath', ['OpenSSL']], + ['PHP32', ['OpenSSL']], + ['PHP64', ['DefaultEngine']], + ['PHP32', ['DefaultEngine']] + ]; + + foreach ($engines as $engine) { + try { + self::setEngine($engine[0], $engine[1]); + return; + } catch (\Exception $e) { + } + } + + throw new UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath'); + } + } + + /** + * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. + * + * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using + * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. + * + * @param string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x = 0, $base = 10) + { + self::initialize_static_variables(); + + if ($x instanceof self::$mainEngine) { + $this->value = clone $x; + } elseif ($x instanceof BigInteger\Engines\Engine) { + $this->value = new static("$x"); + $this->value->setPrecision($x->getPrecision()); + } else { + $this->value = new self::$mainEngine($x, $base); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return $this->value->toString(); + } + + /** + * __toString() magic method + */ + public function __toString() + { + return (string)$this->value; + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + */ + public function __debugInfo() + { + return $this->value->__debugInfo(); + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + return $this->value->toBytes($twos_compliment); + } + + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = false) + { + return $this->value->toHex($twos_compliment); + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + return $this->value->toBits($twos_compliment); + } + + /** + * Adds two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function add(BigInteger $y) + { + return new static($this->value->add($y->value)); + } + + /** + * Subtracts two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function subtract(BigInteger $y) + { + return new static($this->value->subtract($y->value)); + } + + /** + * Multiplies two BigIntegers + * + * @param BigInteger $x + * @return BigInteger + */ + public function multiply(BigInteger $x) + { + return new static($this->value->multiply($x->value)); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * Here's an example: + * + * divide($b); + * + * echo $quotient->toString(); // outputs 0 + * echo "\r\n"; + * echo $remainder->toString(); // outputs 10 + * ?> + * + * + * @param BigInteger $y + * @return BigInteger[] + */ + public function divide(BigInteger $y) + { + list($q, $r) = $this->value->divide($y->value); + return [ + new static($q), + new static($r) + ]; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BigInteger $n + * @return BigInteger + */ + public function modInverse(BigInteger $n) + { + return new static($this->value->modInverse($n->value)); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BigInteger $n + * @return BigInteger[] + */ + public function extendedGCD(BigInteger $n) + { + extract($this->value->extendedGCD($n->value)); + /** + * @var BigInteger $gcd + * @var BigInteger $x + * @var BigInteger $y + */ + return [ + 'gcd' => new static($gcd), + 'x' => new static($x), + 'y' => new static($y) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BigInteger $n + * @return BigInteger + */ + public function gcd(BigInteger $n) + { + return new static($this->value->gcd($n->value)); + } + + /** + * Absolute value. + * + * @return BigInteger + */ + public function abs() + { + return new static($this->value->abs()); + } + + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + $this->value->setPrecision($bits); + } + + /** + * Get Precision + * + * Returns the precision if it exists, false if it doesn't + * + * @return int|bool + */ + public function getPrecision() + { + return $this->value->getPrecision(); + } + + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * __sleep() / __wakeup() have been around since PHP 4.0 + * + * \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1: + * https://wiki.php.net/rfc/phase_out_serializable + * + * __serialize() / __unserialize() were introduced in PHP 7.4: + * https://wiki.php.net/rfc/custom_object_serialization + * + * @return array + */ + public function __sleep() + { + $this->hex = $this->toHex(true); + $vars = ['hex']; + if ($this->getPrecision() > 0) { + $vars[] = 'precision'; + } + return $vars; + } + + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + */ + public function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * @return array{hex: string, precision?: int] + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $result = ['hex' => $this->toHex(true)]; + if ($this->precision > 0) { + $result['precision'] = $this->getPrecision(); + } + return $result; + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function powMod(BigInteger $e, BigInteger $n) + { + return new static($this->value->powMod($e->value, $n->value)); + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function modPow(BigInteger $e, BigInteger $n) + { + return new static($this->value->modPow($e->value, $n->value)); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BigInteger $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(BigInteger $y) + { + return $this->value->compare($y->value); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BigInteger $x + * @return bool + */ + public function equals(BigInteger $x) + { + return $this->value->equals($x->value); + } + + /** + * Logical Not + * + * @return BigInteger + */ + public function bitwise_not() + { + return new static($this->value->bitwise_not()); + } + + /** + * Logical And + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_and(BigInteger $x) + { + return new static($this->value->bitwise_and($x->value)); + } + + /** + * Logical Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_or(BigInteger $x) + { + return new static($this->value->bitwise_or($x->value)); + } + + /** + * Logical Exclusive Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_xor(BigInteger $x) + { + return new static($this->value->bitwise_xor($x->value)); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightShift($shift) + { + return new static($this->value->bitwise_rightShift($shift)); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftShift($shift) + { + return new static($this->value->bitwise_leftShift($shift)); + } + + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftRotate($shift) + { + return new static($this->value->bitwise_leftRotate($shift)); + } + + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightRotate($shift) + { + return new static($this->value->bitwise_rightRotate($shift)); + } + + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return BigInteger[] + */ + public static function minMaxBits($bits) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + extract($class::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + return [ + 'min' => new static($min), + 'max' => new static($max) + ]; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return $this->value->getLength(); + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return $this->value->getLengthInBytes(); + } + + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function random($size) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + return new static($class::random($size)); + } + + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function randomPrime($size) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + return new static($class::randomPrime($size)); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BigInteger $min + * @param BigInteger $max + * @return false|BigInteger + */ + public static function randomRangePrime(BigInteger $min, BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRangePrime($min->value, $max->value)); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BigInteger $min + * @param BigInteger $max + * @return BigInteger + */ + public static function randomRange(BigInteger $min, BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRange($min->value, $max->value)); + } + + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = false) + { + return $this->value->isPrime($t); + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n optional + * @return BigInteger + */ + public function root($n = 2) + { + return new static($this->value->root($n)); + } + + /** + * Performs exponentiation. + * + * @param BigInteger $n + * @return BigInteger + */ + public function pow(BigInteger $n) + { + return new static($this->value->pow($n->value)); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function min(BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = array_map(function ($num) { + return $num->value; + }, $nums); + return new static($class::min(...$nums)); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function max(BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = array_map(function ($num) { + return $num->value; + }, $nums); + return new static($class::max(...$nums)); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BigInteger $min + * @param BigInteger $max + * @return bool + */ + public function between(BigInteger $min, BigInteger $max) + { + return $this->value->between($min->value, $max->value); + } + + /** + * Clone + */ + public function __clone() + { + $this->value = clone $this->value; + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value->isOdd(); + } + + /** + * Tests if a bit is set + * + * @param int $x + * @return bool + */ + public function testBit($x) + { + return $this->value->testBit($x); + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return $this->value->isNegative(); + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BigInteger + */ + public function negate() + { + return new static($this->value->negate()); + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BigInteger $r + * @return int + */ + public static function scan1divide(BigInteger $r) + { + $class = self::$mainEngine; + return $class::scan1divide($r->value); + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $func = $this->value->createRecurringModuloFunction(); + return function (BigInteger $x) use ($func) { + return new static($func($x->value)); + }; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return BigInteger[] + */ + public function bitwise_split($split) + { + return array_map(function ($val) { + return new static($val); + }, $this->value->bitwise_split($split)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php new file mode 100644 index 000000000..7c5ca9fb3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php @@ -0,0 +1,697 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; + +/** + * BCMath Engine. + * + * @author Jim Wigginton + */ +class BCMath extends Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = false; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'BCMath'; + + /** + * Test for engine validity + * + * @return bool + * @see parent::__construct() + */ + public static function isValidEngine() + { + return extension_loaded('bcmath'); + } + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new BadConfigurationException('BCMath is not setup correctly on this system'); + } + + $this->value = '0'; + + parent::__construct($x, $base); + } + + /** + * Initialize a BCMath BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 256: + // round $len to the nearest 4 + $len = (strlen($this->value) + 3) & ~3; + + $x = str_pad($this->value, $len, chr(0), STR_PAD_LEFT); + + $this->value = '0'; + for ($i = 0; $i < $len; $i += 4) { + $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 + $this->value = bcadd( + $this->value, + 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord( + $x[$i + 2] + ) << 8) | ord($x[$i + 3])), + 0 + ); + } + + if ($this->is_negative) { + $this->value = '-' . $this->value; + } + break; + case 16: + $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; + $temp = new self(Strings::hex2bin($x), 256); + $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; + $this->is_negative = false; + break; + case 10: + // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different + // results then doing it on '-1' does (modInverse does $x[0]) + $this->value = $this->value === '-' ? '0' : (string)$this->value; + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if ($this->value === '0') { + return '0'; + } + + return ltrim($this->value, '0'); + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + $value = ''; + $current = $this->value; + + if ($current[0] == '-') { + $current = substr($current, 1); + } + + while (bccomp($current, '0', 0) > 0) { + $temp = bcmod($current, '16777216'); + $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; + $current = bcdiv($current, '16777216', 0); + } + + return $this->precision > 0 ? + substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($value, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function add(BCMath $y) + { + $temp = new self(); + $temp->value = bcadd($this->value, $y->value); + + return $this->normalize($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function subtract(BCMath $y) + { + $temp = new self(); + $temp->value = bcsub($this->value, $y->value); + + return $this->normalize($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param BCMath $x + * @return BCMath + */ + public function multiply(BCMath $x) + { + $temp = new self(); + $temp->value = bcmul($this->value, $x->value); + + return $this->normalize($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param BCMath $y + * @return array{static, static} + */ + public function divide(BCMath $y) + { + $quotient = new self(); + $remainder = new self(); + + $quotient->value = bcdiv($this->value, $y->value, 0); + $remainder->value = bcmod($this->value, $y->value); + + if ($remainder->value[0] == '-') { + $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); + } + + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BCMath $n + * @return false|BCMath + */ + public function modInverse(BCMath $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param BCMath $n + * @return array{gcd: static, x: static, y: static} + */ + public function extendedGCD(BCMath $n) + { + // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works + // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, + // the basic extended euclidean algorithim is what we're using. + + $u = $this->value; + $v = $n->value; + + $a = '1'; + $b = '0'; + $c = '0'; + $d = '1'; + + while (bccomp($v, '0', 0) != 0) { + $q = bcdiv($u, $v, 0); + + $temp = $u; + $u = $v; + $v = bcsub($temp, bcmul($v, $q, 0), 0); + + $temp = $a; + $a = $c; + $c = bcsub($temp, bcmul($a, $q, 0), 0); + + $temp = $b; + $b = $d; + $d = bcsub($temp, bcmul($b, $q, 0), 0); + } + + return [ + 'gcd' => $this->normalize(new static($u)), + 'x' => $this->normalize(new static($a)), + 'y' => $this->normalize(new static($b)) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BCMath $n + * @return BCMath + */ + public function gcd(BCMath $n) + { + extract($this->extendedGCD($n)); + /** @var BCMath $gcd */ + return $gcd; + } + + /** + * Absolute value. + * + * @return BCMath + */ + public function abs() + { + $temp = new static(); + $temp->value = strlen($this->value) && $this->value[0] == '-' ? + substr($this->value, 1) : + $this->value; + + return $temp; + } + + /** + * Logical And + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_and(BCMath $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_or(BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_xor(BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BCMath + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BCMath + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); + + return $this->normalize($temp); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BCMath $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(BCMath $y) + { + return bccomp($this->value, $y->value, 0); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BCMath $x + * @return bool + */ + public function equals(BCMath $x) + { + return $this->value == $x->value; + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function modPow(BCMath $e, BCMath $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function powMod(BCMath $e, BCMath $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected function powModInner(BCMath $e, BCMath $n) + { + try { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param BCMath $result + * @return BCMath + */ + protected function normalize(BCMath $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + if ($result->bitmask !== false) { + $result->value = bcmod($result->value, $result->bitmask->value); + } + + return $result; + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BCMath $min + * @param BCMath $max + * @return false|BCMath + */ + public static function randomRangePrime(BCMath $min, BCMath $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BCMath $min + * @param BCMath $max + * @return BCMath + */ + public static function randomRange(BCMath $min, BCMath $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + if (!$this->isOdd()) { + $this->value = bcadd($this->value, '1'); + } + } + + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value === '1') { + return false; + } + if ($this->value === '2') { + return true; + } + if ($this->value[strlen($this->value) - 1] % 2 == 0) { + return false; + } + + $value = $this->value; + + foreach (self::PRIMES as $prime) { + $r = bcmod($this->value, $prime); + if ($r == '0') { + return $this->value == $prime; + } + } + + return true; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BCMath $r + * @return int + * @see self::isPrime() + */ + public static function scan1divide(BCMath $r) + { + $r_value = &$r->value; + $s = 0; + // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one[static::class]) check earlier + while ($r_value[strlen($r_value) - 1] % 2 == 0) { + $r_value = bcdiv($r_value, '2', 0); + ++$s; + } + + return $s; + } + + /** + * Performs exponentiation. + * + * @param BCMath $n + * @return BCMath + */ + public function pow(BCMath $n) + { + $temp = new self(); + $temp->value = bcpow($this->value, $n->value); + + return $this->normalize($temp); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function min(BCMath ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function max(BCMath ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BCMath $min + * @param BCMath $max + * @return bool + */ + public function between(BCMath $min, BCMath $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + + /** + * Set Bitmask + * + * @param int $bits + * @return Engine + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + $temp = parent::setBitmask($bits); + return $temp->add(static::$one[static::class]); + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value[strlen($this->value) - 1] % 2 == 1; + } + + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + return bccomp( + bcmod($this->value, bcpow('2', $x + 1, 0)), + bcpow('2', $x, 0), + 0 + ) >= 0; + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return strlen($this->value) && $this->value[0] == '-'; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BCMath + */ + public function negate() + { + $temp = clone $this; + + if (!strlen($temp->value)) { + return $temp; + } + + $temp->value = $temp->value[0] == '-' ? + substr($this->value, 1) : + '-' . $this->value; + + return $temp; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php new file mode 100644 index 000000000..fe21e0411 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php @@ -0,0 +1,110 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * Sliding Window Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Base extends BCMath +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @param string $class + * @return BCMath + */ + protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = '1'; + return $x->normalize($temp); + } + + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + + /** + * Modular reduction preparation + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function prepareReduce($x, $n, $class) + { + return static::reduce($x, $n); + } + + /** + * Modular multiply + * + * @param string $x + * @param string $y + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function multiplyReduce($x, $y, $n, $class) + { + return static::reduce(bcmul($x, $y), $n); + } + + /** + * Modular square + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function squareReduce($x, $n, $class) + { + return static::reduce(bcmul($x, $x), $n); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php new file mode 100644 index 000000000..b7ca8a2c6 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * Built-In BCMath Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class BuiltIn extends BCMath +{ + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n) + { + $temp = new BCMath(); + $temp->value = bcpowmod($x->value, $e->value, $n->value); + + return $x->normalize($temp); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php new file mode 100644 index 000000000..b2d9fa95c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; + +/** + * PHP Default Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends Barrett +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php new file mode 100644 index 000000000..aed949420 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL extends Progenitor +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php new file mode 100644 index 000000000..0fb7eaeba --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php @@ -0,0 +1,187 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Barrett extends Base +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $m_length = strlen($m); + + if (strlen($n) > 2 * $m_length) { + return bcmod($n, $m); + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m); + } + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); + $u = bcdiv($lhs, $m, 0); + $m1 = bcsub($lhs, bcmul($u, $m)); + + $cache[self::DATA][] = [ + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1' => $m1 // m.length + ]; + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + + $lsd = substr($n, -$cutoff); + $msd = substr($n, 0, -$cutoff); + + $temp = bcmul($msd, $m1); // m.length + (m.length >> 1) + $n = bcadd($lsd, $temp); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n, $m); + //} + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = substr($n, 0, -$m_length + 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = bcmul($temp, $u); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = substr($temp, 0, -($m_length >> 1) - 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = bcmul($temp, $m); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = bcsub($n, $temp); + + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $temp = '1' . str_repeat('0', $m_length + 1); + $result = bcadd($result, $temp); + } + + while (bccomp($result, $m) >= 0) { + $result = bcsub($result, $m); + } + + return $result; + } + + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param string $x + * @param string $n + * @return string + */ + private static function regularBarrett($x, $n) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $n_length = strlen($n); + + if (strlen($x) > 2 * $n_length) { + return bcmod($x, $n); + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = '1' . str_repeat('0', 2 * $n_length); + $cache[self::DATA][] = bcdiv($lhs, $n, 0); + } + + $temp = substr($x, 0, -$n_length + 1); + $temp = bcmul($temp, $cache[self::DATA][$key]); + $temp = substr($temp, 0, -$n_length - 1); + + $r1 = substr($x, -$n_length - 1); + $r2 = substr(bcmul($temp, $n), -$n_length - 1); + $result = bcsub($r1, $r2); + + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $q = '1' . str_repeat('0', $n_length + 1); + $result = bcadd($result, $q); + } + + while (bccomp($result, $n) >= 0) { + $result = bcsub($result, $n); + } + + return $result; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php new file mode 100644 index 000000000..e033ba575 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php @@ -0,0 +1,108 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use phpseclib3\Math\BigInteger\Engines\BCMath; +use phpseclib3\Math\BigInteger\Engines\BCMath\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class EvalBarrett extends Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + $inline = self::$custom_reduction; + return $inline($n); + } + + /** + * Generate Custom Reduction + * + * @param BCMath $m + * @param string $class + * @return callable|void + */ + protected static function generateCustomReduction(BCMath $m, $class) + { + $m_length = strlen($m); + + if ($m_length < 5) { + $code = 'return bcmod($x, $n);'; + eval('$func = function ($n) { ' . $code . '};'); + self::$custom_reduction = $func; + return; + } + + $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); + $u = bcdiv($lhs, $m, 0); + $m1 = bcsub($lhs, bcmul($u, $m)); + + $cutoff = $m_length + ($m_length >> 1); + + $m = "'$m'"; + $u = "'$u'"; + $m1 = "'$m1'"; + + $code = ' + $lsd = substr($n, -' . $cutoff . '); + $msd = substr($n, 0, -' . $cutoff . '); + + $temp = bcmul($msd, ' . $m1 . '); + $n = bcadd($lsd, $temp); + + $temp = substr($n, 0, ' . (-$m_length + 1) . '); + $temp = bcmul($temp, ' . $u . '); + $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); + $temp = bcmul($temp, ' . $m . '); + + $result = bcsub($n, $temp); + + if ($result[0] == \'-\') { + $temp = \'1' . str_repeat('0', $m_length + 1) . '\'; + $result = bcadd($result, $temp); + } + + while (bccomp($result, ' . $m . ') >= 0) { + $result = bcsub($result, ' . $m . '); + } + + return $result;'; + + eval('$func = function ($n) { ' . $code . '};'); + + self::$custom_reduction = $func; + + return $func; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php new file mode 100644 index 000000000..abdf3b475 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php @@ -0,0 +1,1285 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Random; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger; + +/** + * Base Engine. + * + * @author Jim Wigginton + */ +abstract class Engine implements \JsonSerializable +{ + /* final protected */ const PRIMES = [ + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, + ]; + + /** + * BigInteger(0) + * + * @var array, static> + */ + protected static $zero = []; + + /** + * BigInteger(1) + * + * @var array, static> + */ + protected static $one = []; + + /** + * BigInteger(2) + * + * @var array, static> + */ + protected static $two = []; + + /** + * Modular Exponentiation Engine + * + * @var array, class-string> + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var array, bool> + */ + protected static $isValidEngine; + + /** + * Holds the BigInteger's value + * + * @var \GMP|string|array|int + */ + protected $value; + + /** + * Holds the BigInteger's sign + * + * @var bool + */ + protected $is_negative; + + /** + * Precision + * + * @see static::setPrecision() + * @var int + */ + protected $precision = -1; + + /** + * Precision Bitmask + * + * @see static::setPrecision() + * @var static|false + */ + protected $bitmask = false; + + /** + * Recurring Modulo Function + * + * @var callable + */ + protected $reduce; + + /** + * Mode independent value used for serialization. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + */ + protected $hex; + + /** + * Default constructor + * + * @param int|numeric-string $x integer Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x = 0, $base = 10) + { + if (!array_key_exists(static::class, static::$zero)) { + static::$zero[static::class] = null; // Placeholder to prevent infinite loop. + static::$zero[static::class] = new static(0); + static::$one[static::class] = new static(1); + static::$two[static::class] = new static(2); + } + + // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 + // '0' is the only value like this per http://php.net/empty + if (empty($x) && (abs($base) != 256 || $x !== '0')) { + return; + } + + switch ($base) { + case -256: + case 256: + if ($base == -256 && (ord($x[0]) & 0x80)) { + $this->value = ~$x; + $this->is_negative = true; + } else { + $this->value = $x; + $this->is_negative = false; + } + + $this->initialize($base); + + if ($this->is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -16: + case 16: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#s', '$1', $x); + + $is_negative = false; + if ($base < 0 && hexdec($x[0]) >= 8) { + $this->is_negative = $is_negative = true; + $x = Strings::bin2hex(~Strings::hex2bin($x)); + } + + $this->value = $x; + $this->initialize($base); + + if ($is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -10: + case 10: + // (?value = preg_replace('#(?value) || $this->value == '-') { + $this->value = '0'; + } + $this->initialize($base); + break; + case -2: + case 2: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^([01]*).*#s', '$1', $x); + + $temp = new static(Strings::bits2bin($x), 128 * $base); // ie. either -16 or +16 + $this->value = $temp->value; + if ($temp->is_negative) { + $this->is_negative = true; + } + + break; + default: + // base not supported, so we'll let $this == 0 + } + } + + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param class-string $engine + */ + public static function setModExpEngine($engine) + { + $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; + if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { + throw new \InvalidArgumentException("$engine is not a valid engine"); + } + if (!$fqengine::isValidEngine()) { + throw new BadConfigurationException("$engine is not setup correctly on this system"); + } + static::$modexpEngine[static::class] = $fqengine; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * @return string + */ + protected function toBytesHelper() + { + $comparison = $this->compare(new static()); + if ($comparison == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = $comparison < 0 ? $this->add(new static(1)) : $this; + $bytes = $temp->toBytes(); + + if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 + $bytes = chr(0); + } + + if (ord($bytes[0]) & 0x80) { + $bytes = chr(0) . $bytes; + } + + return $comparison < 0 ? ~$bytes : $bytes; + } + + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = false) + { + return Strings::bin2hex($this->toBytes($twos_compliment)); + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + $hex = $this->toBytes($twos_compliment); + $bits = Strings::bin2bits($hex); + + $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $result; + } + + return $result; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} + * + * @param Engine $n + * @return static|false + */ + protected function modInverseHelper(Engine $n) + { + // $x mod -$n == $x mod $n. + $n = $n->abs(); + + if ($this->compare(static::$zero[static::class]) < 0) { + $temp = $this->abs(); + $temp = $temp->modInverse($n); + return $this->normalize($n->subtract($temp)); + } + + extract($this->extendedGCD($n)); + /** + * @var Engine $gcd + * @var Engine $x + */ + + if (!$gcd->equals(static::$one[static::class])) { + return false; + } + + $x = $x->compare(static::$zero[static::class]) < 0 ? $x->add($n) : $x; + + return $this->compare(static::$zero[static::class]) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); + } + + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * @return array + */ + public function __sleep() + { + $this->hex = $this->toHex(true); + $vars = ['hex']; + if ($this->precision > 0) { + $vars[] = 'precision'; + } + return $vars; + } + + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @return void + */ + public function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + $this->is_negative = $temp->is_negative; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * @return array{hex: string, precision?: int] + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $result = ['hex' => $this->toHex(true)]; + if ($this->precision > 0) { + $result['precision'] = $this->precision; + } + return $result; + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + * + * @return array + */ + public function __debugInfo() + { + $result = [ + 'value' => '0x' . $this->toHex(true), + 'engine' => basename(static::class) + ]; + return $this->precision > 0 ? $result + ['precision' => $this->precision] : $result; + } + + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + if ($bits < 1) { + $this->precision = -1; + $this->bitmask = false; + + return; + } + $this->precision = $bits; + $this->bitmask = static::setBitmask($bits); + + $temp = $this->normalize($this); + $this->value = $temp->value; + } + + /** + * Get Precision + * + * Returns the precision if it exists, -1 if it doesn't + * + * @return int + */ + public function getPrecision() + { + return $this->precision; + } + + /** + * Set Bitmask + * @return static + * @param int $bits + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + return new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); + } + + /** + * Logical Not + * + * @return Engine|string + */ + public function bitwise_not() + { + // calculuate "not" without regard to $this->precision + // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) + $temp = $this->toBytes(); + if ($temp == '') { + return $this->normalize(static::$zero[static::class]); + } + $pre_msb = decbin(ord($temp[0])); + $temp = ~$temp; + $msb = decbin(ord($temp[0])); + if (strlen($msb) == 8) { + $msb = substr($msb, strpos($msb, '0')); + } + $temp[0] = chr(bindec($msb)); + + // see if we need to add extra leading 1's + $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; + $new_bits = $this->precision - $current_bits; + if ($new_bits <= 0) { + return $this->normalize(new static($temp, 256)); + } + + // generate as many leading 1's as we need to. + $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); + + self::base256_lshift($leading_ones, $current_bits); + + $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($leading_ones | $temp, 256)); + } + + /** + * Logical Left Shift + * + * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. + * + * @param string $x + * @param int $shift + * @return void + */ + protected static function base256_lshift(&$x, $shift) + { + if ($shift == 0) { + return; + } + + $num_bytes = $shift >> 3; // eg. floor($shift/8) + $shift &= 7; // eg. $shift % 8 + + $carry = 0; + for ($i = strlen($x) - 1; $i >= 0; --$i) { + $temp = ord($x[$i]) << $shift | $carry; + $x[$i] = chr($temp); + $carry = $temp >> 8; + } + $carry = ($carry != 0) ? chr($carry) : ''; + $x = $carry . $x . str_repeat(chr(0), $num_bytes); + } + + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return Engine + */ + public function bitwise_leftRotate($shift) + { + $bits = $this->toBytes(); + + if ($this->precision > 0) { + $precision = $this->precision; + if (static::FAST_BITWISE) { + $mask = $this->bitmask->toBytes(); + } else { + $mask = $this->bitmask->subtract(new static(1)); + $mask = $mask->toBytes(); + } + } else { + $temp = ord($bits[0]); + for ($i = 0; $temp >> $i; ++$i) { + } + $precision = 8 * strlen($bits) - 8 + $i; + $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); + } + + if ($shift < 0) { + $shift += $precision; + } + $shift %= $precision; + + if (!$shift) { + return clone $this; + } + + $left = $this->bitwise_leftShift($shift); + $left = $left->bitwise_and(new static($mask, 256)); + $right = $this->bitwise_rightShift($precision - $shift); + $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); + return $this->normalize($result); + } + + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return Engine + */ + public function bitwise_rightRotate($shift) + { + return $this->bitwise_leftRotate(-$shift); + } + + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return array{min: static, max: static} + */ + public static function minMaxBits($bits) + { + $bytes = $bits >> 3; + $min = str_repeat(chr(0), $bytes); + $max = str_repeat(chr(0xFF), $bytes); + $msb = $bits & 7; + if ($msb) { + $min = chr(1 << ($msb - 1)) . $min; + $max = chr((1 << $msb) - 1) . $max; + } else { + $min[0] = chr(0x80); + } + return [ + 'min' => new static($min, 256), + 'max' => new static($max, 256) + ]; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return strlen($this->toBits()); + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return strlen($this->toBytes()); + } + + /** + * Performs some pre-processing for powMod + * + * @param Engine $e + * @param Engine $n + * @return static|false + */ + protected function powModOuter(Engine $e, Engine $n) + { + $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); + + if ($e->compare(new static()) < 0) { + $e = $e->abs(); + + $temp = $this->modInverse($n); + if ($temp === false) { + return false; + } + + return $this->normalize($temp->powModInner($e, $n)); + } + + if ($this->compare($n) > 0) { + list(, $temp) = $this->divide($n); + return $temp->powModInner($e, $n); + } + + return $this->powModInner($e, $n); + } + + /** + * Sliding Window k-ary Modular Exponentiation + * + * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, + * however, this function performs a modular reduction after every multiplication and squaring operation. + * As such, this function has the same preconditions that the reductions being used do. + * + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T + */ + protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) + { + static $window_ranges = [7, 25, 81, 241, 673, 1793]; // from BigInteger.java's oddModPow function + //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 + + $e_bits = $e->toBits(); + $e_length = strlen($e_bits); + + // calculate the appropriate window size. + // $window_size == 3 if $window_ranges is between 25 and 81, for example. + for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { + } + + $n_value = $n->value; + + if (method_exists(static::class, 'generateCustomReduction')) { + static::generateCustomReduction($n, $class); + } + + // precompute $this^0 through $this^$window_size + $powers = []; + $powers[1] = static::prepareReduce($x->value, $n_value, $class); + $powers[2] = static::squareReduce($powers[1], $n_value, $class); + + // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end + // in a 1. ie. it's supposed to be odd. + $temp = 1 << ($window_size - 1); + for ($i = 1; $i < $temp; ++$i) { + $i2 = $i << 1; + $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); + } + + $result = new $class(1); + $result = static::prepareReduce($result->value, $n_value, $class); + + for ($i = 0; $i < $e_length;) { + if (!$e_bits[$i]) { + $result = static::squareReduce($result, $n_value, $class); + ++$i; + } else { + for ($j = $window_size - 1; $j > 0; --$j) { + if (!empty($e_bits[$i + $j])) { + break; + } + } + + // eg. the length of substr($e_bits, $i, $j + 1) + for ($k = 0; $k <= $j; ++$k) { + $result = static::squareReduce($result, $n_value, $class); + } + + $result = static::multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $class); + + $i += $j + 1; + } + } + + $temp = new $class(); + $temp->value = static::reduce($result, $n_value, $class); + + return $temp; + } + + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return Engine + */ + public static function random($size) + { + extract(static::minMaxBits($size)); + /** + * @var BigInteger $min + * @var BigInteger $max + */ + return static::randomRange($min, $max); + } + + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return Engine + */ + public static function randomPrime($size) + { + extract(static::minMaxBits($size)); + /** + * @var static $min + * @var static $max + */ + return static::randomRangePrime($min, $max); + } + + /** + * Performs some pre-processing for randomRangePrime + * + * @param Engine $min + * @param Engine $max + * @return static|false + */ + protected static function randomRangePrimeOuter(Engine $min, Engine $max) + { + $compare = $max->compare($min); + + if (!$compare) { + return $min->isPrime() ? $min : false; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + $x = static::randomRange($min, $max); + + return static::randomRangePrimeInner($x, $min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param Engine $min + * @param Engine $max + * @return Engine + */ + protected static function randomRangeHelper(Engine $min, Engine $max) + { + $compare = $max->compare($min); + + if (!$compare) { + return $min; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + if (!isset(static::$one[static::class])) { + static::$one[static::class] = new static(1); + } + + $max = $max->subtract($min->subtract(static::$one[static::class])); + + $size = strlen(ltrim($max->toBytes(), chr(0))); + + /* + doing $random % $max doesn't work because some numbers will be more likely to occur than others. + eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 + would produce 5 whereas the only value of random that could produce 139 would be 139. ie. + not all numbers would be equally likely. some would be more likely than others. + + creating a whole new random number until you find one that is within the range doesn't work + because, for sufficiently small ranges, the likelihood that you'd get a number within that range + would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability + would be pretty high that $random would be greater than $max. + + phpseclib works around this using the technique described here: + + http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string + */ + $random_max = new static(chr(1) . str_repeat("\0", $size), 256); + $random = new static(Random::string($size), 256); + + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + + while ($random->compare($max_multiple) >= 0) { + $random = $random->subtract($max_multiple); + $random_max = $random_max->subtract($max_multiple); + $random = $random->bitwise_leftShift(8); + $random = $random->add(new static(Random::string(1), 256)); + $random_max = $random_max->bitwise_leftShift(8); + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + } + list(, $random) = $random->divide($max); + + return $random->add($min); + } + + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return static|false + */ + protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) + { + if (!isset(static::$two[static::class])) { + static::$two[static::class] = new static('2'); + } + + $x->make_odd(); + if ($x->compare($max) > 0) { + // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range + if ($min->equals($max)) { + return false; + } + $x = clone $min; + $x->make_odd(); + } + + $initial_x = clone $x; + + while (true) { + if ($x->isPrime()) { + return $x; + } + + $x = $x->add(static::$two[static::class]); + + if ($x->compare($max) > 0) { + $x = clone $min; + if ($x->equals(static::$two[static::class])) { + return $x; + } + $x->make_odd(); + } + + if ($x->equals($initial_x)) { + return false; + } + } + } + + /** + * Sets the $t parameter for primality testing + * + * @return int + */ + protected function setupIsPrime() + { + $length = $this->getLengthInBytes(); + + // see HAC 4.49 "Note (controlling the error probability)" + // @codingStandardsIgnoreStart + if ($length >= 163) { $t = 2; } // floor(1300 / 8) + else if ($length >= 106) { $t = 3; } // floor( 850 / 8) + else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) + else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) + else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) + else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) + else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) + else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) + else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) + else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) + else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) + else { $t = 27; } + // @codingStandardsIgnoreEnd + + return $t; + } + + /** + * Tests Primality + * + * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + if (!$this->testSmallPrimes()) { + return false; + } + + $n = clone $this; + $n_1 = $n->subtract(static::$one[static::class]); + $n_2 = $n->subtract(static::$two[static::class]); + + $r = clone $n_1; + $s = static::scan1divide($r); + + for ($i = 0; $i < $t; ++$i) { + $a = static::randomRange(static::$two[static::class], $n_2); + $y = $a->modPow($r, $n); + + if (!$y->equals(static::$one[static::class]) && !$y->equals($n_1)) { + for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { + $y = $y->modPow(static::$two[static::class], $n); + if ($y->equals(static::$one[static::class])) { + return false; + } + } + + if (!$y->equals($n_1)) { + return false; + } + } + } + + return true; + } + + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = false) + { + if (!$t) { + $t = $this->setupIsPrime(); + } + return $this->testPrimality($t); + } + + /** + * Performs a few preliminary checks on root + * + * @param int $n + * @return Engine + */ + protected function rootHelper($n) + { + if ($n < 1) { + return clone static::$zero[static::class]; + } // we want positive exponents + if ($this->compare(static::$one[static::class]) < 0) { + return clone static::$zero[static::class]; + } // we want positive numbers + if ($this->compare(static::$two[static::class]) < 0) { + return clone static::$one[static::class]; + } // n-th root of 1 or 2 is 1 + + return $this->rootInner($n); + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} + * + * @param int $n + * @return Engine + */ + protected function rootInner($n) + { + $n = new static($n); + + // g is our guess number + $g = static::$two[static::class]; + // while (g^n < num) g=g*2 + while ($g->pow($n)->compare($this) < 0) { + $g = $g->multiply(static::$two[static::class]); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + // == 0 bccomp(bcpow($g, $n), $n->value)==0 + if ($g->pow($n)->equals($this) > 0) { + $root = $g; + return $this->normalize($root); + } + + // if we're here num wasn't a power of 2 :( + $og = $g; // og means original guess and here is our upper bound + $g = $g->divide(static::$two[static::class])[0]; // g is set to be our lower bound + $step = $og->subtract($g)->divide(static::$two[static::class])[0]; // step is the half of upper bound - lower bound + $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval + + // while step>1 + + while ($step->compare(static::$one[static::class]) == 1) { + $guess = $g->pow($n); + $step = $step->divide(static::$two[static::class])[0]; + $comp = $guess->compare($this); // compare our guess with real number + switch ($comp) { + case -1: // if guess is lower we add the new step + $g = $g->add($step); + break; + case 1: // if guess is higher we sub the new step + $g = $g->subtract($step); + break; + case 0: // if guess is exactly the num we're done, we return the value + $root = $g; + break 2; + } + } + + if ($comp == 1) { + $g = $g->subtract($step); + } + + // whatever happened, g is the closest guess we can make so return it + $root = $g; + + return $this->normalize($root); + } + + /** + * Calculates the nth root of a biginteger. + * + * @param int $n + * @return Engine + */ + public function root($n = 2) + { + return $this->rootHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function minHelper(array $nums) + { + if (count($nums) == 1) { + return $nums[0]; + } + $min = $nums[0]; + for ($i = 1; $i < count($nums); $i++) { + $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; + } + return $min; + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function maxHelper(array $nums) + { + if (count($nums) == 1) { + return $nums[0]; + } + $max = $nums[0]; + for ($i = 1; $i < count($nums); $i++) { + $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; + } + return $max; + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $class = static::class; + + $fqengine = !method_exists(static::$modexpEngine[static::class], 'reduce') ? + '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : + static::$modexpEngine[static::class]; + if (method_exists($fqengine, 'generateCustomReduction')) { + $func = $fqengine::generateCustomReduction($this, static::class); + return eval('return function(' . static::class . ' $x) use ($func, $class) { + $r = new $class(); + $r->value = $func($x->value); + return $r; + };'); + } + $n = $this->value; + return eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { + $r = new $class(); + $r->value = $fqengine::reduce($x->value, $n, $class); + return $r; + };'); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * @param Engine $n + * @return array{gcd: Engine, x: Engine, y: Engine} + */ + protected function extendedGCDHelper(Engine $n) + { + $u = clone $this; + $v = clone $n; + + $one = new static(1); + $zero = new static(); + + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + } + + return [ + 'gcd' => $u, + 'x' => $a, + 'y' => $b + ]; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return Engine[] + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + + $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); + + $num = clone $this; + + $vals = []; + while (!$num->equals(static::$zero[static::class])) { + $vals[] = $num->bitwise_and($mask); + $num = $num->bitwise_rightShift($split); + } + + return array_reverse($vals); + } + + /** + * Logical And + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseAndHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($left & $right, -256)); + } + + /** + * Logical Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseOrHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($left | $right, -256)); + } + + /** + * Logical Exclusive Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseXorHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + return $this->normalize(new static($left ^ $right, -256)); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php new file mode 100644 index 000000000..f61636297 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php @@ -0,0 +1,694 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Exception\BadConfigurationException; + +/** + * GMP Engine. + * + * @author Jim Wigginton + */ +class GMP extends Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = true; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'GMP'; + + /** + * Test for engine validity + * + * @return bool + * @see parent::__construct() + */ + public static function isValidEngine() + { + return extension_loaded('gmp'); + } + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new BadConfigurationException('GMP is not setup correctly on this system'); + } + + if ($x instanceof \GMP) { + $this->value = $x; + return; + } + + $this->value = gmp_init(0); + + parent::__construct($x, $base); + } + + /** + * Initialize a GMP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 256: + $this->value = gmp_import($this->value); + if ($this->is_negative) { + $this->value = -$this->value; + } + break; + case 16: + $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; + $this->value = gmp_init($temp); + break; + case 10: + $this->value = gmp_init(isset($this->value) ? $this->value : '0'); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return (string)$this->value; + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + $hex = $this->toHex($twos_compliment); + + $bits = gmp_strval(gmp_init($hex, 16), 2); + + if ($this->precision > 0) { + $bits = substr($bits, -$this->precision); + } + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $bits; + } + + return $bits; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + if (gmp_cmp($this->value, gmp_init(0)) == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = gmp_export($this->value); + + return $this->precision > 0 ? + substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($temp, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function add(GMP $y) + { + $temp = new self(); + $temp->value = $this->value + $y->value; + + return $this->normalize($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function subtract(GMP $y) + { + $temp = new self(); + $temp->value = $this->value - $y->value; + + return $this->normalize($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param GMP $x + * @return GMP + */ + public function multiply(GMP $x) + { + $temp = new self(); + $temp->value = $this->value * $x->value; + + return $this->normalize($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param GMP $y + * @return array{GMP, GMP} + */ + public function divide(GMP $y) + { + $quotient = new self(); + $remainder = new self(); + + list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); + + if (gmp_sign($remainder->value) < 0) { + $remainder->value = $remainder->value + gmp_abs($y->value); + } + + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param GMP $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(GMP $y) + { + $r = gmp_cmp($this->value, $y->value); + if ($r < -1) { + $r = -1; + } + if ($r > 1) { + $r = 1; + } + return $r; + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param GMP $x + * @return bool + */ + public function equals(GMP $x) + { + return $this->value == $x->value; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param GMP $n + * @return false|GMP + */ + public function modInverse(GMP $n) + { + $temp = new self(); + $temp->value = gmp_invert($this->value, $n->value); + + return $temp->value === false ? false : $this->normalize($temp); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param GMP $n + * @return GMP[] + */ + public function extendedGCD(GMP $n) + { + extract(gmp_gcdext($this->value, $n->value)); + + return [ + 'gcd' => $this->normalize(new self($g)), + 'x' => $this->normalize(new self($s)), + 'y' => $this->normalize(new self($t)) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param GMP $n + * @return GMP + */ + public function gcd(GMP $n) + { + $r = gmp_gcd($this->value, $n->value); + return $this->normalize(new self($r)); + } + + /** + * Absolute value. + * + * @return GMP + */ + public function abs() + { + $temp = new self(); + $temp->value = gmp_abs($this->value); + + return $temp; + } + + /** + * Logical And + * + * @param GMP $x + * @return GMP + */ + public function bitwise_and(GMP $x) + { + $temp = new self(); + $temp->value = $this->value & $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_or(GMP $x) + { + $temp = new self(); + $temp->value = $this->value | $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Exclusive Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_xor(GMP $x) + { + $temp = new self(); + $temp->value = $this->value ^ $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return GMP + */ + public function bitwise_rightShift($shift) + { + // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) + // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') + + $temp = new self(); + $temp->value = $this->value >> $shift; + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return GMP + */ + public function bitwise_leftShift($shift) + { + $temp = new self(); + $temp->value = $this->value << $shift; + + return $this->normalize($temp); + } + + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function modPow(GMP $e, GMP $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function powMod(GMP $e, GMP $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected function powModInner(GMP $e, GMP $n) + { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n); + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param GMP $result + * @return GMP + */ + protected function normalize(GMP $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + if ($result->bitmask !== false) { + $flip = $result->value < 0; + if ($flip) { + $result->value = -$result->value; + } + $result->value = $result->value & $result->bitmask->value; + if ($flip) { + $result->value = -$result->value; + } + } + + return $result; + } + + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return GMP + */ + protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) + { + $p = gmp_nextprime($x->value); + + if ($p <= $max->value) { + return new self($p); + } + + if ($min->value != $x->value) { + $x = new self($x->value - 1); + } + + return self::randomRangePrime($min, $x); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param GMP $min + * @param GMP $max + * @return false|GMP + */ + public static function randomRangePrime(GMP $min, GMP $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param GMP $min + * @param GMP $max + * @return GMP + */ + public static function randomRange(GMP $min, GMP $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + gmp_setbit($this->value, 0); + } + + /** + * Tests Primality + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + return gmp_prob_prime($this->value, $t) != 0; + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n + * @return GMP + */ + protected function rootInner($n) + { + $root = new self(); + $root->value = gmp_root($this->value, $n); + return $this->normalize($root); + } + + /** + * Performs exponentiation. + * + * @param GMP $n + * @return GMP + */ + public function pow(GMP $n) + { + $temp = new self(); + $temp->value = $this->value ** $n->value; + + return $this->normalize($temp); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function min(GMP ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function max(GMP ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param GMP $min + * @param GMP $max + * @return bool + */ + public function between(GMP $min, GMP $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $temp = $this->value; + return function (GMP $x) use ($temp) { + return new GMP($x->value % $temp); + }; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param GMP $r + * @return int + */ + public static function scan1divide(GMP $r) + { + $s = gmp_scan1($r->value, 0); + $r->value >>= $s; + return $s; + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return gmp_testbit($this->value, 0); + } + + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + return gmp_testbit($this->value, $x); + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return gmp_sign($this->value) == -1; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return GMP + */ + public function negate() + { + $temp = clone $this; + $temp->value = -$this->value; + + return $temp; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php new file mode 100644 index 000000000..bc219fbee --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\GMP; + +use phpseclib3\Math\BigInteger\Engines\GMP; + +/** + * GMP Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends GMP +{ + /** + * Performs modular exponentiation. + * + * @param GMP $x + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected static function powModHelper(GMP $x, GMP $e, GMP $n) + { + $temp = new GMP(); + $temp->value = gmp_powm($x->value, $e->value, $n->value); + + return $x->normalize($temp); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php new file mode 100644 index 000000000..e33a9f196 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php @@ -0,0 +1,68 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return extension_loaded('openssl') && static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @return Engine + */ + public static function powModHelper(Engine $x, Engine $e, Engine $n) + { + if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { + throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); + } + + $key = PKCS8::savePublicKey( + new BigInteger($n), + new BigInteger($e) + ); + + $plaintext = str_pad($x->toBytes(), $n->getLengthInBytes(), "\0", STR_PAD_LEFT); + + // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it + // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" + // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what + // about odd numbers divisible by 3, by 5, etc? + if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) { + throw new \UnexpectedValueException(openssl_error_string()); + } + + $class = get_class($x); + return new $class($result, 256); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php new file mode 100644 index 000000000..4c30da564 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php @@ -0,0 +1,1343 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; + +/** + * Pure-PHP Engine. + * + * @author Jim Wigginton + */ +abstract class PHP extends Engine +{ + /**#@+ + * Array constants + * + * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and + * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. + * + */ + /** + * $result[self::VALUE] contains the value. + */ + const VALUE = 0; + /** + * $result[self::SIGN] contains the sign. + */ + const SIGN = 1; + /**#@-*/ + + /** + * Karatsuba Cutoff + * + * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? + * + */ + const KARATSUBA_CUTOFF = 25; + + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = true; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'PHP'; + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @return PHP + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = static::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); + } + + $this->value = []; + parent::__construct($x, $base); + } + + /** + * Initialize a PHP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 16: + $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; + $temp = new static(Strings::hex2bin($x), 256); + $this->value = $temp->value; + break; + case 10: + $temp = new static(); + + $multiplier = new static(); + $multiplier->value = [static::MAX10]; + + $x = $this->value; + + if ($x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = str_pad( + $x, + strlen($x) + ((static::MAX10LEN - 1) * strlen($x)) % static::MAX10LEN, + 0, + STR_PAD_LEFT + ); + while (strlen($x)) { + $temp = $temp->multiply($multiplier); + $temp = $temp->add(new static($this->int2bytes(substr($x, 0, static::MAX10LEN)), 256)); + $x = substr($x, static::MAX10LEN); + } + + $this->value = $temp->value; + } + } + + /** + * Pads strings so that unpack may be used on them + * + * @param string $str + * @return string + */ + protected function pad($str) + { + $length = strlen($str); + + $pad = 4 - (strlen($str) % 4); + + return str_pad($str, $length + $pad, "\0", STR_PAD_LEFT); + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if (!count($this->value)) { + return '0'; + } + + $temp = clone $this; + $temp->bitmask = false; + $temp->is_negative = false; + + $divisor = new static(); + $divisor->value = [static::MAX10]; + $result = ''; + while (count($temp->value)) { + list($temp, $mod) = $temp->divide($divisor); + $result = str_pad( + isset($mod->value[0]) ? $mod->value[0] : '', + static::MAX10LEN, + '0', + STR_PAD_LEFT + ) . $result; + } + $result = ltrim($result, '0'); + if (empty($result)) { + $result = '0'; + } + + if ($this->is_negative) { + $result = '-' . $result; + } + + return $result; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + if (!count($this->value)) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $result = $this->bitwise_small_split(8); + $result = implode('', array_map('chr', $result)); + + return $this->precision > 0 ? + str_pad( + substr($result, -(($this->precision + 7) >> 3)), + ($this->precision + 7) >> 3, + chr(0), + STR_PAD_LEFT + ) : + $result; + } + + /** + * Performs addition. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return [ + self::VALUE => $y_value, + self::SIGN => $y_negative + ]; + } elseif ($y_size == 0) { + return [ + self::VALUE => $x_value, + self::SIGN => $x_negative + ]; + } + + // subtract, if appropriate + if ($x_negative != $y_negative) { + if ($x_value == $y_value) { + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + $temp = self::subtractHelper($x_value, false, $y_value, false); + $temp[self::SIGN] = self::compareHelper($x_value, false, $y_value, false) > 0 ? + $x_negative : $y_negative; + + return $temp; + } + + if ($x_size < $y_size) { + $size = $x_size; + $value = $y_value; + } else { + $size = $y_size; + $value = $x_value; + } + + $value[count($value)] = 0; // just in case the carry adds an extra digit + + $carry = 0; + for ($i = 0, $j = 1; $j < $size; $i += 2, $j += 2) { + //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; + $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; + + $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $value[$i] = (int)($sum - static::BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) + $value[$j] = $temp; + } + + if ($j == $size) { // ie. if $y_size is odd + $sum = $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::BASE_FULL; + $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; + ++$i; // ie. let $i = $j since we've just done $value[$i] + } + + if ($carry) { + for (; $value[$i] == static::MAX_DIGIT; ++$i) { + $value[$i] = 0; + } + ++$value[$i]; + } + + return [ + self::VALUE => self::trim($value), + self::SIGN => $x_negative + ]; + } + + /** + * Performs subtraction. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + public static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return [ + self::VALUE => $y_value, + self::SIGN => !$y_negative + ]; + } elseif ($y_size == 0) { + return [ + self::VALUE => $x_value, + self::SIGN => $x_negative + ]; + } + + // add, if appropriate (ie. -$x - +$y or +$x - -$y) + if ($x_negative != $y_negative) { + $temp = self::addHelper($x_value, false, $y_value, false); + $temp[self::SIGN] = $x_negative; + + return $temp; + } + + $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); + + if (!$diff) { + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + // switch $x and $y around, if appropriate. + if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_negative = !$x_negative; + + $x_size = count($x_value); + $y_size = count($y_value); + } + + // at this point, $x_value should be at least as big as - if not bigger than - $y_value + + $carry = 0; + for ($i = 0, $j = 1; $j < $y_size; $i += 2, $j += 2) { + $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; + + $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; + + $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $x_value[$i] = (int)($sum - static::BASE_FULL * $temp); + $x_value[$j] = $temp; + } + + if ($j == $y_size) { // ie. if $y_size is odd + $sum = $x_value[$i] - $y_value[$i] - $carry; + $carry = $sum < 0; + $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; + ++$i; + } + + if ($carry) { + for (; !$x_value[$i]; ++$i) { + $x_value[$i] = static::MAX_DIGIT; + } + --$x_value[$i]; + } + + return [ + self::VALUE => self::trim($x_value), + self::SIGN => $x_negative + ]; + } + + /** + * Performs multiplication. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + //if ( $x_value == $y_value ) { + // return [ + // self::VALUE => self::square($x_value), + // self::SIGN => $x_sign != $y_value + // ]; + //} + + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + return [ + self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? + self::trim(self::regularMultiply($x_value, $y_value)) : + self::trim(self::karatsuba($x_value, $y_value)), + self::SIGN => $x_negative != $y_negative + ]; + } + + /** + * Performs Karatsuba multiplication on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + private static function karatsuba(array $x_value, array $y_value) + { + $m = min(count($x_value) >> 1, count($y_value) >> 1); + + if ($m < self::KARATSUBA_CUTOFF) { + return self::regularMultiply($x_value, $y_value); + } + + $x1 = array_slice($x_value, $m); + $x0 = array_slice($x_value, 0, $m); + $y1 = array_slice($y_value, $m); + $y0 = array_slice($y_value, 0, $m); + + $z2 = self::karatsuba($x1, $y1); + $z0 = self::karatsuba($x0, $y0); + + $z1 = self::addHelper($x1, false, $x0, false); + $temp = self::addHelper($y1, false, $y0, false); + $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); + $temp = self::addHelper($z2, false, $z0, false); + $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xy = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, false); + + return $xy[self::VALUE]; + } + + /** + * Performs long multiplication on two BigIntegers + * + * Modeled after 'multiply' in MutableBigInteger.java. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + protected static function regularMultiply(array $x_value, array $y_value) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return []; + } + + $product_value = self::array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int)($temp - static::BASE_FULL * $carry); + } + + $product_value[$j] = $carry; + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int)($temp - static::BASE_FULL * $carry); + } + + $product_value[$k] = $carry; + } + + return $product_value; + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @return array{static, static} + * @internal This function is based off of + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. + */ + protected function divideHelper(PHP $y) + { + if (count($y->value) == 1) { + list($q, $r) = $this->divide_digit($this->value, $y->value[0]); + $quotient = new static(); + $remainder = new static(); + $quotient->value = $q; + $remainder->value = [$r]; + $quotient->is_negative = $this->is_negative != $y->is_negative; + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + $x = clone $this; + $y = clone $y; + + $x_sign = $x->is_negative; + $y_sign = $y->is_negative; + + $x->is_negative = $y->is_negative = false; + + $diff = $x->compare($y); + + if (!$diff) { + $temp = new static(); + $temp->value = [1]; + $temp->is_negative = $x_sign != $y_sign; + return [$this->normalize($temp), $this->normalize(static::$zero[static::class])]; + } + + if ($diff < 0) { + // if $x is negative, "add" $y. + if ($x_sign) { + $x = $y->subtract($x); + } + return [$this->normalize(static::$zero[static::class]), $this->normalize($x)]; + } + + // normalize $x and $y as described in HAC 14.23 / 14.24 + $msb = $y->value[count($y->value) - 1]; + for ($shift = 0; !($msb & static::MSB); ++$shift) { + $msb <<= 1; + } + $x->lshift($shift); + $y->lshift($shift); + $y_value = &$y->value; + + $x_max = count($x->value) - 1; + $y_max = count($y->value) - 1; + + $quotient = new static(); + $quotient_value = &$quotient->value; + $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); + + static $temp, $lhs, $rhs; + if (!isset($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + if (static::class != get_class($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + $temp_value = &$temp->value; + $rhs_value = &$rhs->value; + + // $temp = $y << ($x_max - $y_max-1) in base 2**26 + $temp_value = array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); + + while ($x->compare($temp) >= 0) { + // calculate the "common residue" + ++$quotient_value[$x_max - $y_max]; + $x = $x->subtract($temp); + $x_max = count($x->value) - 1; + } + + for ($i = $x_max; $i >= $y_max + 1; --$i) { + $x_value = &$x->value; + $x_window = [ + isset($x_value[$i]) ? $x_value[$i] : 0, + isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, + isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 + ]; + $y_window = [ + $y_value[$y_max], + ($y_max > 0) ? $y_value[$y_max - 1] : 0 + ]; + + $q_index = $i - $y_max - 1; + if ($x_window[0] == $y_window[0]) { + $quotient_value[$q_index] = static::MAX_DIGIT; + } else { + $quotient_value[$q_index] = self::safe_divide( + $x_window[0] * static::BASE_FULL + $x_window[1], + $y_window[0] + ); + } + + $temp_value = [$y_window[1], $y_window[0]]; + + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + + $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; + + while ($lhs->compare($rhs) > 0) { + --$quotient_value[$q_index]; + + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + } + + $adjust = self::array_repeat(0, $q_index); + $temp_value = [$quotient_value[$q_index]]; + $temp = $temp->multiply($y); + $temp_value = &$temp->value; + if (count($temp_value)) { + $temp_value = array_merge($adjust, $temp_value); + } + + $x = $x->subtract($temp); + + if ($x->compare(static::$zero[static::class]) < 0) { + $temp_value = array_merge($adjust, $y_value); + $x = $x->add($temp); + + --$quotient_value[$q_index]; + } + + $x_max = count($x_value) - 1; + } + + // unnormalize the remainder + $x->rshift($shift); + + $quotient->is_negative = $x_sign != $y_sign; + + // calculate the "common residue", if appropriate + if ($x_sign) { + $y->rshift($shift); + $x = $y->subtract($x); + } + + return [$this->normalize($quotient), $this->normalize($x)]; + } + + /** + * Divides a BigInteger by a regular integer + * + * abc / x = a00 / x + b0 / x + c / x + * + * @param array $dividend + * @param int $divisor + * @return array + */ + private static function divide_digit(array $dividend, $divisor) + { + $carry = 0; + $result = []; + + for ($i = count($dividend) - 1; $i >= 0; --$i) { + $temp = static::BASE_FULL * $carry + $dividend[$i]; + $result[$i] = self::safe_divide($temp, $divisor); + $carry = (int)($temp - $divisor * $result[$i]); + } + + return [$result, $carry]; + } + + /** + * Single digit division + * + * Even if int64 is being used the division operator will return a float64 value + * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't + * have the precision of int64 this is a problem so, when int64 is being used, + * we'll guarantee that the dividend is divisible by first subtracting the remainder. + * + * @param int $x + * @param int $y + * @return int + */ + private static function safe_divide($x, $y) + { + if (static::BASE === 26) { + return (int)($x / $y); + } + + // static::BASE === 31 + /** @var int */ + return ($x - ($x % $y)) / $y; + } + + /** + * Convert an array / boolean to a PHP BigInteger object + * + * @param array $arr + * @return static + */ + protected function convertToObj(array $arr) + { + $result = new static(); + $result->value = $arr[self::VALUE]; + $result->is_negative = $arr[self::SIGN]; + + return $this->normalize($result); + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param PHP $result + * @return static + */ + protected function normalize(PHP $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + $value = &$result->value; + + if (!count($value)) { + $result->is_negative = false; + return $result; + } + + $value = static::trim($value); + + if (!empty($result->bitmask->value)) { + $length = min(count($value), count($result->bitmask->value)); + $value = array_slice($value, 0, $length); + + for ($i = 0; $i < $length; ++$i) { + $value[$i] = $value[$i] & $result->bitmask->value[$i]; + } + + $value = static::trim($value); + } + + return $result; + } + + /** + * Compares two numbers. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return int + * @see static::compare() + */ + protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + if ($x_negative != $y_negative) { + return (!$x_negative && $y_negative) ? 1 : -1; + } + + $result = $x_negative ? -1 : 1; + + if (count($x_value) != count($y_value)) { + return (count($x_value) > count($y_value)) ? $result : -$result; + } + $size = max(count($x_value), count($y_value)); + + $x_value = array_pad($x_value, $size, 0); + $y_value = array_pad($y_value, $size, 0); + + for ($i = count($x_value) - 1; $i >= 0; --$i) { + if ($x_value[$i] != $y_value[$i]) { + return ($x_value[$i] > $y_value[$i]) ? $result : -$result; + } + } + + return 0; + } + + /** + * Absolute value. + * + * @return PHP + */ + public function abs() + { + $temp = new static(); + $temp->value = $this->value; + + return $temp; + } + + /** + * Trim + * + * Removes leading zeros + * + * @param list $value + * @return list + */ + protected static function trim(array $value) + { + for ($i = count($value) - 1; $i >= 0; --$i) { + if ($value[$i]) { + break; + } + unset($value[$i]); + } + + return $value; + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return PHP + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + + // could just replace lshift with this, but then all lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->rshift($shift); + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return PHP + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->lshift($shift); + + return $this->normalize($temp); + } + + /** + * Converts 32-bit integers to bytes. + * + * @param int $x + * @return string + */ + private static function int2bytes($x) + { + return ltrim(pack('N', $x), chr(0)); + } + + /** + * Array Repeat + * + * @param int $input + * @param int $multiplier + * @return array + */ + protected static function array_repeat($input, $multiplier) + { + return $multiplier ? array_fill(0, $multiplier, $input) : []; + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function lshift($shift) + { + if ($shift == 0) { + return; + } + + $num_digits = (int)($shift / static::BASE); + $shift %= static::BASE; + $shift = 1 << $shift; + + $carry = 0; + + for ($i = 0; $i < count($this->value); ++$i) { + $temp = $this->value[$i] * $shift + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $this->value[$i] = (int)($temp - $carry * static::BASE_FULL); + } + + if ($carry) { + $this->value[count($this->value)] = $carry; + } + + while ($num_digits--) { + array_unshift($this->value, 0); + } + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function rshift($shift) + { + if ($shift == 0) { + return; + } + + $num_digits = (int)($shift / static::BASE); + $shift %= static::BASE; + $carry_shift = static::BASE - $shift; + $carry_mask = (1 << $shift) - 1; + + if ($num_digits) { + $this->value = array_slice($this->value, $num_digits); + } + + $carry = 0; + + for ($i = count($this->value) - 1; $i >= 0; --$i) { + $temp = $this->value[$i] >> $shift | $carry; + $carry = ($this->value[$i] & $carry_mask) << $carry_shift; + $this->value[$i] = $temp; + } + + $this->value = static::trim($this->value); + } + + /** + * Performs modular exponentiation. + * + * @param PHP $e + * @param PHP $n + * @return PHP + */ + protected function powModInner(PHP $e, PHP $n) + { + try { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + + /** + * Performs squaring + * + * @param list $x + * @return list + */ + protected static function square(array $x) + { + return count($x) < 2 * self::KARATSUBA_CUTOFF ? + self::trim(self::baseSquare($x)) : + self::trim(self::karatsubaSquare($x)); + } + + /** + * Performs traditional squaring on two BigIntegers + * + * Squaring can be done faster than multiplying a number by itself can be. See + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. + * + * @param array $value + * @return array + */ + protected static function baseSquare(array $value) + { + if (empty($value)) { + return []; + } + $square_value = self::array_repeat(0, 2 * count($value)); + + for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { + $i2 = $i << 1; + + $temp = $square_value[$i2] + $value[$i] * $value[$i]; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$i2] = (int)($temp - static::BASE_FULL * $carry); + + // note how we start from $i+1 instead of 0 as we do in multiplication. + for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { + $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$k] = (int)($temp - static::BASE_FULL * $carry); + } + + // the following line can yield values larger 2**15. at this point, PHP should switch + // over to floats. + $square_value[$i + $max_index + 1] = $carry; + } + + return $square_value; + } + + /** + * Performs Karatsuba "squaring" on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. + * + * @param array $value + * @return array + */ + protected static function karatsubaSquare(array $value) + { + $m = count($value) >> 1; + + if ($m < self::KARATSUBA_CUTOFF) { + return self::baseSquare($value); + } + + $x1 = array_slice($value, $m); + $x0 = array_slice($value, 0, $m); + + $z2 = self::karatsubaSquare($x1); + $z0 = self::karatsubaSquare($x0); + + $z1 = self::addHelper($x1, false, $x0, false); + $z1 = self::karatsubaSquare($z1[self::VALUE]); + $temp = self::addHelper($z2, false, $z0, false); + $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xx = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, false); + + return $xx[self::VALUE]; + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + $this->value[0] |= 1; + } + + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value == [1]) { + return false; + } + if ($this->value == [2]) { + return true; + } + if (~$this->value[0] & 1) { + return false; + } + + $value = $this->value; + foreach (static::PRIMES as $prime) { + list(, $r) = self::divide_digit($value, $prime); + if (!$r) { + return count($value) == 1 && $value[0] == $prime; + } + } + + return true; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param PHP $r + * @return int + * @see self::isPrime() + */ + public static function scan1divide(PHP $r) + { + $r_value = &$r->value; + for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { + $temp = ~$r_value[$i] & static::MAX_DIGIT; + for ($j = 1; ($temp >> $j) & 1; ++$j) { + } + if ($j <= static::BASE) { + break; + } + } + $s = static::BASE * $i + $j; + $r->rshift($s); + return $s; + } + + /** + * Performs exponentiation. + * + * @param PHP $n + * @return PHP + */ + protected function powHelper(PHP $n) + { + if ($n->compare(static::$zero[static::class]) == 0) { + return new static(1); + } // n^0 = 1 + + $temp = clone $this; + while (!$n->equals(static::$one[static::class])) { + $temp = $temp->multiply($this); + $n = $n->subtract(static::$one[static::class]); + } + + return $temp; + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return (bool)($this->value[0] & 1); + } + + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + $digit = (int) floor($x / static::BASE); + $bit = $x % static::BASE; + + if (!isset($this->value[$digit])) { + return false; + } + + return (bool)($this->value[$digit] & (1 << $bit)); + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return $this->is_negative; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return static + */ + public function negate() + { + $temp = clone $this; + $temp->is_negative = !$temp->is_negative; + + return $temp; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return list + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + + $width = (int)($split / static::BASE); + if (!$width) { + $arr = $this->bitwise_small_split($split); + return array_map(function ($digit) { + $temp = new static(); + $temp->value = $digit != 0 ? [$digit] : []; + return $temp; + }, $arr); + } + + $vals = []; + $val = $this->value; + + $i = $overflow = 0; + $len = count($val); + while ($i < $len) { + $digit = []; + if (!$overflow) { + $digit = array_slice($val, $i, $width); + $i += $width; + $overflow = $split % static::BASE; + if ($overflow) { + $mask = (1 << $overflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $mask; + } + } else { + $remaining = static::BASE - $overflow; + $tempsplit = $split - $remaining; + $tempwidth = (int)($tempsplit / static::BASE + 1); + $digit = array_slice($val, $i, $tempwidth); + $i += $tempwidth; + $tempoverflow = $tempsplit % static::BASE; + if ($tempoverflow) { + $tempmask = (1 << $tempoverflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $tempmask; + } + $newbits = 0; + for ($j = count($digit) - 1; $j >= 0; $j--) { + $temp = $digit[$j] & $mask; + $digit[$j] = ($digit[$j] >> $overflow) | ($newbits << $remaining); + $newbits = $temp; + } + $overflow = $tempoverflow; + $mask = $tempmask; + } + $temp = new static(); + $temp->value = static::trim($digit); + $vals[] = $temp; + } + + return array_reverse($vals); + } + + /** + * Bitwise Split where $split < static::BASE + * + * @param int $split + * @return list + */ + private function bitwise_small_split($split) + { + $vals = []; + $val = $this->value; + + $mask = (1 << $split) - 1; + + $i = $overflow = 0; + $len = count($val); + $val[] = 0; + $remaining = static::BASE; + while ($i != $len) { + $digit = $val[$i] & $mask; + $val[$i] >>= $split; + if (!$overflow) { + $remaining -= $split; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + + if (!$remaining) { + $i++; + $remaining = static::BASE; + $overflow = 0; + } + } elseif (++$i != $len) { + $tempmask = (1 << $overflow) - 1; + $digit |= ($val[$i] & $tempmask) << $remaining; + $val[$i] >>= $overflow; + $remaining = static::BASE - $overflow; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + } + + $vals[] = $digit; + } + + while ($vals[count($vals) - 1] == 0) { + unset($vals[count($vals) - 1]); + } + + return array_reverse($vals); + } + + /** + * @return bool + */ + protected static function testJITOnWindows() + { + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && !defined('PHPSECLIB_ALLOW_JIT')) { + $status = opcache_get_status(); + if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { + return true; + } + } + return false; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php new file mode 100644 index 000000000..40f64bd17 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php @@ -0,0 +1,143 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP; + +/** + * PHP Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Base extends PHP +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * The most naive approach to modular exponentiation has very unreasonable requirements, and + * and although the approach involving repeated squaring does vastly better, it, too, is impractical + * for our purposes. The reason being that division - by far the most complicated and time-consuming + * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. + * + * Modular reductions resolve this issue. Although an individual modular reduction takes more time + * then an individual division, when performed in succession (with the same modulo), they're a lot faster. + * + * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, + * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the + * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because + * the product of two odd numbers is odd), but what about when RSA isn't used? + * + * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a + * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the + * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, + * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and + * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. + * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. + * + * @param PHP $x + * @param PHP $e + * @param PHP $n + * @param string $class + * @return PHP + */ + protected static function powModHelper(PHP $x, PHP $e, PHP $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = [1]; + return $x->normalize($temp); + } + + if ($e->value == [1]) { + list(, $temp) = $x->divide($n); + return $x->normalize($temp); + } + + if ($e->value == [2]) { + $temp = new $class(); + $temp->value = $class::square($x->value); + list(, $temp) = $temp->divide($n); + return $x->normalize($temp); + } + + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + + /** + * Modular reduction preparation + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return static::reduce($x, $n, $class); + } + + /** + * Modular multiply + * + * @param array $x + * @param array $y + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function multiplyReduce(array $x, array $y, array $n, $class) + { + $temp = $class::multiplyHelper($x, false, $y, false); + return static::reduce($temp[self::VALUE], $n, $class); + } + + /** + * Modular square + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function squareReduce(array $x, array $n, $class) + { + return static::reduce($class::square($x), $n, $class); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php new file mode 100644 index 000000000..6d33532e1 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; + +/** + * PHP Default Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends EvalBarrett +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php new file mode 100644 index 000000000..09f825f95 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php @@ -0,0 +1,89 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\Engine; +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; + +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Montgomery extends Base +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T + */ + protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) + { + // is the modulo odd? + if ($n->value[0] & 1) { + return parent::slidingWindow($x, $e, $n, $class); + } + // if it's not, it's even + + // find the lowest set bit (eg. the max pow of 2 that divides $n) + for ($i = 0; $i < count($n->value); ++$i) { + if ($n->value[$i]) { + $temp = decbin($n->value[$i]); + $j = strlen($temp) - strrpos($temp, '1') - 1; + $j += $class::BASE * $i; + break; + } + } + // at this point, 2^$j * $n/(2^$j) == $n + + $mod1 = clone $n; + $mod1->rshift($j); + $mod2 = new $class(); + $mod2->value = [1]; + $mod2->lshift($j); + + $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); + $part2 = PowerOfTwo::slidingWindow($x, $e, $mod2, $class); + + $y1 = $mod2->modInverse($mod1); + $y2 = $mod1->modInverse($mod2); + + $result = $part1->multiply($mod2); + $result = $result->multiply($y1); + + $temp = $part2->multiply($mod1); + $temp = $temp->multiply($y2); + + $result = $result->add($temp); + list(, $result) = $result->divide($n); + + return $result; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php new file mode 100644 index 000000000..eddd25e2e --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL extends Progenitor +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php new file mode 100644 index 000000000..3518d76f3 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php @@ -0,0 +1,281 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Barrett extends Base +{ + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param array $n + * @param array $m + * @param class-string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $m_length = count($m); + + // if (self::compareHelper($n, $static::square($m)) >= 0) { + if (count($n) > 2 * $m_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $n; + $rhs->value = $m; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m, $class); + } + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = new $class(); + $lhs_value = &$lhs->value; + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $m; + + list($u, $m1) = $lhs->divide($rhs); + $u = $u->value; + $m1 = $m1->value; + + $cache[self::DATA][] = [ + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1' => $m1 // m.length + ]; + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) + $msd = array_slice($n, $cutoff); // m.length >> 1 + + $lsd = self::trim($lsd); + $temp = $class::multiplyHelper($msd, false, $m1, false); // m.length + (m.length >> 1) + $n = $class::addHelper($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n[self::VALUE], $m, $class); + //} + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = array_slice($n[self::VALUE], $m_length - 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = $class::multiplyHelper($temp, false, $u, false); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = $class::multiplyHelper($temp, false, $m, false); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = $class::subtractHelper($n[self::VALUE], false, $temp[self::VALUE], false); + + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, false); + } + + return $result[self::VALUE]; + } + + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + private static function regularBarrett(array $x, array $n, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $n_length = count($n); + + if (count($x) > 2 * $n_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $x; + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = new $class(); + $lhs_value = &$lhs->value; + $lhs_value = self::array_repeat(0, 2 * $n_length); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $n; + list($temp, ) = $lhs->divide($rhs); // m.length + $cache[self::DATA][] = $temp->value; + } + + // 2 * m.length - (m.length - 1) = m.length + 1 + $temp = array_slice($x, $n_length - 1); + // (m.length + 1) + m.length = 2 * m.length + 1 + $temp = $class::multiplyHelper($temp, false, $cache[self::DATA][$key], false); + // (2 * m.length + 1) - (m.length - 1) = m.length + 2 + $temp = array_slice($temp[self::VALUE], $n_length + 1); + + // m.length + 1 + $result = array_slice($x, 0, $n_length + 1); + // m.length + 1 + $temp = self::multiplyLower($temp, false, $n, false, $n_length + 1, $class); + // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) + + if (self::compareHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { + $corrector_value = self::array_repeat(0, $n_length + 1); + $corrector_value[count($corrector_value)] = 1; + $result = $class::addHelper($result, false, $corrector_value, false); + $result = $result[self::VALUE]; + } + + // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits + $result = $class::subtractHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]); + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Performs long multiplication up to $stop digits + * + * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. + * + * @see self::regularBarrett() + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @param int $stop + * @param string $class + * @return array + */ + private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + if ($x_length < $y_length) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_length = count($x_value); + $y_length = count($y_value); + } + + $product_value = self::array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); + } + + if ($j < $stop) { + $product_value[$j] = $carry; + } + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); + } + + if ($k < $stop) { + $product_value[$k] = $carry; + } + } + + return [ + self::VALUE => self::trim($product_value), + self::SIGN => $x_negative != $y_negative + ]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php new file mode 100644 index 000000000..54f3b863b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Classic Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Classic extends Base +{ + /** + * Regular Division + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php new file mode 100644 index 000000000..2f9433172 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php @@ -0,0 +1,484 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Dynamic Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class EvalBarrett extends Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param array $n + * @param array $m + * @param string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + $inline = self::$custom_reduction; + return $inline($n); + } + + /** + * Generate Custom Reduction + * + * @param PHP $m + * @param string $class + * @return callable + */ + protected static function generateCustomReduction(PHP $m, $class) + { + $m_length = count($m->value); + + if ($m_length < 5) { + $code = ' + $lhs = new ' . $class . '(); + $lhs->value = $x; + $rhs = new ' . $class . '(); + $rhs->value = [' . + implode(',', array_map(self::class . '::float2string', $m->value)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + '; + eval('$func = function ($x) { ' . $code . '};'); + self::$custom_reduction = $func; + //self::$custom_reduction = \Closure::bind($func, $m, $class); + return $func; + } + + $lhs = new $class(); + $lhs_value = &$lhs->value; + + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + + list($u, $m1) = $lhs->divide($m); + + if ($class::BASE != 26) { + $u = $u->value; + } else { + $lhs_value = self::array_repeat(0, 2 * $m_length); + $lhs_value[] = 1; + $rhs = new $class(); + + list($u) = $lhs->divide($m); + $u = $u->value; + } + + $m = $m->value; + $m1 = $m1->value; + + $cutoff = count($m) + (count($m) >> 1); + + $code = ' + if (count($n) > ' . (2 * count($m)) . ') { + $lhs = new ' . $class . '(); + $rhs = new ' . $class . '(); + $lhs->value = $n; + $rhs->value = [' . + implode(',', array_map(self::class . '::float2string', $m)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + $lsd = array_slice($n, 0, ' . $cutoff . '); + $msd = array_slice($n, ' . $cutoff . ');'; + + $code .= self::generateInlineTrim('msd'); + $code .= self::generateInlineMultiply('msd', $m1, 'temp', $class); + $code .= self::generateInlineAdd('lsd', 'temp', 'n', $class); + + $code .= '$temp = array_slice($n, ' . (count($m) - 1) . ');'; + $code .= self::generateInlineMultiply('temp', $u, 'temp2', $class); + $code .= self::generateInlineTrim('temp2'); + + $code .= $class::BASE == 26 ? + '$temp = array_slice($temp2, ' . (count($m) + 1) . ');' : + '$temp = array_slice($temp2, ' . ((count($m) >> 1) + 1) . ');'; + $code .= self::generateInlineMultiply('temp', $m, 'temp2', $class); + $code .= self::generateInlineTrim('temp2'); + + /* + if ($class::BASE == 26) { + $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); + $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; + } + */ + + $code .= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); + + $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); + $subcode .= '$temp = $temp2;'; + + $code .= self::generateInlineCompare($m, 'temp', $subcode); + + $code .= 'return $temp;'; + + eval('$func = function ($n) { ' . $code . '};'); + + self::$custom_reduction = $func; + + return $func; + + //self::$custom_reduction = \Closure::bind($func, $m, $class); + } + + /** + * Inline Trim + * + * Removes leading zeros + * + * @param string $name + * @return string + */ + private static function generateInlineTrim($name) + { + return ' + for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { + if ($' . $name . '[$i]) { + break; + } + unset($' . $name . '[$i]); + }'; + } + + /** + * Inline Multiply (unknown, known) + * + * @param string $input + * @param array $arr + * @param string $output + * @param string $class + * @return string + */ + private static function generateInlineMultiply($input, array $arr, $output, $class) + { + if (!count($arr)) { + return 'return [];'; + } + + $regular = ' + $length = count($' . $input . '); + if (!$length) { + $' . $output . ' = []; + }else{ + $' . $output . ' = array_fill(0, $length + ' . count($arr) . ', 0); + $carry = 0;'; + + for ($i = 0; $i < count($arr); $i++) { + $regular .= ' + $subtemp = $' . $input . '[0] * ' . $arr[$i]; + $regular .= $i ? ' + $carry;' : ';'; + + $regular .= '$carry = '; + $regular .= $class::BASE === 26 ? + 'intval($subtemp / 0x4000000);' : + '$subtemp >> 31;'; + $regular .= + '$' . $output . '[' . $i . '] = '; + if ($class::BASE === 26) { + $regular .= '(int) ('; + } + $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular .= $class::BASE === 26 ? ');' : ';'; + } + + $regular .= '$' . $output . '[' . count($arr) . '] = $carry;'; + + $regular .= ' + for ($i = 1; $i < $length; ++$i) {'; + + for ($j = 0; $j < count($arr); $j++) { + $regular .= $j ? '$k++;' : '$k = $i;'; + $regular .= ' + $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; + $regular .= $j ? ' + $carry;' : ';'; + + $regular .= '$carry = '; + $regular .= $class::BASE === 26 ? + 'intval($subtemp / 0x4000000);' : + '$subtemp >> 31;'; + $regular .= + '$' . $output . '[$k] = '; + if ($class::BASE === 26) { + $regular .= '(int) ('; + } + $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular .= $class::BASE === 26 ? ');' : ';'; + } + + $regular .= '$' . $output . '[++$k] = $carry; $carry = 0;'; + + $regular .= '}}'; + + //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { + //} + + return $regular; + } + + /** + * Inline Addition + * + * @param string $x + * @param string $y + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineAdd($x, $y, $result, $class) + { + $code = ' + $length = max(count($' . $x . '), count($' . $y . ')); + $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); + $_' . $y . ' = array_pad($' . $y . ', $length, 0); + $carry = 0; + for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { + $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' + + $' . $result . '[$i] + $_' . $y . '[$i] + + $carry; + $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; + $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; + + $code .= $class::BASE === 26 ? + '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : + '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; + $code .= ' + $' . $result . '[$j] = $upper; + } + if ($j == $length) { + $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; + $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; + $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; + ++$i; + } + if ($carry) { + for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { + $' . $result . '[$i] = 0; + } + ++$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Subtraction 2 + * + * For when $known is more digits than $unknown. This is the harder use case to optimize for. + * + * @param string $known + * @param string $unknown + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract2($known, $unknown, $result, $class) + { + $code = ' + $' . $result . ' = $' . $known . '; + $carry = 0; + $size = count($' . $unknown . '); + for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { + $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] + - $' . $unknown . '[$i] + - $carry; + $carry = $sum < 0; + if ($carry) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code .= $class::BASE === 26 ? + 'intval($sum / 0x4000000);' : + '$sum >> 31;'; + $code .= '$' . $result . '[$i] = '; + if ($class::BASE === 26) { + $code .= '(int) ('; + } + $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code .= ')'; + } + $code .= '; + $' . $result . '[$j] = $subtemp; + } + if ($j == $size) { + $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; + $carry = $sum < 0; + $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i; + } + + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + + $code .= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Subtraction 1 + * + * For when $unknown is more digits than $known. This is the easier use case to optimize for. + * + * @param string $unknown + * @param array $known + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract1($unknown, array $known, $result, $class) + { + $code = '$' . $result . ' = $' . $unknown . ';'; + for ($i = 0, $j = 1; $j < count($known); $i += 2, $j += 2) { + $code .= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; + $code .= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); + if ($i != 0) { + $code .= ' - $carry'; + } + + $code .= '; + if ($carry = $sum < 0) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code .= $class::BASE === 26 ? + 'intval($sum / 0x4000000);' : + '$sum >> 31;'; + $code .= ' + $' . $result . '[' . $i . '] = '; + if ($class::BASE === 26) { + $code .= ' (int) ('; + } + $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code .= ')'; + } + $code .= '; + $' . $result . '[' . $j . '] = $subtemp;'; + } + + $code .= '$i = ' . $i . ';'; + + if ($j == count($known)) { + $code .= ' + $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; + $carry = $sum < 0; + $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i;'; + } + + $code .= ' + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Comparison + * + * If $unknown >= $known then loop + * + * @param array $known + * @param string $unknown + * @param string $subcode + * @return string + */ + private static function generateInlineCompare(array $known, $unknown, $subcode) + { + $uniqid = uniqid(); + $code = 'loop_' . $uniqid . ': + $clength = count($' . $unknown . '); + switch (true) { + case $clength < ' . count($known) . ': + goto end_' . $uniqid . '; + case $clength > ' . count($known) . ':'; + for ($i = count($known) - 1; $i >= 0; $i--) { + $code .= ' + case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': + goto subcode_' . $uniqid . '; + case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': + goto end_' . $uniqid . ';'; + } + $code .= ' + default: + // do subcode + } + + subcode_' . $uniqid . ':' . $subcode . ' + goto loop_' . $uniqid . '; + + end_' . $uniqid . ':'; + + return $code; + } + + /** + * Convert a float to a string + * + * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of + * precision but displayed in this way there will be precision loss, hence the need for this method. + * + * @param int|float $num + * @return string + */ + private static function float2string($num) + { + if (!is_float($num)) { + return (string) $num; + } + + if ($num < 0) { + return '-' . self::float2string(abs($num)); + } + + $temp = ''; + while ($num) { + $temp = fmod($num, 10) . $temp; + $num = floor($num / 10); + } + + return $temp; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php new file mode 100644 index 000000000..a34035e7a --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php @@ -0,0 +1,126 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; + +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Montgomery extends Progenitor +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = array_merge(self::array_repeat(0, count($n)), $x); + $rhs = new $class(); + $rhs->value = $n; + + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $x; + $cache[self::DATA][] = self::modInverse67108864($n, $class); + } + + $k = count($n); + + $result = [self::VALUE => $x]; + + for ($i = 0; $i < $k; ++$i) { + $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $class::regularMultiply([$temp], $n); + $temp = array_merge(self::array_repeat(0, $i), $temp); + $result = $class::addHelper($result[self::VALUE], false, $temp, false); + } + + $result[self::VALUE] = array_slice($result[self::VALUE], $k); + + if (self::compareHelper($result, false, $n, false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], false, $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Modular Inverse of a number mod 2**26 (eg. 67108864) + * + * Based off of the bnpInvDigit function implemented and justified in the following URL: + * + * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} + * + * The following URL provides more info: + * + * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} + * + * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For + * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields + * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't + * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that + * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the + * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to + * 40 bits, which only 64-bit floating points will support. + * + * Thanks to Pedro Gimeno Fortea for input! + * + * @param array $x + * @param string $class + * @return int + */ + protected static function modInverse67108864(array $x, $class) // 2**26 == 67,108,864 + { + $x = -$x[0]; + $result = $x & 0x3; // x**-1 mod 2**2 + $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 + $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 + $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 + $result = $class::BASE == 26 ? + fmod($result * (2 - fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : // x**-1 mod 2**26 + ($result * (2 - ($x * $result) % $class::BASE_FULL)) % $class::BASE_FULL; + return $result & $class::MAX_DIGIT; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php new file mode 100644 index 000000000..4fed3c3fa --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php @@ -0,0 +1,76 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP; + +/** + * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication + * + * @author Jim Wigginton + */ +abstract class MontgomeryMult extends Montgomery +{ + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @see self::_prepMontgomery() + * @see self::_montgomery() + * @param array $x + * @param array $y + * @param array $m + * @param class-string $class + * @return array + */ + public static function multiplyReduce(array $x, array $y, array $m, $class) + { + // the following code, although not callable, can be run independently of the above code + // although the above code performed better in my benchmarks the following could might + // perform better under different circumstances. in lieu of deleting it it's just been + // made uncallable + + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $cache[self::DATA][] = self::modInverse67108864($m, $class); + } + + $n = max(count($x), count($y), count($m)); + $x = array_pad($x, $n, 0); + $y = array_pad($y, $n, 0); + $m = array_pad($m, $n, 0); + $a = [self::VALUE => self::array_repeat(0, $n + 1)]; + for ($i = 0; $i < $n; ++$i) { + $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $temp * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), false, $class::regularMultiply([$temp], $m), false); + $a = $class::addHelper($a[self::VALUE], false, $temp[self::VALUE], false); + $a[self::VALUE] = array_slice($a[self::VALUE], 1); + } + if (self::compareHelper($a[self::VALUE], false, $m, false) >= 0) { + $a = $class::subtractHelper($a[self::VALUE], false, $m, false); + } + return $a[self::VALUE]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php new file mode 100644 index 000000000..9da133a14 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php @@ -0,0 +1,59 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Power Of Two Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class PowerOfTwo extends Base +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return self::reduce($x, $n, $class); + } + + /** + * Power Of Two Reduction + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + + $temp = new $class(); + $temp->value = [1]; + + $result = $lhs->bitwise_and($rhs->subtract($temp)); + return $result->value; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php new file mode 100644 index 000000000..3a775e7db --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -0,0 +1,371 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +/** + * Pure-PHP 32-bit Engine. + * + * Uses 64-bit floats if int size is 4 bits + * + * @author Jim Wigginton + */ +class PHP32 extends PHP +{ + // Constants used by PHP.php + const BASE = 26; + const BASE_FULL = 0x4000000; + const MAX_DIGIT = 0x3FFFFFF; + const MSB = 0x2000000; + + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 10000000; + + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 7; + const MAX_DIGIT2 = 4503599627370496; + + /** + * Initialize a PHP32 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + + $val = $this->value; + $this->value = []; + $vals = &$this->value; + $i = strlen($val); + if (!$i) { + return; + } + + while (true) { + $i -= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = substr($val, 0, 4 + $i); + $val = str_pad($val, 4, "\0", STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = unpack('N', substr($val, $i, 4)); + if ($digit < 0) { + $digit += 0xFFFFFFFF + 1; + } + $step = count($vals) & 3; + if ($step) { + $digit = (int) floor($digit / pow(2, 2 * $step)); + } + if ($step != 3) { + $digit = (int) fmod($digit, static::BASE_FULL); + $i++; + } + $vals[] = $digit; + } + while (end($vals) === 0) { + array_pop($vals); + } + reset($vals); + } + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return PHP_INT_SIZE >= 4 && !self::testJITOnWindows(); + } + + /** + * Adds two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function add(PHP32 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function subtract(PHP32 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function multiply(PHP32 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP32 $y + * @return array{PHP32, PHP32} + */ + public function divide(PHP32 $y) + { + return $this->divideHelper($y); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return false|PHP32 + */ + public function modInverse(PHP32 $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return PHP32[] + */ + public function extendedGCD(PHP32 $n) + { + return $this->extendedGCDHelper($n); + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP32 $n + * @return PHP32 + */ + public function gcd(PHP32 $n) + { + return $this->extendedGCD($n)['gcd']; + } + + /** + * Logical And + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_and(PHP32 $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_or(PHP32 $x) + { + return $this->bitwiseOrHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_xor(PHP32 $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP32 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(PHP32 $y) + { + return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP32 $x + * @return bool + */ + public function equals(PHP32 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + + /** + * Performs modular exponentiation. + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function modPow(PHP32 $e, PHP32 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function powMod(PHP32 $e, PHP32 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP32 $min + * @param PHP32 $max + * @return false|PHP32 + */ + public static function randomRangePrime(PHP32 $min, PHP32 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP32 $min + * @param PHP32 $max + * @return PHP32 + */ + public static function randomRange(PHP32 $min, PHP32 $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Performs exponentiation. + * + * @param PHP32 $n + * @return PHP32 + */ + public function pow(PHP32 $n) + { + return $this->powHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function min(PHP32 ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function max(PHP32 ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP32 $min + * @param PHP32 $max + * @return bool + */ + public function between(PHP32 $min, PHP32 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php new file mode 100644 index 000000000..70a2e173b --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -0,0 +1,372 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +/** + * Pure-PHP 64-bit Engine. + * + * Uses 64-bit integers if int size is 8 bits + * + * @author Jim Wigginton + */ +class PHP64 extends PHP +{ + // Constants used by PHP.php + const BASE = 31; + const BASE_FULL = 0x80000000; + const MAX_DIGIT = 0x7FFFFFFF; + const MSB = 0x40000000; + + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 1000000000; + + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 9; + const MAX_DIGIT2 = 4611686018427387904; + + /** + * Initialize a PHP64 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + + $val = $this->value; + $this->value = []; + $vals = &$this->value; + $i = strlen($val); + if (!$i) { + return; + } + + while (true) { + $i -= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = substr($val, 0, 4 + $i); + $val = str_pad($val, 4, "\0", STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = unpack('N', substr($val, $i, 4)); + $step = count($vals) & 7; + if (!$step) { + $digit &= static::MAX_DIGIT; + $i++; + } else { + $shift = 8 - $step; + $digit >>= $shift; + $shift = 32 - $shift; + $digit &= (1 << $shift) - 1; + $temp = $i > 0 ? ord($val[$i - 1]) : 0; + $digit |= ($temp << $shift) & 0x7F000000; + } + $vals[] = $digit; + } + while (end($vals) === 0) { + array_pop($vals); + } + reset($vals); + } + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return PHP_INT_SIZE >= 8 && !self::testJITOnWindows(); + } + + /** + * Adds two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function add(PHP64 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function subtract(PHP64 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function multiply(PHP64 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP64 $y + * @return array{PHP64, PHP64} + */ + public function divide(PHP64 $y) + { + return $this->divideHelper($y); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return false|PHP64 + */ + public function modInverse(PHP64 $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return PHP64[] + */ + public function extendedGCD(PHP64 $n) + { + return $this->extendedGCDHelper($n); + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP64 $n + * @return PHP64 + */ + public function gcd(PHP64 $n) + { + return $this->extendedGCD($n)['gcd']; + } + + /** + * Logical And + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_and(PHP64 $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_or(PHP64 $x) + { + return $this->bitwiseOrHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_xor(PHP64 $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP64 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(PHP64 $y) + { + return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP64 $x + * @return bool + */ + public function equals(PHP64 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + + /** + * Performs modular exponentiation. + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64 + */ + public function modPow(PHP64 $e, PHP64 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64|false + */ + public function powMod(PHP64 $e, PHP64 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP64 $min + * @param PHP64 $max + * @return false|PHP64 + */ + public static function randomRangePrime(PHP64 $min, PHP64 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP64 $min + * @param PHP64 $max + * @return PHP64 + */ + public static function randomRange(PHP64 $min, PHP64 $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Performs exponentiation. + * + * @param PHP64 $n + * @return PHP64 + */ + public function pow(PHP64 $n) + { + return $this->powHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function min(PHP64 ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function max(PHP64 ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP64 $min + * @param PHP64 $max + * @return bool + */ + public function between(PHP64 $min, PHP64 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php new file mode 100644 index 000000000..3e21a67ad --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php @@ -0,0 +1,194 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BinaryField\Integer; +use phpseclib3\Math\Common\FiniteField; + +/** + * Binary Finite Fields + * + * @author Jim Wigginton + */ +class BinaryField extends FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** @var BigInteger */ + private $randomMax; + + /** + * Default constructor + */ + public function __construct(...$indices) + { + $m = array_shift($indices); + $val = str_repeat('0', $m) . '1'; + foreach ($indices as $index) { + $val[$index] = '1'; + } + $modulo = static::base2ToBase256(strrev($val)); + + $mStart = 2 * $m - 2; + $t = ceil($m / 8); + $finalMask = chr((1 << ($m % 8)) - 1); + if ($finalMask == "\0") { + $finalMask = "\xFF"; + } + $bitLen = $mStart + 1; + $pad = ceil($bitLen / 8); + $h = $bitLen & 7; + $h = $h ? 8 - $h : 0; + + $r = rtrim(substr($val, 0, -1), '0'); + $u = [static::base2ToBase256(strrev($r))]; + for ($i = 1; $i < 8; $i++) { + $u[] = static::base2ToBase256(strrev(str_repeat('0', $i) . $r)); + } + + // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" + // with W = 8 + $reduce = function ($c) use ($u, $mStart, $m, $t, $finalMask, $pad, $h) { + $c = str_pad($c, $pad, "\0", STR_PAD_LEFT); + for ($i = $mStart; $i >= $m;) { + $g = $h >> 3; + $mask = $h & 7; + $mask = $mask ? 1 << (7 - $mask) : 0x80; + for (; $mask > 0; $mask >>= 1, $i--, $h++) { + if (ord($c[$g]) & $mask) { + $temp = $i - $m; + $j = $temp >> 3; + $k = $temp & 7; + $t1 = $j ? substr($c, 0, -$j) : $c; + $length = strlen($t1); + if ($length) { + $t2 = str_pad($u[$k], $length, "\0", STR_PAD_LEFT); + $temp = $t1 ^ $t2; + $c = $j ? substr_replace($c, $temp, 0, $length) : $temp; + } + } + } + } + $c = substr($c, -$t); + if (strlen($c) == $t) { + $c[0] = $c[0] & $finalMask; + } + return ltrim($c, "\0"); + }; + + $this->instanceID = self::$instanceCounter++; + Integer::setModulo($this->instanceID, $modulo); + Integer::setRecurringModuloFunction($this->instanceID, $reduce); + + $this->randomMax = new BigInteger($modulo, 2); + } + + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @param string $num + * @return Integer + */ + public function newInteger($num) + { + return new Integer($this->instanceID, $num instanceof BigInteger ? $num->toBytes() : $num); + } + + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return Integer + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return new Integer($this->instanceID, BigInteger::randomRange($one, $this->randomMax)->toBytes()); + } + + /** + * Returns the length of the modulo in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return strlen(Integer::getModulo($this->instanceID)); + } + + /** + * Returns the length of the modulo in bits + * + * @return int + */ + public function getLength() + { + return strlen(Integer::getModulo($this->instanceID)) << 3; + } + + /** + * Converts a base-2 string to a base-256 string + * + * @param string $x + * @param int|null $size + * @return string + */ + public static function base2ToBase256($x, $size = null) + { + $str = Strings::bits2bin($x); + + $pad = strlen($x) >> 3; + if (strlen($x) & 3) { + $pad++; + } + $str = str_pad($str, $pad, "\0", STR_PAD_LEFT); + if (isset($size)) { + $str = str_pad($str, $size, "\0", STR_PAD_LEFT); + } + + return $str; + } + + /** + * Converts a base-256 string to a base-2 string + * + * @param string $x + * @return string + */ + public static function base256ToBase2($x) + { + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + + return Strings::bin2bits($x); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php new file mode 100644 index 000000000..8e880589c --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php @@ -0,0 +1,516 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\BinaryField; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\Common\FiniteField\Integer as Base; + +/** + * Binary Finite Fields + * + * @author Jim Wigginton + */ +class Integer extends Base +{ + /** + * Holds the BinaryField's value + * + * @var string + */ + protected $value; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Holds the PrimeField's modulo + * + * @var array + */ + protected static $modulo; + + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var callable[] + */ + protected static $reduce; + + /** + * Default constructor + */ + public function __construct($instanceID, $num = '') + { + $this->instanceID = $instanceID; + if (!strlen($num)) { + $this->value = ''; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + + /** + * Set the modulo for a given instance + * @param int $instanceID + * @param string $modulo + */ + public static function setModulo($instanceID, $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + + /** + * Set the modulo for a given instance + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + } + + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + */ + private static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); + } + } + + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + + return $this->value == $x->value; + } + + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + + $a = $this->value; + $b = $x->value; + + $length = max(strlen($a), strlen($b)); + + $a = str_pad($a, $length, "\0", STR_PAD_LEFT); + $b = str_pad($b, $length, "\0", STR_PAD_LEFT); + + return strcmp($a, $b); + } + + /** + * Returns the degree of the polynomial + * + * @param string $x + * @return int + */ + private static function deg($x) + { + $x = ltrim($x, "\0"); + $xbit = decbin(ord($x[0])); + $xlen = $xbit == '0' ? 0 : strlen($xbit); + $len = strlen($x); + if (!$len) { + return -1; + } + return 8 * strlen($x) - 9 + $xlen; + } + + /** + * Perform polynomial division + * + * @return string[] + * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division + */ + private static function polynomialDivide($x, $y) + { + // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's + // always going to be 1. + + $q = chr(0); + $d = static::deg($y); + $r = $x; + while (($degr = static::deg($r)) >= $d) { + $s = '1' . str_repeat('0', $degr - $d); + $s = BinaryField::base2ToBase256($s); + $length = max(strlen($s), strlen($q)); + $q = !isset($q) ? $s : + str_pad($q, $length, "\0", STR_PAD_LEFT) ^ + str_pad($s, $length, "\0", STR_PAD_LEFT); + $s = static::polynomialMultiply($s, $y); + $length = max(strlen($r), strlen($s)); + $r = str_pad($r, $length, "\0", STR_PAD_LEFT) ^ + str_pad($s, $length, "\0", STR_PAD_LEFT); + } + + return [ltrim($q, "\0"), ltrim($r, "\0")]; + } + + /** + * Perform polynomial multiplation in the traditional way + * + * @return string + * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication + */ + private static function regularPolynomialMultiply($x, $y) + { + $precomputed = [ltrim($x, "\0")]; + $x = strrev(BinaryField::base256ToBase2($x)); + $y = strrev(BinaryField::base256ToBase2($y)); + if (strlen($x) == strlen($y)) { + $length = strlen($x); + } else { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, '0'); + $y = str_pad($y, $length, '0'); + } + $result = str_repeat('0', 2 * $length - 1); + $result = BinaryField::base2ToBase256($result); + $size = strlen($result); + $x = strrev($x); + + // precompute left shift 1 through 7 + for ($i = 1; $i < 8; $i++) { + $precomputed[$i] = BinaryField::base2ToBase256($x . str_repeat('0', $i)); + } + for ($i = 0; $i < strlen($y); $i++) { + if ($y[$i] == '1') { + $temp = $precomputed[$i & 7] . str_repeat("\0", $i >> 3); + $result ^= str_pad($temp, $size, "\0", STR_PAD_LEFT); + } + } + + return $result; + } + + /** + * Perform polynomial multiplation + * + * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications + * + * @return string + * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm + */ + private static function polynomialMultiply($x, $y) + { + if (strlen($x) == strlen($y)) { + $length = strlen($x); + } else { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + } + + switch (true) { + case PHP_INT_SIZE == 8 && $length <= 4: + return $length != 4 ? + self::subMultiply(str_pad($x, 4, "\0", STR_PAD_LEFT), str_pad($y, 4, "\0", STR_PAD_LEFT)) : + self::subMultiply($x, $y); + case PHP_INT_SIZE == 4 || $length > 32: + return self::regularPolynomialMultiply($x, $y); + } + + $m = $length >> 1; + + $x1 = substr($x, 0, -$m); + $x0 = substr($x, -$m); + $y1 = substr($y, 0, -$m); + $y0 = substr($y, -$m); + + $z2 = self::polynomialMultiply($x1, $y1); + $z0 = self::polynomialMultiply($x0, $y0); + $z1 = self::polynomialMultiply( + self::subAdd2($x1, $x0), + self::subAdd2($y1, $y0) + ); + + $z1 = self::subAdd3($z1, $z2, $z0); + + $xy = self::subAdd3( + $z2 . str_repeat("\0", 2 * $m), + $z1 . str_repeat("\0", $m), + $z0 + ); + + return ltrim($xy, "\0"); + } + + /** + * Perform polynomial multiplication on 2x 32-bit numbers, returning + * a 64-bit number + * + * @param string $x + * @param string $y + * @return string + * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm + */ + private static function subMultiply($x, $y) + { + $x = unpack('N', $x)[1]; + $y = unpack('N', $y)[1]; + + $x0 = $x & 0x11111111; + $x1 = $x & 0x22222222; + $x2 = $x & 0x44444444; + $x3 = $x & 0x88888888; + + $y0 = $y & 0x11111111; + $y1 = $y & 0x22222222; + $y2 = $y & 0x44444444; + $y3 = $y & 0x88888888; + + $z0 = ($x0 * $y0) ^ ($x1 * $y3) ^ ($x2 * $y2) ^ ($x3 * $y1); + $z1 = ($x0 * $y1) ^ ($x1 * $y0) ^ ($x2 * $y3) ^ ($x3 * $y2); + $z2 = ($x0 * $y2) ^ ($x1 * $y1) ^ ($x2 * $y0) ^ ($x3 * $y3); + $z3 = ($x0 * $y3) ^ ($x1 * $y2) ^ ($x2 * $y1) ^ ($x3 * $y0); + + $z0 &= 0x1111111111111111; + $z1 &= 0x2222222222222222; + $z2 &= 0x4444444444444444; + $z3 &= -8608480567731124088; // 0x8888888888888888 gets interpreted as a float + + $z = $z0 | $z1 | $z2 | $z3; + + return pack('J', $z); + } + + /** + * Adds two numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd2($x, $y) + { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + return $x ^ $y; + } + + /** + * Adds three numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd3($x, $y, $z) + { + $length = max(strlen($x), strlen($y), strlen($z)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + $z = str_pad($z, $length, "\0", STR_PAD_LEFT); + return $x ^ $y ^ $z; + } + + /** + * Adds two BinaryFieldIntegers. + * + * @return static + */ + public function add(self $y) + { + static::checkInstance($this, $y); + + $length = strlen(static::$modulo[$this->instanceID]); + + $x = str_pad($this->value, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y->value, $length, "\0", STR_PAD_LEFT); + + return new static($this->instanceID, $x ^ $y); + } + + /** + * Subtracts two BinaryFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + return $this->add($x); + } + + /** + * Multiplies two BinaryFieldIntegers. + * + * @return static + */ + public function multiply(self $y) + { + static::checkInstance($this, $y); + + return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); + } + + /** + * Returns the modular inverse of a BinaryFieldInteger + * + * @return static + */ + public function modInverse() + { + $remainder0 = static::$modulo[$this->instanceID]; + $remainder1 = $this->value; + + if ($remainder1 == '') { + return new static($this->instanceID); + } + + $aux0 = "\0"; + $aux1 = "\1"; + while ($remainder1 != "\1") { + list($q, $r) = static::polynomialDivide($remainder0, $remainder1); + $remainder0 = $remainder1; + $remainder1 = $r; + // the auxiliary in row n is given by the sum of the auxiliary in + // row n-2 and the product of the quotient and the auxiliary in row + // n-1 + $temp = static::polynomialMultiply($aux1, $q); + $aux = str_pad($aux0, strlen($temp), "\0", STR_PAD_LEFT) ^ + str_pad($temp, strlen($aux0), "\0", STR_PAD_LEFT); + $aux0 = $aux1; + $aux1 = $aux; + } + + $temp = new static($this->instanceID); + $temp->value = ltrim($aux1, "\0"); + return $temp; + } + + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + + $x = $x->modInverse(); + return $this->multiply($x); + } + + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return object + */ + public function negate() + { + $x = str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); + + return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); + } + + /** + * Returns the modulo + * + * @return string + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + return str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return Strings::bin2hex($this->toBytes()); + } + + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); + return BinaryField::base256ToBase2($this->value); + } + + /** + * Converts an Integer to a BigInteger + * + * @return string + */ + public function toBigInteger() + { + return new BigInteger($this->value, 256); + } + + /** + * __toString() magic method + * + */ + public function __toString() + { + return (string) $this->toBigInteger(); + } + + /** + * __debugInfo() magic method + * + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php new file mode 100644 index 000000000..2ea5f4858 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php @@ -0,0 +1,22 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\Common; + +/** + * Finite Fields + * + * @author Jim Wigginton + */ +abstract class FiniteField +{ +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php new file mode 100644 index 000000000..3c959e94f --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php @@ -0,0 +1,44 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\Common\FiniteField; + +/** + * Finite Field Integer + * + * @author Jim Wigginton + */ +abstract class Integer implements \JsonSerializable +{ + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * PHP Serialize isn't supported because unserializing would require the factory be + * serialized as well and that just sounds like too much + * + * @return array{hex: string} + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ['hex' => $this->toHex(true)]; + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + abstract public function toHex(); +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php new file mode 100644 index 000000000..1a0667f09 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php @@ -0,0 +1,118 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math; + +use phpseclib3\Math\Common\FiniteField; +use phpseclib3\Math\PrimeField\Integer; + +/** + * Prime Finite Fields + * + * @author Jim Wigginton + */ +class PrimeField extends FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Default constructor + */ + public function __construct(BigInteger $modulo) + { + if (!$modulo->isPrime()) { + throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); + } + + $this->instanceID = self::$instanceCounter++; + Integer::setModulo($this->instanceID, $modulo); + Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); + } + + /** + * Use a custom defined modular reduction function + * + * @return void + */ + public function setReduction(\Closure $func) + { + $this->reduce = $func->bindTo($this, $this); + } + + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @return Integer + */ + public function newInteger(BigInteger $num) + { + return new Integer($this->instanceID, $num); + } + + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return Integer + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); + } + + /** + * Returns the length of the modulo in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return Integer::getModulo($this->instanceID)->getLengthInBytes(); + } + + /** + * Returns the length of the modulo in bits + * + * @return int + */ + public function getLength() + { + return Integer::getModulo($this->instanceID)->getLength(); + } + + /** + * Destructor + */ + public function __destruct() + { + Integer::cleanupCache($this->instanceID); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php new file mode 100644 index 000000000..ddb04912d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php @@ -0,0 +1,419 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\PrimeField; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField\Integer as Base; + +/** + * Prime Finite Fields + * + * @author Jim Wigginton + */ +class Integer extends Base +{ + /** + * Holds the PrimeField's value + * + * @var BigInteger + */ + protected $value; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Holds the PrimeField's modulo + * + * @var array + */ + protected static $modulo; + + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var array + */ + protected static $reduce; + + /** + * Zero + * + * @var BigInteger + */ + protected static $zero; + + /** + * Default constructor + * + * @param int $instanceID + */ + public function __construct($instanceID, BigInteger $num = null) + { + $this->instanceID = $instanceID; + if (!isset($num)) { + $this->value = clone static::$zero[static::class]; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + + /** + * Set the modulo for a given instance + * + * @param int $instanceID + * @return void + */ + public static function setModulo($instanceID, BigInteger $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + + /** + * Set the modulo for a given instance + * + * @param int $instanceID + * @return void + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + if (!isset(static::$zero[static::class])) { + static::$zero[static::class] = new BigInteger(); + } + } + + /** + * Delete the modulo for a given instance + */ + public static function cleanupCache($instanceID) + { + unset(static::$modulo[$instanceID]); + unset(static::$reduce[$instanceID]); + } + + /** + * Returns the modulo + * + * @param int $instanceID + * @return BigInteger + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + * + * @return void + */ + public static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); + } + } + + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + + return $this->value->equals($x->value); + } + + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + + return $this->value->compare($x->value); + } + + /** + * Adds two PrimeFieldIntegers. + * + * @return static + */ + public function add(self $x) + { + static::checkInstance($this, $x); + + $temp = new static($this->instanceID); + $temp->value = $this->value->add($x->value); + if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { + $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); + } + + return $temp; + } + + /** + * Subtracts two PrimeFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + static::checkInstance($this, $x); + + $temp = new static($this->instanceID); + $temp->value = $this->value->subtract($x->value); + if ($temp->value->isNegative()) { + $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); + } + + return $temp; + } + + /** + * Multiplies two PrimeFieldIntegers. + * + * @return static + */ + public function multiply(self $x) + { + static::checkInstance($this, $x); + + return new static($this->instanceID, $this->value->multiply($x->value)); + } + + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + + $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); + return new static($this->instanceID, $this->value->multiply($denominator)); + } + + /** + * Performs power operation on a PrimeFieldInteger. + * + * @return static + */ + public function pow(BigInteger $x) + { + $temp = new static($this->instanceID); + $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); + + return $temp; + } + + /** + * Calculates the square root + * + * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm + * @return static|false + */ + public function squareRoot() + { + static $one, $two; + if (!isset($one)) { + $one = new BigInteger(1); + $two = new BigInteger(2); + } + $reduce = static::$reduce[$this->instanceID]; + $p_1 = static::$modulo[$this->instanceID]->subtract($one); + $q = clone $p_1; + $s = BigInteger::scan1divide($q); + list($pow) = $p_1->divide($two); + for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) { + $temp = $z->powMod($pow, static::$modulo[$this->instanceID]); + if ($temp->equals($p_1)) { + break; + } + } + + $m = new BigInteger($s); + $c = $z->powMod($q, static::$modulo[$this->instanceID]); + $t = $this->value->powMod($q, static::$modulo[$this->instanceID]); + list($temp) = $q->add($one)->divide($two); + $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); + + while (!$t->equals($one)) { + for ($i == clone $one; $i->compare($m) < 0; $i = $i->add($one)) { + if ($t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { + break; + } + } + + if ($i->compare($m) == 0) { + return false; + } + $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]); + $m = $i; + $c = $reduce($b->multiply($b)); + $t = $reduce($t->multiply($c)); + $r = $reduce($r->multiply($b)); + } + + return new static($this->instanceID, $r); + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value->isOdd(); + } + + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return static + */ + public function negate() + { + return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); + } + + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + if (isset(static::$modulo[$this->instanceID])) { + $length = static::$modulo[$this->instanceID]->getLengthInBytes(); + return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + } + return $this->value->toBytes(); + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return Strings::bin2hex($this->toBytes()); + } + + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + // return $this->value->toBits(); + static $length; + if (!isset($length)) { + $length = static::$modulo[$this->instanceID]->getLength(); + } + + return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT); + } + + /** + * Returns the w-ary non-adjacent form (wNAF) + * + * @param int $w optional + * @return array + */ + public function getNAF($w = 1) + { + $w++; + + $mask = new BigInteger((1 << $w) - 1); + $sub = new BigInteger(1 << $w); + //$sub = new BigInteger(1 << ($w - 1)); + $d = $this->toBigInteger(); + $d_i = []; + + $i = 0; + while ($d->compare(static::$zero[static::class]) > 0) { + if ($d->isOdd()) { + // start mods + + $bigInteger = $d->testBit($w - 1) ? + $d->bitwise_and($mask)->subtract($sub) : + //$sub->subtract($d->bitwise_and($mask)) : + $d->bitwise_and($mask); + // end mods + $d = $d->subtract($bigInteger); + $d_i[$i] = (int) $bigInteger->toString(); + } else { + $d_i[$i] = 0; + } + $shift = !$d->equals(static::$zero[static::class]) && $d->bitwise_and($mask)->equals(static::$zero[static::class]) ? $w : 1; // $w or $w + 1? + $d = $d->bitwise_rightShift($shift); + while (--$shift > 0) { + $d_i[++$i] = 0; + } + $i++; + } + + return $d_i; + } + + /** + * Converts an Integer to a BigInteger + * + * @return BigInteger + */ + public function toBigInteger() + { + return clone $this->value; + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return (string) $this->value; + } + + /** + * __debugInfo() magic method + * + * @return array + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php similarity index 58% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php index 0eec73870..cdf0bec69 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -14,7 +14,7 @@ * login('username', 'password')) { * exit('Login Failed'); * } @@ -25,63 +25,66 @@ * ?> * * - * @category Net - * @package SFTP * @author Jim Wigginton * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Net; +namespace phpseclib3\Net; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\FileNotFoundException; /** * Pure-PHP implementations of SFTP. * - * @package SFTP * @author Jim Wigginton - * @access public */ class SFTP extends SSH2 { /** * SFTP channel constant * - * \phpseclib\Net\SSH2::exec() uses 0 and \phpseclib\Net\SSH2::read() / \phpseclib\Net\SSH2::write() use 1. + * \phpseclib3\Net\SSH2::exec() uses 0 and \phpseclib3\Net\SSH2::read() / \phpseclib3\Net\SSH2::write() use 1. * - * @see \phpseclib\Net\SSH2::_send_channel_packet() - * @see \phpseclib\Net\SSH2::_get_channel_packet() - * @access private + * @see \phpseclib3\Net\SSH2::send_channel_packet() + * @see \phpseclib3\Net\SSH2::get_channel_packet() */ const CHANNEL = 0x100; - /**#@+ - * @access public - * @see \phpseclib\Net\SFTP::put() - */ /** * Reads data from a local file. + * + * @see \phpseclib3\Net\SFTP::put() */ const SOURCE_LOCAL_FILE = 1; /** * Reads data from a string. + * + * @see \phpseclib3\Net\SFTP::put() */ // this value isn't really used anymore but i'm keeping it reserved for historical reasons const SOURCE_STRING = 2; /** * Reads data from callback: * function callback($length) returns string to proceed, null for EOF + * + * @see \phpseclib3\Net\SFTP::put() */ const SOURCE_CALLBACK = 16; /** * Resumes an upload + * + * @see \phpseclib3\Net\SFTP::put() */ const RESUME = 4; /** * Append a local file to an already existing remote file + * + * @see \phpseclib3\Net\SFTP::put() */ const RESUME_START = 8; - /**#@-*/ /** * Packet Types @@ -90,7 +93,7 @@ class SFTP extends SSH2 * @var array * @access private */ - var $packet_types = array(); + private static $packet_types = []; /** * Status Codes @@ -99,7 +102,19 @@ class SFTP extends SSH2 * @var array * @access private */ - var $status_codes = array(); + private static $status_codes = []; + + /** @var array */ + private static $attributes; + + /** @var array */ + private static $open_flags; + + /** @var array */ + private static $open_flags5; + + /** @var array */ + private static $file_types; /** * The Request ID @@ -109,9 +124,8 @@ class SFTP extends SSH2 * * @var boolean * @see self::_send_sftp_packet() - * @access private */ - var $use_request_id = false; + private $use_request_id = false; /** * The Packet Type @@ -121,82 +135,106 @@ class SFTP extends SSH2 * * @var int * @see self::_get_sftp_packet() - * @access private */ - var $packet_type = -1; + private $packet_type = -1; /** * Packet Buffer * * @var string * @see self::_get_sftp_packet() - * @access private */ - var $packet_buffer = ''; + private $packet_buffer = ''; /** * Extensions supported by the server * * @var array * @see self::_initChannel() - * @access private */ - var $extensions = array(); + private $extensions = []; /** * Server SFTP version * * @var int * @see self::_initChannel() - * @access private */ - var $version; + private $version; /** * Default Server SFTP version * * @var int * @see self::_initChannel() - * @access private */ - var $defaultVersion; + private $defaultVersion; /** * Preferred SFTP version * * @var int * @see self::_initChannel() - * @access private */ - var $preferredVersion = 3; + private $preferredVersion = 3; /** * Current working directory * - * @var string + * @var string|bool * @see self::realpath() * @see self::chdir() - * @access private */ - var $pwd = false; + private $pwd = false; /** * Packet Type Log * * @see self::getLog() * @var array - * @access private */ - var $packet_type_log = array(); + private $packet_type_log = []; /** * Packet Log * * @see self::getLog() * @var array - * @access private */ - var $packet_log = array(); + private $packet_log = []; + + /** + * Real-time log file pointer + * + * @see self::_append_log() + * @var resource|closed-resource + */ + private $realtime_log_file; + + /** + * Real-time log file size + * + * @see self::_append_log() + * @var int + */ + private $realtime_log_size; + + /** + * Real-time log file wrap boolean + * + * @see self::_append_log() + * @var bool + */ + private $realtime_log_wrap; + + /** + * Current log size + * + * Should never exceed self::LOG_MAX_SIZE + * + * @var int + */ + private $log_size; /** * Error information @@ -204,9 +242,8 @@ class SFTP extends SSH2 * @see self::getSFTPErrors() * @see self::getLastSFTPError() * @var array - * @access private */ - var $sftp_errors = array(); + private $sftp_errors = []; /** * Stat Cache @@ -218,19 +255,17 @@ class SFTP extends SSH2 * @see self::_remove_from_stat_cache() * @see self::_query_stat_cache() * @var array - * @access private */ - var $stat_cache = array(); + private $stat_cache = []; /** * Max SFTP Packet Size * * @see self::__construct() * @see self::get() - * @var array - * @access private + * @var int */ - var $max_sftp_packet; + private $max_sftp_packet; /** * Stat Cache Flag @@ -238,9 +273,8 @@ class SFTP extends SSH2 * @see self::disableStatCache() * @see self::enableStatCache() * @var bool - * @access private */ - var $use_stat_cache = true; + private $use_stat_cache = true; /** * Sort Options @@ -248,9 +282,8 @@ class SFTP extends SSH2 * @see self::_comparator() * @see self::setListOrder() * @var array - * @access private */ - var $sortOptions = array(); + protected $sortOptions = []; /** * Canonicalization Flag @@ -262,18 +295,16 @@ class SFTP extends SSH2 * @see self::disablePathCanonicalization() * @see self::realpath() * @var bool - * @access private */ - var $canonicalize_paths = true; + private $canonicalize_paths = true; /** * Request Buffers * * @see self::_get_sftp_packet() * @var array - * @access private */ - var $requestBuffer = array(); + private $requestBuffer = []; /** * Preserve timestamps on file downloads / uploads @@ -281,9 +312,8 @@ class SFTP extends SSH2 * @see self::get() * @see self::put() * @var bool - * @access private */ - var $preserveTime = false; + private $preserveTime = false; /** * Arbitrary Length Packets Flag @@ -296,9 +326,8 @@ class SFTP extends SSH2 * @see self::enableArbitraryLengthPackets() * @see self::_get_sftp_packet() * @var bool - * @access private */ - var $allow_arbitrary_length_packets = false; + private $allow_arbitrary_length_packets = false; /** * Was the last packet due to the channels being closed or not? @@ -306,180 +335,183 @@ class SFTP extends SSH2 * @see self::get() * @see self::get_sftp_packet() * @var bool - * @access private */ - var $channel_close = false; + private $channel_close = false; /** * Has the SFTP channel been partially negotiated? * * @var bool - * @access private */ - var $partial_init = false; + private $partial_init = false; /** * Default Constructor. * * Connects to an SFTP server * - * @param string $host + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host * @param int $port * @param int $timeout - * @return \phpseclib\Net\SFTP - * @access public */ - function __construct($host, $port = 22, $timeout = 10) + public function __construct($host, $port = 22, $timeout = 10) { parent::__construct($host, $port, $timeout); $this->max_sftp_packet = 1 << 15; - $this->packet_types = array( - 1 => 'NET_SFTP_INIT', - 2 => 'NET_SFTP_VERSION', - 3 => 'NET_SFTP_OPEN', - 4 => 'NET_SFTP_CLOSE', - 5 => 'NET_SFTP_READ', - 6 => 'NET_SFTP_WRITE', - 7 => 'NET_SFTP_LSTAT', - 9 => 'NET_SFTP_SETSTAT', - 10 => 'NET_SFTP_FSETSTAT', - 11 => 'NET_SFTP_OPENDIR', - 12 => 'NET_SFTP_READDIR', - 13 => 'NET_SFTP_REMOVE', - 14 => 'NET_SFTP_MKDIR', - 15 => 'NET_SFTP_RMDIR', - 16 => 'NET_SFTP_REALPATH', - 17 => 'NET_SFTP_STAT', - 18 => 'NET_SFTP_RENAME', - 19 => 'NET_SFTP_READLINK', - 20 => 'NET_SFTP_SYMLINK', - 21 => 'NET_SFTP_LINK', + if (empty(self::$packet_types)) { + self::$packet_types = [ + 1 => 'NET_SFTP_INIT', + 2 => 'NET_SFTP_VERSION', + 3 => 'NET_SFTP_OPEN', + 4 => 'NET_SFTP_CLOSE', + 5 => 'NET_SFTP_READ', + 6 => 'NET_SFTP_WRITE', + 7 => 'NET_SFTP_LSTAT', + 9 => 'NET_SFTP_SETSTAT', + 10 => 'NET_SFTP_FSETSTAT', + 11 => 'NET_SFTP_OPENDIR', + 12 => 'NET_SFTP_READDIR', + 13 => 'NET_SFTP_REMOVE', + 14 => 'NET_SFTP_MKDIR', + 15 => 'NET_SFTP_RMDIR', + 16 => 'NET_SFTP_REALPATH', + 17 => 'NET_SFTP_STAT', + 18 => 'NET_SFTP_RENAME', + 19 => 'NET_SFTP_READLINK', + 20 => 'NET_SFTP_SYMLINK', + 21 => 'NET_SFTP_LINK', - 101=> 'NET_SFTP_STATUS', - 102=> 'NET_SFTP_HANDLE', - 103=> 'NET_SFTP_DATA', - 104=> 'NET_SFTP_NAME', - 105=> 'NET_SFTP_ATTRS', + 101 => 'NET_SFTP_STATUS', + 102 => 'NET_SFTP_HANDLE', + 103 => 'NET_SFTP_DATA', + 104 => 'NET_SFTP_NAME', + 105 => 'NET_SFTP_ATTRS', - 200=> 'NET_SFTP_EXTENDED' - ); - $this->status_codes = array( - 0 => 'NET_SFTP_STATUS_OK', - 1 => 'NET_SFTP_STATUS_EOF', - 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', - 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', - 4 => 'NET_SFTP_STATUS_FAILURE', - 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', - 6 => 'NET_SFTP_STATUS_NO_CONNECTION', - 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', - 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', - 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', - 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', - 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', - 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', - 13 => 'NET_SFTP_STATUS_NO_MEDIA', - 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', - 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', - 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', - 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', - 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', - 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', - 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', - 21 => 'NET_SFTP_STATUS_LINK_LOOP', - 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', - 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', - 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', - 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', - 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', - 27 => 'NET_SFTP_STATUS_DELETE_PENDING', - 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', - 29 => 'NET_SFTP_STATUS_OWNER_INVALID', - 30 => 'NET_SFTP_STATUS_GROUP_INVALID', - 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' - ); - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 - // the order, in this case, matters quite a lot - see \phpseclib\Net\SFTP::_parseAttributes() to understand why - $this->attributes = array( - 0x00000001 => 'NET_SFTP_ATTR_SIZE', - 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ - 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ - 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', - 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', - 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ - 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', - 0x00000040 => 'NET_SFTP_ATTR_ACL', - 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', - 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ - 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ - 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', - 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', - 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', - 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', - 0x00008000 => 'NET_SFTP_ATTR_CTIME', - // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers - // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in - // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. - // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. - (-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED' - ); - $this->open_flags = array( - 0x00000001 => 'NET_SFTP_OPEN_READ', - 0x00000002 => 'NET_SFTP_OPEN_WRITE', - 0x00000004 => 'NET_SFTP_OPEN_APPEND', - 0x00000008 => 'NET_SFTP_OPEN_CREATE', - 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', - 0x00000020 => 'NET_SFTP_OPEN_EXCL', - 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 - ); - // SFTPv5+ changed the flags up: - // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 - $this->open_flags5 = array( - // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened - 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', - 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', - 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', - 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', - 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', - // the rest of the flags are not supported - 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" - 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', - 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', - 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', - 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', - 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', - 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', - 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', - 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', - 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', - 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', - 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', - 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', - ); - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 - // see \phpseclib\Net\SFTP::_parseLongname() for an explanation - $this->file_types = array( - 1 => 'NET_SFTP_TYPE_REGULAR', - 2 => 'NET_SFTP_TYPE_DIRECTORY', - 3 => 'NET_SFTP_TYPE_SYMLINK', - 4 => 'NET_SFTP_TYPE_SPECIAL', - 5 => 'NET_SFTP_TYPE_UNKNOWN', - // the followin types were first defined for use in SFTPv5+ - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 - 6 => 'NET_SFTP_TYPE_SOCKET', - 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', - 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', - 9 => 'NET_SFTP_TYPE_FIFO' - ); - $this->_define_array( - $this->packet_types, - $this->status_codes, - $this->attributes, - $this->open_flags, - $this->open_flags5, - $this->file_types - ); + 200 => 'NET_SFTP_EXTENDED' + ]; + self::$status_codes = [ + 0 => 'NET_SFTP_STATUS_OK', + 1 => 'NET_SFTP_STATUS_EOF', + 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', + 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', + 4 => 'NET_SFTP_STATUS_FAILURE', + 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', + 6 => 'NET_SFTP_STATUS_NO_CONNECTION', + 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', + 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', + 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', + 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', + 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', + 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', + 13 => 'NET_SFTP_STATUS_NO_MEDIA', + 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', + 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', + 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', + 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', + 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', + 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', + 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', + 21 => 'NET_SFTP_STATUS_LINK_LOOP', + 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', + 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', + 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', + 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', + 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', + 27 => 'NET_SFTP_STATUS_DELETE_PENDING', + 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', + 29 => 'NET_SFTP_STATUS_OWNER_INVALID', + 30 => 'NET_SFTP_STATUS_GROUP_INVALID', + 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 + // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why + self::$attributes = [ + 0x00000001 => 'NET_SFTP_ATTR_SIZE', + 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ + 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ + 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', + 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', + 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ + 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', + 0x00000040 => 'NET_SFTP_ATTR_ACL', + 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', + 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ + 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ + 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', + 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', + 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', + 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', + 0x00008000 => 'NET_SFTP_ATTR_CTIME', + // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers + // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in + // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. + // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. + (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 + // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name + // the array for that $this->open5_flags and similarly alter the constant names. + self::$open_flags = [ + 0x00000001 => 'NET_SFTP_OPEN_READ', + 0x00000002 => 'NET_SFTP_OPEN_WRITE', + 0x00000004 => 'NET_SFTP_OPEN_APPEND', + 0x00000008 => 'NET_SFTP_OPEN_CREATE', + 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', + 0x00000020 => 'NET_SFTP_OPEN_EXCL', + 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 + ]; + // SFTPv5+ changed the flags up: + // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 + self::$open_flags5 = [ + // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened + 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', + 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', + 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', + 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', + 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', + // the rest of the flags are not supported + 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" + 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', + 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', + 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', + 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', + 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', + 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', + 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', + 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', + 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', + 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', + 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', + 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 + // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation + self::$file_types = [ + 1 => 'NET_SFTP_TYPE_REGULAR', + 2 => 'NET_SFTP_TYPE_DIRECTORY', + 3 => 'NET_SFTP_TYPE_SYMLINK', + 4 => 'NET_SFTP_TYPE_SPECIAL', + 5 => 'NET_SFTP_TYPE_UNKNOWN', + // the following types were first defined for use in SFTPv5+ + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 + 6 => 'NET_SFTP_TYPE_SOCKET', + 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', + 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', + 9 => 'NET_SFTP_TYPE_FIFO' + ]; + self::define_array( + self::$packet_types, + self::$status_codes, + self::$attributes, + self::$open_flags, + self::$open_flags5, + self::$file_types + ); + } if (!defined('NET_SFTP_QUEUE_SIZE')) { define('NET_SFTP_QUEUE_SIZE', 32); @@ -493,16 +525,15 @@ class SFTP extends SSH2 * Check a few things before SFTP functions are called * * @return bool - * @access public */ - function _precheck() + private function precheck() { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } if ($this->pwd === false) { - return $this->_init_sftp_connection(); + return $this->init_sftp_connection(); } return true; @@ -511,53 +542,29 @@ class SFTP extends SSH2 /** * Partially initialize an SFTP connection * + * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool - * @access public */ - function _partial_init_sftp_connection() + private function partial_init_sftp_connection() { - $this->window_size_server_to_client[self::CHANNEL] = $this->window_size; - - $packet = pack( - 'CNa*N3', - NET_SSH2_MSG_CHANNEL_OPEN, - strlen('session'), - 'session', - self::CHANNEL, - $this->window_size, - 0x4000 - ); - - if (!$this->_send_binary_packet($packet)) { + $response = $this->openChannel(self::CHANNEL, true); + if ($response === true && $this->isTimeout()) { return false; } - $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = $this->_get_channel_packet(self::CHANNEL, true); - if ($response === false) { - return false; - } elseif ($response === true && $this->isTimeout()) { - return false; - } - - $packet = pack( - 'CNNa*CNa*', + $packet = Strings::packSSH2( + 'CNsbs', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], - strlen('subsystem'), 'subsystem', - 1, - strlen('sftp'), + true, 'sftp' ); - if (!$this->_send_binary_packet($packet)) { - return false; - } + $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->_get_channel_packet(self::CHANNEL, true); + $response = $this->get_channel_packet(self::CHANNEL, true); if ($response === false) { // from PuTTY's psftp.exe $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . @@ -565,23 +572,19 @@ class SFTP extends SSH2 "exec sftp-server"; // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does // is redundant - $packet = pack( - 'CNNa*CNa*', + $packet = Strings::packSSH2( + 'CNsCs', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], - strlen('exec'), 'exec', 1, - strlen($command), $command ); - if (!$this->_send_binary_packet($packet)) { - return false; - } + $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; - $response = $this->_get_channel_packet(self::CHANNEL, true); + $response = $this->get_channel_packet(self::CHANNEL, true); if ($response === false) { return false; } @@ -590,35 +593,19 @@ class SFTP extends SSH2 } $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; + $this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3"); - if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) { - return false; - } - - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_VERSION) { - user_error('Expected SSH_FXP_VERSION'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_VERSION. ' + . 'Got packet type: ' . $this->packet_type); } $this->use_request_id = true; - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nversion', $this->_string_shift($response, 4))); - $this->defaultVersion = $version; + list($this->defaultVersion) = Strings::unpackSSH2('N', $response); while (!empty($response)) { - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $key = $this->_string_shift($response, $length); - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $value = $this->_string_shift($response, $length); + list($key, $value) = Strings::unpackSSH2('ss', $response); $this->extensions[$key] = $value; } @@ -631,11 +618,10 @@ class SFTP extends SSH2 * (Re)initializes the SFTP channel * * @return bool - * @access private */ - function _init_sftp_connection() + private function init_sftp_connection() { - if (!$this->partial_init && !$this->_partial_init_sftp_connection()) { + if (!$this->partial_init && !$this->partial_init_sftp_connection()) { return false; } @@ -659,15 +645,15 @@ class SFTP extends SSH2 So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed - in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib\Net\SFTP would do is close the + in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the channel and reopen it with a new and updated SSH_FXP_INIT packet. */ $this->version = $this->defaultVersion; if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) { $versions = explode(',', $this->extensions['versions']); - $supported = array(6, 5, 4); + $supported = [6, 5, 4]; if ($this->preferredVersion) { - $supported = array_diff($supported, array($this->preferredVersion)); + $supported = array_diff($supported, [$this->preferredVersion]); array_unshift($supported, $this->preferredVersion); } foreach ($supported as $ver) { @@ -676,25 +662,19 @@ class SFTP extends SSH2 break; } $this->version = (int) $ver; - $packet = pack('Na*Na*', strlen('version-select'), 'version-select', strlen($ver), $ver); - if (!$this->_send_sftp_packet(NET_SFTP_EXTENDED, $packet)) { - return false; - } - $response = $this->_get_sftp_packet(); + $packet = Strings::packSSH2('ss', 'version-select', "$ver"); + $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); - return false; + $this->logError($response, $status); + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS_OK. ' + . ' Got ' . $status); } - break; } } @@ -713,14 +693,22 @@ class SFTP extends SSH2 unset($this->extensions['newline@vandyke.com']); } */ - if ($this->version < 2 || $this->version > 6) { return false; } - $this->pwd = $this->_realpath('.'); + $this->pwd = true; + try { + $this->pwd = $this->realpath('.'); + } catch (\UnexpectedValueException $e) { + if (!$this->canonicalize_paths) { + throw $e; + } + $this->canonicalize_paths = false; + $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); + } - $this->_update_stat_cache($this->pwd, array()); + $this->update_stat_cache($this->pwd, []); return true; } @@ -728,9 +716,8 @@ class SFTP extends SSH2 /** * Disable the stat cache * - * @access public */ - function disableStatCache() + public function disableStatCache() { $this->use_stat_cache = false; } @@ -738,9 +725,8 @@ class SFTP extends SSH2 /** * Enable the stat cache * - * @access public */ - function enableStatCache() + public function enableStatCache() { $this->use_stat_cache = true; } @@ -748,29 +734,28 @@ class SFTP extends SSH2 /** * Clear the stat cache * - * @access public */ - function clearStatCache() + public function clearStatCache() { - $this->stat_cache = array(); + $this->stat_cache = []; } /** * Enable path canonicalization * - * @access public */ - function enablePathCanonicalization() + public function enablePathCanonicalization() { $this->canonicalize_paths = true; } /** - * Enable path canonicalization + * Disable path canonicalization + * + * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path * - * @access public */ - function disablePathCanonicalization() + public function disablePathCanonicalization() { $this->canonicalize_paths = false; } @@ -778,9 +763,8 @@ class SFTP extends SSH2 /** * Enable arbitrary length packets * - * @access public */ - function enableArbitraryLengthPackets() + public function enableArbitraryLengthPackets() { $this->allow_arbitrary_length_packets = true; } @@ -788,9 +772,8 @@ class SFTP extends SSH2 /** * Disable arbitrary length packets * - * @access public */ - function disableArbitraryLengthPackets() + public function disableArbitraryLengthPackets() { $this->allow_arbitrary_length_packets = false; } @@ -798,12 +781,11 @@ class SFTP extends SSH2 /** * Returns the current directory name * - * @return mixed - * @access public + * @return string|bool */ - function pwd() + public function pwd() { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } @@ -815,46 +797,23 @@ class SFTP extends SSH2 * * @param string $response * @param int $status - * @access public */ - function _logError($response, $status = -1) + private function logError($response, $status = -1) { if ($status == -1) { - if (strlen($response) < 4) { - return; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); } - $error = $this->status_codes[$status]; + $error = self::$status_codes[$status]; - if ($this->version > 2 || strlen($response) < 4) { - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length); + if ($this->version > 2) { + list($message) = Strings::unpackSSH2('s', $response); + $this->sftp_errors[] = "$error: $message"; } else { $this->sftp_errors[] = $error; } } - /** - * Returns canonicalized absolute pathname - * - * realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input - * path and returns the canonicalized absolute pathname. - * - * @param string $path - * @return mixed - * @access public - */ - function realpath($path) - { - if (!$this->_precheck()) { - return false; - } - - return $this->_realpath($path); - } - /** * Canonicalize the Server-Side Path Name * @@ -866,39 +825,62 @@ class SFTP extends SSH2 * @see self::chdir() * @see self::disablePathCanonicalization() * @param string $path + * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed - * @access private */ - function _realpath($path) + public function realpath($path) { - if (!$this->canonicalize_paths) { - return $path; + if ($this->precheck() === false) { + return false; } - if ($this->pwd === false) { - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 - if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) { - return false; + if (!$this->canonicalize_paths) { + if ($this->pwd === true) { + return '.'; } + if (!strlen($path) || $path[0] != '/') { + $path = $this->pwd . '/' . $path; + } + $parts = explode('/', $path); + $afterPWD = $beforePWD = []; + foreach ($parts as $part) { + switch ($part) { + //case '': // some SFTP servers /require/ double /'s. see https://github.com/phpseclib/phpseclib/pull/1137 + case '.': + break; + case '..': + if (!empty($afterPWD)) { + array_pop($afterPWD); + } else { + $beforePWD[] = '..'; + } + break; + default: + $afterPWD[] = $part; + } + } + $beforePWD = count($beforePWD) ? implode('/', $beforePWD) : '.'; + return $beforePWD . '/' . implode('/', $afterPWD); + } - $response = $this->_get_sftp_packet(); + if ($this->pwd === true) { + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 + $this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path)); + + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks // at is the first part and that part is defined the same in SFTP versions 3 through 6. - $this->_string_shift($response, 4); // skip over the count - it should be 1, anyway - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - return $this->_string_shift($response, $length); + list(, $filename) = Strings::unpackSSH2('Ns', $response); + return $filename; case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); return false; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } } @@ -907,7 +889,7 @@ class SFTP extends SSH2 } $path = explode('/', $path); - $new = array(); + $new = []; foreach ($path as $dir) { if (!strlen($dir)) { continue; @@ -915,6 +897,7 @@ class SFTP extends SSH2 switch ($dir) { case '..': array_pop($new); + // fall-through case '.': break; default: @@ -929,12 +912,12 @@ class SFTP extends SSH2 * Changes the current directory * * @param string $dir + * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool - * @access public */ - function chdir($dir) + public function chdir($dir) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } @@ -943,13 +926,13 @@ class SFTP extends SSH2 $dir = './'; // suffix a slash if needed } elseif ($dir[strlen($dir) - 1] != '/') { - $dir.= '/'; + $dir .= '/'; } - $dir = $this->_realpath($dir); + $dir = $this->realpath($dir); // confirm that $dir is, in fact, a valid directory - if ($this->use_stat_cache && is_array($this->_query_stat_cache($dir))) { + if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) { $this->pwd = $dir; return true; } @@ -959,29 +942,27 @@ class SFTP extends SSH2 // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy // way to get those with SFTP - if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); - // see \phpseclib\Net\SFTP::nlist() for a more thorough explanation of the following - $response = $this->_get_sftp_packet(); + // see \phpseclib3\Net\SFTP::nlist() for a more thorough explanation of the following + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS' . + 'Got packet type: ' . $this->packet_type); } - if (!$this->_close_handle($handle)) { + if (!$this->close_handle($handle)) { return false; } - $this->_update_stat_cache($dir, array()); + $this->update_stat_cache($dir, []); $this->pwd = $dir; return true; @@ -992,12 +973,11 @@ class SFTP extends SSH2 * * @param string $dir * @param bool $recursive - * @return mixed - * @access public + * @return array|false */ - function nlist($dir = '.', $recursive = false) + public function nlist($dir = '.', $recursive = false) { - return $this->_nlist_helper($dir, $recursive, ''); + return $this->nlist_helper($dir, $recursive, ''); } /** @@ -1006,28 +986,31 @@ class SFTP extends SSH2 * @param string $dir * @param bool $recursive * @param string $relativeDir - * @return mixed - * @access private + * @return array|false */ - function _nlist_helper($dir, $recursive, $relativeDir) + private function nlist_helper($dir, $recursive, $relativeDir) { - $files = $this->_list($dir, false); + $files = $this->readlist($dir, false); + + // If we get an int back, then that is an "unexpected" status. + // We do not have a file list, so return false. + if (is_int($files)) { + return false; + } if (!$recursive || $files === false) { return $files; } - $result = array(); + $result = []; foreach ($files as $value) { if ($value == '.' || $value == '..') { - if ($relativeDir == '') { - $result[] = $value; - } + $result[] = $relativeDir . $value; continue; } - if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) { - $temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); - $temp = is_array($temp) ? $temp : array(); + if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) { + $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); + $temp = is_array($temp) ? $temp : []; $result = array_merge($result, $temp); } else { $result[] = $relativeDir . $value; @@ -1042,12 +1025,18 @@ class SFTP extends SSH2 * * @param string $dir * @param bool $recursive - * @return mixed - * @access public + * @return array|false */ - function rawlist($dir = '.', $recursive = false) + public function rawlist($dir = '.', $recursive = false) { - $files = $this->_list($dir, true); + $files = $this->readlist($dir, true); + + // If we get an int back, then that is an "unexpected" status. + // We do not have a file list, so return false. + if (is_int($files)) { + return false; + } + if (!$recursive || $files === false) { return $files; } @@ -1062,7 +1051,7 @@ class SFTP extends SSH2 $is_directory = false; if ($key != '.' && $key != '..') { if ($this->use_stat_cache) { - $is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key))); + $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key))); } else { $stat = $this->lstat($dir . '/' . $key); $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY; @@ -1086,26 +1075,24 @@ class SFTP extends SSH2 * * @param string $dir * @param bool $raw - * @return mixed - * @access private + * @return array|false + * @throws \UnexpectedValueException on receipt of unexpected packets */ - function _list($dir, $raw = true) + private function readlist($dir, $raw = true) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $dir = $this->_realpath($dir . '/'); + $dir = $this->realpath($dir . '/'); if ($dir === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2 - if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2 @@ -1115,91 +1102,76 @@ class SFTP extends SSH2 break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - $this->_logError($response); - return false; + list($status) = Strings::unpackSSH2('N', $response); + $this->logError($response, $status); + return $status; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - $this->_update_stat_cache($dir, array()); + $this->update_stat_cache($dir, []); - $contents = array(); + $contents = []; while (true) { // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2 // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many // SSH_MSG_CHANNEL_DATA messages is not known to me. - if (!$this->_send_sftp_packet(NET_SFTP_READDIR, pack('Na*', strlen($handle), $handle))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle)); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: - if (strlen($response) < 4) { - return false; - } - extract(unpack('Ncount', $this->_string_shift($response, 4))); + list($count) = Strings::unpackSSH2('N', $response); for ($i = 0; $i < $count; $i++) { - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $shortname = $this->_string_shift($response, $length); + list($shortname) = Strings::unpackSSH2('s', $response); // SFTPv4 "removed the long filename from the names structure-- it can now be // built from information available in the attrs structure." if ($this->version < 4) { - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $longname = $this->_string_shift($response, $length); + list($longname) = Strings::unpackSSH2('s', $response); } - $attributes = $this->_parseAttributes($response); + $attributes = $this->parseAttributes($response); if (!isset($attributes['type']) && $this->version < 4) { - $fileType = $this->_parseLongname($longname); + $fileType = $this->parseLongname($longname); if ($fileType) { $attributes['type'] = $fileType; } } - $contents[$shortname] = $attributes + array('filename' => $shortname); + $contents[$shortname] = $attributes + ['filename' => $shortname]; if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) { - $this->_update_stat_cache($dir . '/' . $shortname, array()); + $this->update_stat_cache($dir . '/' . $shortname, []); } else { if ($shortname == '..') { - $temp = $this->_realpath($dir . '/..') . '/.'; + $temp = $this->realpath($dir . '/..') . '/.'; } else { $temp = $dir . '/' . $shortname; } - $this->_update_stat_cache($temp, (object) array('lstat' => $attributes)); + $this->update_stat_cache($temp, (object) ['lstat' => $attributes]); } // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the // final SSH_FXP_STATUS packet should tell us that, already. } break; case NET_SFTP_STATUS: - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_EOF) { - $this->_logError($response, $status); - return false; + $this->logError($response, $status); + return $status; } break 2; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } } - if (!$this->_close_handle($handle)) { + if (!$this->close_handle($handle)) { return false; } if (count($this->sortOptions)) { - uasort($contents, array(&$this, '_comparator')); + uasort($contents, [&$this, 'comparator']); } return $raw ? $contents : array_map('strval', array_keys($contents)); @@ -1213,9 +1185,8 @@ class SFTP extends SSH2 * @param array $a * @param array $b * @return int - * @access private */ - function _comparator($a, $b) + private function comparator(array $a, array $b) { switch (true) { case $a['filename'] === '.' || $b['filename'] === '.': @@ -1256,10 +1227,10 @@ class SFTP extends SSH2 return $order === SORT_DESC ? -$result : $result; } break; - case 'permissions': case 'mode': - $a[$sort]&= 07777; - $b[$sort]&= 07777; + $a[$sort] &= 07777; + $b[$sort] &= 07777; + // fall-through default: if ($a[$sort] === $b[$sort]) { break; @@ -1287,50 +1258,30 @@ class SFTP extends SSH2 * $sftp->setListOrder(); * Don't do any sort of sorting * - * @access public + * @param string ...$args */ - function setListOrder() + public function setListOrder(...$args) { - $this->sortOptions = array(); - $args = func_get_args(); + $this->sortOptions = []; if (empty($args)) { return; } $len = count($args) & 0x7FFFFFFE; - for ($i = 0; $i < $len; $i+=2) { + for ($i = 0; $i < $len; $i += 2) { $this->sortOptions[$args[$i]] = $args[$i + 1]; } if (!count($this->sortOptions)) { - $this->sortOptions = array('bogus' => true); + $this->sortOptions = ['bogus' => true]; } } - /** - * Returns the file size, in bytes, or false, on failure - * - * Files larger than 4GB will show up as being exactly 4GB. - * - * @param string $filename - * @return mixed - * @access public - */ - function size($filename) - { - $result = $this->stat($filename); - if ($result === false) { - return false; - } - return isset($result['size']) ? $result['size'] : -1; - } - /** * Save files / directories to cache * * @param string $path * @param mixed $value - * @access private */ - function _update_stat_cache($path, $value) + private function update_stat_cache($path, $value) { if ($this->use_stat_cache === false) { return; @@ -1346,10 +1297,10 @@ class SFTP extends SSH2 // 1. a file was deleted and changed to a directory behind phpseclib's back // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to if (is_object($temp)) { - $temp = array(); + $temp = []; } if (!isset($temp[$dir])) { - $temp[$dir] = array(); + $temp[$dir] = []; } if ($i === $max) { if (is_object($temp[$dir]) && is_object($value)) { @@ -1372,9 +1323,8 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access private */ - function _remove_from_stat_cache($path) + private function remove_from_stat_cache($path) { $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); @@ -1402,9 +1352,8 @@ class SFTP extends SSH2 * * @param string $path * @return mixed - * @access private */ - function _query_stat_cache($path) + private function query_stat_cache($path) { $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); @@ -1427,22 +1376,21 @@ class SFTP extends SSH2 * Returns an array on success and false otherwise. * * @param string $filename - * @return mixed - * @access public + * @return array|false */ - function stat($filename) + public function stat($filename) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $filename = $this->_realpath($filename); + $filename = $this->realpath($filename); if ($filename === false) { return false; } if ($this->use_stat_cache) { - $result = $this->_query_stat_cache($filename); + $result = $this->query_stat_cache($filename); if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) { return $result['.']->stat; } @@ -1451,16 +1399,16 @@ class SFTP extends SSH2 } } - $stat = $this->_stat($filename, NET_SFTP_STAT); + $stat = $this->stat_helper($filename, NET_SFTP_STAT); if ($stat === false) { - $this->_remove_from_stat_cache($filename); + $this->remove_from_stat_cache($filename); return false; } if (isset($stat['type'])) { if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename.= '/.'; + $filename .= '/.'; } - $this->_update_stat_cache($filename, (object) array('stat' => $stat)); + $this->update_stat_cache($filename, (object) ['stat' => $stat]); return $stat; } @@ -1471,9 +1419,9 @@ class SFTP extends SSH2 $this->pwd = $pwd; if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename.= '/.'; + $filename .= '/.'; } - $this->_update_stat_cache($filename, (object) array('stat' => $stat)); + $this->update_stat_cache($filename, (object) ['stat' => $stat]); return $stat; } @@ -1484,22 +1432,21 @@ class SFTP extends SSH2 * Returns an array on success and false otherwise. * * @param string $filename - * @return mixed - * @access public + * @return array|false */ - function lstat($filename) + public function lstat($filename) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $filename = $this->_realpath($filename); + $filename = $this->realpath($filename); if ($filename === false) { return false; } if ($this->use_stat_cache) { - $result = $this->_query_stat_cache($filename); + $result = $this->query_stat_cache($filename); if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) { return $result['.']->lstat; } @@ -1508,24 +1455,24 @@ class SFTP extends SSH2 } } - $lstat = $this->_stat($filename, NET_SFTP_LSTAT); + $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT); if ($lstat === false) { - $this->_remove_from_stat_cache($filename); + $this->remove_from_stat_cache($filename); return false; } if (isset($lstat['type'])) { if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename.= '/.'; + $filename .= '/.'; } - $this->_update_stat_cache($filename, (object) array('lstat' => $lstat)); + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); return $lstat; } - $stat = $this->_stat($filename, NET_SFTP_STAT); + $stat = $this->stat_helper($filename, NET_SFTP_STAT); if ($lstat != $stat) { - $lstat = array_merge($lstat, array('type' => NET_SFTP_TYPE_SYMLINK)); - $this->_update_stat_cache($filename, (object) array('lstat' => $lstat)); + $lstat = array_merge($lstat, ['type' => NET_SFTP_TYPE_SYMLINK]); + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); return $stat; } @@ -1536,9 +1483,9 @@ class SFTP extends SSH2 $this->pwd = $pwd; if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename.= '/.'; + $filename .= '/.'; } - $this->_update_stat_cache($filename, (object) array('lstat' => $lstat)); + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); return $lstat; } @@ -1546,33 +1493,31 @@ class SFTP extends SSH2 /** * Returns general information about a file or symbolic link * - * Determines information without calling \phpseclib\Net\SFTP::realpath(). + * Determines information without calling \phpseclib3\Net\SFTP::realpath(). * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. * * @param string $filename * @param int $type - * @return mixed - * @access private + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return array|false */ - function _stat($filename, $type) + private function stat_helper($filename, $type) { // SFTPv4+ adds an additional 32-bit integer field - flags - to the following: - $packet = pack('Na*', strlen($filename), $filename); - if (!$this->_send_sftp_packet($type, $packet)) { - return false; - } + $packet = Strings::packSSH2('s', $filename); + $this->send_sftp_packet($type, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_ATTRS: - return $this->_parseAttributes($response); + return $this->parseAttributes($response); case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); return false; } - user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } /** @@ -1581,13 +1526,12 @@ class SFTP extends SSH2 * @param string $filename * @param int $new_size * @return bool - * @access public */ - function truncate($filename, $new_size) + public function truncate($filename, $new_size) { - $attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); // 4294967296 == 0x100000000 == 1<<32 + $attr = Strings::packSSH2('NQ', NET_SFTP_ATTR_SIZE, $new_size); - return $this->_setstat($filename, $attr, false); + return $this->setstat($filename, $attr, false); } /** @@ -1598,16 +1542,16 @@ class SFTP extends SSH2 * @param string $filename * @param int $time * @param int $atime + * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool - * @access public */ - function touch($filename, $time = null, $atime = null) + public function touch($filename, $time = null, $atime = null) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $filename = $this->_realpath($filename); + $filename = $this->realpath($filename); if ($filename === false) { return false; } @@ -1619,42 +1563,31 @@ class SFTP extends SSH2 $atime = $time; } - if ($this->version < 4) { - $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $atime, $time); - } else { - $attr = pack( - 'N5', - NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, - $atime / 4294967296, - $atime, - $time / 4294967296, - $time - ); - } + $attr = $this->version < 4 ? + pack('N3', NET_SFTP_ATTR_ACCESSTIME, $atime, $time) : + Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $atime, $time); - $packet = pack('Na*', strlen($filename), $filename); - $packet.= $this->version >= 5 ? + $packet = Strings::packSSH2('s', $filename); + $packet .= $this->version >= 5 ? pack('N2', 0, NET_SFTP_OPEN_OPEN_EXISTING) : pack('N', NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL); - $packet.= $attr; + $packet .= $attr; - if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { - return false; - } + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: - return $this->_close_handle(substr($response, 4)); + return $this->close_handle(substr($response, 4)); case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); break; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - return $this->_setstat($filename, $attr, false); + return $this->setstat($filename, $attr, false); } /** @@ -1671,9 +1604,8 @@ class SFTP extends SSH2 * @param int|string $uid * @param bool $recursive * @return bool - * @access public */ - function chown($filename, $uid, $recursive = false) + public function chown($filename, $uid, $recursive = false) { /* quoting , @@ -1700,9 +1632,9 @@ class SFTP extends SSH2 // "If either the owner or group field is zero length, the field should be // considered absent, and no change should be made to that specific field // during a modification operation" - pack('NNa*Na*', NET_SFTP_ATTR_OWNERGROUP, strlen($uid), $uid, 0, ''); + Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, $uid, ''); - return $this->_setstat($filename, $attr, $recursive); + return $this->setstat($filename, $attr, $recursive); } /** @@ -1719,15 +1651,14 @@ class SFTP extends SSH2 * @param int|string $gid * @param bool $recursive * @return bool - * @access public */ - function chgrp($filename, $gid, $recursive = false) + public function chgrp($filename, $gid, $recursive = false) { $attr = $this->version < 4 ? - pack('N3', NET_SFTP_ATTR_UIDGID, $gid, -1) : - pack('NNa*Na*', NET_SFTP_ATTR_OWNERGROUP, 0, '', strlen($gid), $gid); + pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) : + Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, '', $gid); - return $this->_setstat($filename, $attr, $recursive); + return $this->setstat($filename, $attr, $recursive); } /** @@ -1739,10 +1670,10 @@ class SFTP extends SSH2 * @param int $mode * @param string $filename * @param bool $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed - * @access public */ - function chmod($mode, $filename, $recursive = false) + public function chmod($mode, $filename, $recursive = false) { if (is_string($mode) && is_int($filename)) { $temp = $mode; @@ -1751,7 +1682,7 @@ class SFTP extends SSH2 } $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777); - if (!$this->_setstat($filename, $attr, $recursive)) { + if (!$this->setstat($filename, $attr, $recursive)) { return false; } if ($recursive) { @@ -1763,22 +1694,20 @@ class SFTP extends SSH2 // tell us if the file actually exists. // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following: $packet = pack('Na*', strlen($filename), $filename); - if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) { - return false; - } + $this->send_sftp_packet(NET_SFTP_STAT, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_ATTRS: - $attrs = $this->_parseAttributes($response); - return $attrs['permissions']; + $attrs = $this->parseAttributes($response); + return $attrs['mode']; case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); return false; } - user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } /** @@ -1787,35 +1716,34 @@ class SFTP extends SSH2 * @param string $filename * @param string $attr * @param bool $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool - * @access private */ - function _setstat($filename, $attr, $recursive) + private function setstat($filename, $attr, $recursive) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $filename = $this->_realpath($filename); + $filename = $this->realpath($filename); if ($filename === false) { return false; } - $this->_remove_from_stat_cache($filename); + $this->remove_from_stat_cache($filename); if ($recursive) { $i = 0; - $result = $this->_setstat_recursive($filename, $attr, $i); - $this->_read_put_responses($i); + $result = $this->setstat_recursive($filename, $attr, $i); + $this->read_put_responses($i); return $result; } - $packet = $this->version >= 4 ? - pack('Na*a*Ca*', strlen($filename), $filename, substr($attr, 0, 4), NET_SFTP_TYPE_UNKNOWN, substr($attr, 4)) : - pack('Na*a*', strlen($filename), $filename, $attr); - if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, $packet)) { - return false; - } + $packet = Strings::packSSH2('s', $filename); + $packet .= $this->version >= 4 ? + pack('a*Ca*', substr($attr, 0, 4), NET_SFTP_TYPE_UNKNOWN, substr($attr, 4)) : + $attr; + $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); /* "Because some systems must use separate system calls to set various attributes, it is possible that a failure @@ -1824,18 +1752,15 @@ class SFTP extends SSH2 -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6 */ - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); return false; } @@ -1851,18 +1776,17 @@ class SFTP extends SSH2 * @param string $attr * @param int $i * @return bool - * @access private */ - function _setstat_recursive($path, $attr, &$i) + private function setstat_recursive($path, $attr, &$i) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { return false; } $i = 0; - $entries = $this->_list($path, true); + $entries = $this->readlist($path, true); - if ($entries === false) { - return $this->_setstat($path, $attr, false); + if ($entries === false || is_int($entries)) { + return $this->setstat($path, $attr, false); } // normally $entries would have at least . and .. but it might not if the directories @@ -1879,21 +1803,20 @@ class SFTP extends SSH2 $temp = $path . '/' . $filename; if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { - if (!$this->_setstat_recursive($temp, $attr, $i)) { + if (!$this->setstat_recursive($temp, $attr, $i)) { return false; } } else { - $packet = $this->version >= 4 ? - pack('Na*Ca*', strlen($temp), $temp, NET_SFTP_TYPE_UNKNOWN, $attr) : - pack('Na*a*', strlen($temp), $temp, $attr); - if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, $packet)) { - return false; - } + $packet = Strings::packSSH2('s', $temp); + $packet .= $this->version >= 4 ? + pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : + $attr; + $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { return false; } $i = 0; @@ -1901,17 +1824,16 @@ class SFTP extends SSH2 } } - $packet = $this->version >= 4 ? - pack('Na*Ca*', strlen($temp), $temp, NET_SFTP_TYPE_UNKNOWN, $attr) : - pack('Na*a*', strlen($temp), $temp, $attr); - if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, $packet)) { - return false; - } + $packet = Strings::packSSH2('s', $path); + $packet .= $this->version >= 4 ? + pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : + $attr; + $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { return false; } $i = 0; @@ -1924,47 +1846,40 @@ class SFTP extends SSH2 * Return the target of a symbolic link * * @param string $link + * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed - * @access public */ - function readlink($link) + public function readlink($link) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $link = $this->_realpath($link); + $link = $this->realpath($link); - if (!$this->_send_sftp_packet(NET_SFTP_READLINK, pack('Na*', strlen($link), $link))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link)); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: break; case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); return false; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Ncount', $this->_string_shift($response, 4))); + list($count) = Strings::unpackSSH2('N', $response); // the file isn't a symlink if (!$count) { return false; } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - return $this->_string_shift($response, $length); + list($filename) = Strings::unpackSSH2('s', $response); + + return $filename; } /** @@ -1974,17 +1889,17 @@ class SFTP extends SSH2 * * @param string $target * @param string $link + * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool - * @access public */ - function symlink($target, $link) + public function symlink($target, $link) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - //$target = $this->_realpath($target); - $link = $this->_realpath($link); + //$target = $this->realpath($target); + $link = $this->realpath($link); /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-12.1 : @@ -1995,7 +1910,7 @@ class SFTP extends SSH2 */ if ($this->version == 6) { $type = NET_SFTP_LINK; - $packet = pack('Na*Na*C', strlen($link), $link, strlen($target), $target, 1); + $packet = Strings::packSSH2('ssC', $link, $target, 1); } else { $type = NET_SFTP_SYMLINK; /* quoting http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL#347 : @@ -2013,25 +1928,20 @@ class SFTP extends SSH2 string targetpath string linkpath */ $packet = substr($this->server_identifier, 0, 15) == 'SSH-2.0-OpenSSH' ? - pack('Na*Na*', strlen($target), $target, strlen($link), $link) : - pack('Na*Na*', strlen($link), $link, strlen($target), $target); - } - if (!$this->_send_sftp_packet($type, $packet)) { - return false; + Strings::packSSH2('ss', $target, $link) : + Strings::packSSH2('ss', $link, $target); } + $this->send_sftp_packet($type, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); return false; } @@ -2045,15 +1955,14 @@ class SFTP extends SSH2 * @param int $mode * @param bool $recursive * @return bool - * @access public */ - function mkdir($dir, $mode = -1, $recursive = false) + public function mkdir($dir, $mode = -1, $recursive = false) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $dir = $this->_realpath($dir); + $dir = $this->realpath($dir); if ($recursive) { $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir)); @@ -2064,12 +1973,12 @@ class SFTP extends SSH2 for ($i = 0; $i < count($dirs); $i++) { $temp = array_slice($dirs, 0, $i + 1); $temp = implode('/', $temp); - $result = $this->_mkdir_helper($temp, $mode); + $result = $this->mkdir_helper($temp, $mode); } return $result; } - return $this->_mkdir_helper($dir, $mode); + return $this->mkdir_helper($dir, $mode); } /** @@ -2078,27 +1987,21 @@ class SFTP extends SSH2 * @param string $dir * @param int $mode * @return bool - * @access private */ - function _mkdir_helper($dir, $mode) + private function mkdir_helper($dir, $mode) { // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing) - if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, "\0\0\0\0"))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0"); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); return false; } @@ -2113,45 +2016,40 @@ class SFTP extends SSH2 * Removes a directory. * * @param string $dir + * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool - * @access public */ - function rmdir($dir) + public function rmdir($dir) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $dir = $this->_realpath($dir); + $dir = $this->realpath($dir); if ($dir === false) { return false; } - if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir)); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? - $this->_logError($response, $status); + $this->logError($response, $status); return false; } - $this->_remove_from_stat_cache($dir); + $this->remove_from_stat_cache($dir); // the following will do a soft delete, which would be useful if you deleted a file // and then tried to do a stat on the deleted file. the above, in contrast, does // a hard delete - //$this->_update_stat_cache($dir, false); + //$this->update_stat_cache($dir, false); return true; } @@ -2159,8 +2057,8 @@ class SFTP extends SSH2 /** * Uploads a file to the SFTP server. * - * By default, \phpseclib\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. - * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SFTP::get(), you will get a file, twelve bytes + * By default, \phpseclib3\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. + * So, for example, if you set $data to 'filename.ext' and then do \phpseclib3\Net\SFTP::get(), you will get a file, twelve bytes * long, containing 'filename.ext' as its contents. * * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will @@ -2192,28 +2090,31 @@ class SFTP extends SSH2 * * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE. * + * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} + * * @param string $remote_file * @param string|resource $data * @param int $mode * @param int $start * @param int $local_start * @param callable|null $progressCallback + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid + * @throws \phpseclib3\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist * @return bool - * @access public - * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode(). */ - function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) + public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $remote_file = $this->_realpath($remote_file); + $remote_file = $this->realpath($remote_file); if ($remote_file === false) { return false; } - $this->_remove_from_stat_cache($remote_file); + $this->remove_from_stat_cache($remote_file); if ($this->version >= 5) { $flags = NET_SFTP_OPEN_OPEN_OR_CREATE; @@ -2221,43 +2122,43 @@ class SFTP extends SSH2 $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." // in practice, it doesn't seem to do that. - //$flags|= ($mode & SFTP::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; + //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; } if ($start >= 0) { $offset = $start; - } elseif ($mode & self::RESUME) { + } elseif ($mode & (self::RESUME | self::RESUME_START)) { // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called - $size = $this->size($remote_file); + $size = $this->stat($remote_file)['size']; $offset = $size !== false ? $size : 0; } else { $offset = 0; if ($this->version >= 5) { $flags = NET_SFTP_OPEN_CREATE_TRUNCATE; } else { - $flags|= NET_SFTP_OPEN_TRUNCATE; + $flags |= NET_SFTP_OPEN_TRUNCATE; } } - $packet = pack('Na*', strlen($remote_file), $remote_file); - $packet.= $this->version >= 5 ? + $this->remove_from_stat_cache($remote_file); + + $packet = Strings::packSSH2('s', $remote_file); + $packet .= $this->version >= 5 ? pack('N3', 0, $flags, 0) : pack('N2', $flags, 0); - if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { - return false; - } + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: - $this->_logError($response); + $this->logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 @@ -2265,7 +2166,7 @@ class SFTP extends SSH2 switch (true) { case $mode & self::SOURCE_CALLBACK: if (!is_callable($data)) { - user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); + throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); } $dataCallback = $data; // do nothing @@ -2273,7 +2174,7 @@ class SFTP extends SSH2 case is_resource($data): $mode = $mode & ~self::SOURCE_LOCAL_FILE; $info = stream_get_meta_data($data); - if ($info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { + if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { $fp = fopen('php://memory', 'w+'); stream_copy_to_stream($data, $fp); rewind($fp); @@ -2283,8 +2184,7 @@ class SFTP extends SSH2 break; case $mode & self::SOURCE_LOCAL_FILE: if (!is_file($data)) { - user_error("$data is not a valid file"); - return false; + throw new FileNotFoundException("$data is not a valid file"); } $fp = @fopen($data, 'rb'); if (!$fp) { @@ -2298,7 +2198,10 @@ class SFTP extends SSH2 if ($local_start >= 0) { fseek($fp, $local_start); - $size-= $local_start; + $size -= $local_start; + } elseif ($mode & self::RESUME) { + fseek($fp, $offset); + $size -= $offset; } } elseif ($dataCallback) { $size = 0; @@ -2311,11 +2214,11 @@ class SFTP extends SSH2 $sftp_packet_size = $this->max_sftp_packet; // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header" - $sftp_packet_size-= strlen($handle) + 25; + $sftp_packet_size -= strlen($handle) + 25; $i = $j = 0; while ($dataCallback || ($size === 0 || $sent < $size)) { if ($dataCallback) { - $temp = call_user_func($dataCallback, $sftp_packet_size); + $temp = $dataCallback($sftp_packet_size); if (is_null($temp)) { break; } @@ -2328,22 +2231,23 @@ class SFTP extends SSH2 $subtemp = $offset + $sent; $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); - if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) { + try { + $this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j); + } catch (\Exception $e) { if ($mode & self::SOURCE_LOCAL_FILE) { fclose($fp); } - return false; + throw $e; } - $sent+= strlen($temp); + $sent += strlen($temp); if (is_callable($progressCallback)) { - call_user_func($progressCallback, $sent); + $progressCallback($sent); } $i++; $j++; - if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { $i = 0; break; } @@ -2351,13 +2255,13 @@ class SFTP extends SSH2 } } - $result = $this->_close_handle($handle); + $result = $this->close_handle($handle); - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { if ($mode & self::SOURCE_LOCAL_FILE) { fclose($fp); } - $this->_close_handle($handle); + $this->close_handle($handle); return false; } @@ -2368,21 +2272,11 @@ class SFTP extends SSH2 if ($this->preserveTime) { $stat = stat($data); - if ($this->version < 4) { - $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $stat['atime'], $stat['mtime']); - } else { - $attr = pack( - 'N5', - NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, - $stat['atime'] / 4294967296, - $stat['atime'], - $stat['mtime'] / 4294967296, - $stat['mtime'] - ); - } - - if (!$this->_setstat($remote_file, $attr, false)) { - user_error('Error setting file time'); + $attr = $this->version < 4 ? + pack('N3', NET_SFTP_ATTR_ACCESSTIME, $stat['atime'], $stat['mtime']) : + Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $stat['atime'], $stat['mtime']); + if (!$this->setstat($remote_file, $attr, false)) { + throw new \RuntimeException('Error setting file time'); } } } @@ -2398,23 +2292,20 @@ class SFTP extends SSH2 * * @param int $i * @return bool - * @access private + * @throws \UnexpectedValueException on receipt of unexpected packets */ - function _read_put_responses($i) + private function read_put_responses($i) { while ($i--) { - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); break; } } @@ -2427,28 +2318,23 @@ class SFTP extends SSH2 * * @param string $handle * @return bool - * @access private + * @throws \UnexpectedValueException on receipt of unexpected packets */ - function _close_handle($handle) + private function close_handle($handle) { - if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle)); // "The client MUST release all resources associated with the handle regardless of the status." // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); return false; } @@ -2465,43 +2351,41 @@ class SFTP extends SSH2 * $offset and $length can be used to download files in chunks. * * @param string $remote_file - * @param string $local_file + * @param string|bool|resource|callable $local_file * @param int $offset * @param int $length * @param callable|null $progressCallback - * @return mixed - * @access public + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return string|bool */ - function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) + public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $remote_file = $this->_realpath($remote_file); + $remote_file = $this->realpath($remote_file); if ($remote_file === false) { return false; } - $packet = pack('Na*', strlen($remote_file), $remote_file); - $packet.= $this->version >= 5 ? + $packet = Strings::packSSH2('s', $remote_file); + $packet .= $this->version >= 5 ? pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) : pack('N2', NET_SFTP_OPEN_READ, 0); - if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { - return false; - } + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - $this->_logError($response); + $this->logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } if (is_resource($local_file)) { @@ -2532,15 +2416,17 @@ class SFTP extends SSH2 $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet; - $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); - if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) { + $packet = Strings::packSSH2('sN3', $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); + try { + $this->send_sftp_packet(NET_SFTP_READ, $packet, $i); + } catch (\Exception $e) { if ($fclose_check) { fclose($fp); } - return false; + throw $e; } $packet = null; - $read+= $packet_size; + $read += $packet_size; $i++; } @@ -2555,18 +2441,18 @@ class SFTP extends SSH2 $i--; if ($clear_responses) { - $this->_get_sftp_packet($packets_sent - $i); + $this->get_sftp_packet($packets_sent - $i); continue; } else { - $response = $this->_get_sftp_packet($packets_sent - $i); + $response = $this->get_sftp_packet($packets_sent - $i); } switch ($this->packet_type) { case NET_SFTP_DATA: $temp = substr($response, 4); - $offset+= strlen($temp); + $offset += strlen($temp); if ($local_file === false) { - $content.= $temp; + $content .= $temp; } elseif (is_callable($local_file)) { $local_file($temp); } else { @@ -2579,20 +2465,20 @@ class SFTP extends SSH2 break; case NET_SFTP_STATUS: // could, in theory, return false if !strlen($content) but we'll hold off for the time being - $this->_logError($response); + $this->logError($response); $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses break; default: if ($fclose_check) { fclose($fp); } - // maybe the file was successfully transferred, maybe it wasn't if ($this->channel_close) { $this->partial_init = false; - $this->_init_sftp_connection(); + $this->init_sftp_connection(); return false; } else { - user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS'); + throw new \UnexpectedValueException('Expected NET_SFTP_DATA or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } } $response = null; @@ -2603,14 +2489,6 @@ class SFTP extends SSH2 } } - if ($length > 0 && $length <= $offset - $start) { - if ($local_file === false) { - $content = substr($content, 0, $length); - } else { - ftruncate($fp, $length + $res_offset); - } - } - if ($fclose_check) { fclose($fp); @@ -2620,7 +2498,7 @@ class SFTP extends SSH2 } } - if (!$this->_close_handle($handle)) { + if (!$this->close_handle($handle)) { return false; } @@ -2634,11 +2512,11 @@ class SFTP extends SSH2 * @param string $path * @param bool $recursive * @return bool - * @access public + * @throws \UnexpectedValueException on receipt of unexpected packets */ - function delete($path, $recursive = true) + public function delete($path, $recursive = true) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } @@ -2651,39 +2529,35 @@ class SFTP extends SSH2 return false; } - $path = $this->_realpath($path); + $path = $this->realpath($path); if ($path === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 - if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) { - return false; - } + $this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path)); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); if (!$recursive) { return false; } + $i = 0; - $result = $this->_delete_recursive($path, $i); - $this->_read_put_responses($i); + $result = $this->delete_recursive($path, $i); + $this->read_put_responses($i); return $result; } - $this->_remove_from_stat_cache($path); + $this->remove_from_stat_cache($path); return true; } @@ -2696,22 +2570,26 @@ class SFTP extends SSH2 * @param string $path * @param int $i * @return bool - * @access private */ - function _delete_recursive($path, &$i) + private function delete_recursive($path, &$i) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { return false; } $i = 0; - $entries = $this->_list($path, true); + $entries = $this->readlist($path, true); - // normally $entries would have at least . and .. but it might not if the directories - // permissions didn't allow reading - if (empty($entries)) { + // The folder does not exist at all, so we cannot delete it. + if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) { return false; } + // Normally $entries would have at least . and .. but it might not if the directories + // permissions didn't allow reading. If this happens then default to an empty list of files. + if ($entries === false || is_int($entries)) { + $entries = []; + } + unset($entries['.'], $entries['..']); foreach ($entries as $filename => $props) { if (!isset($props['type'])) { @@ -2720,19 +2598,17 @@ class SFTP extends SSH2 $temp = $path . '/' . $filename; if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { - if (!$this->_delete_recursive($temp, $i)) { + if (!$this->delete_recursive($temp, $i)) { return false; } } else { - if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($temp), $temp))) { - return false; - } - $this->_remove_from_stat_cache($temp); + $this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp)); + $this->remove_from_stat_cache($temp); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { return false; } $i = 0; @@ -2740,15 +2616,13 @@ class SFTP extends SSH2 } } - if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($path), $path))) { - return false; - } - $this->_remove_from_stat_cache($path); + $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path)); + $this->remove_from_stat_cache($path); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->_read_put_responses($i)) { + if (!$this->read_put_responses($i)) { return false; } $i = 0; @@ -2762,18 +2636,17 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function file_exists($path) + public function file_exists($path) { if ($this->use_stat_cache) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $path = $this->_realpath($path); + $path = $this->realpath($path); - $result = $this->_query_stat_cache($path); + $result = $this->query_stat_cache($path); if (isset($result)) { // return true if $result is an array or if it's an stdClass object @@ -2789,11 +2662,10 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function is_dir($path) + public function is_dir($path) { - $result = $this->_get_stat_cache_prop($path, 'type'); + $result = $this->get_stat_cache_prop($path, 'type'); if ($result === false) { return false; } @@ -2805,11 +2677,10 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function is_file($path) + public function is_file($path) { - $result = $this->_get_stat_cache_prop($path, 'type'); + $result = $this->get_stat_cache_prop($path, 'type'); if ($result === false) { return false; } @@ -2821,11 +2692,10 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function is_link($path) + public function is_link($path) { - $result = $this->_get_lstat_cache_prop($path, 'type'); + $result = $this->get_lstat_cache_prop($path, 'type'); if ($result === false) { return false; } @@ -2837,30 +2707,25 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function is_readable($path) + public function is_readable($path) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $path = $this->_realpath($path); + $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0); + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_READ, 0); - if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { - return false; - } - - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return true; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } } @@ -2869,30 +2734,25 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function is_writable($path) + public function is_writable($path) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $path = $this->_realpath($path); + $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0); + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_WRITE, 0); - if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) { - return false; - } - - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return true; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } } @@ -2903,9 +2763,8 @@ class SFTP extends SSH2 * * @param string $path * @return bool - * @access public */ - function is_writeable($path) + public function is_writeable($path) { return $this->is_writable($path); } @@ -2915,11 +2774,10 @@ class SFTP extends SSH2 * * @param string $path * @return mixed - * @access public */ - function fileatime($path) + public function fileatime($path) { - return $this->_get_stat_cache_prop($path, 'atime'); + return $this->get_stat_cache_prop($path, 'atime'); } /** @@ -2927,11 +2785,10 @@ class SFTP extends SSH2 * * @param string $path * @return mixed - * @access public */ - function filemtime($path) + public function filemtime($path) { - return $this->_get_stat_cache_prop($path, 'mtime'); + return $this->get_stat_cache_prop($path, 'mtime'); } /** @@ -2939,11 +2796,10 @@ class SFTP extends SSH2 * * @param string $path * @return mixed - * @access public */ - function fileperms($path) + public function fileperms($path) { - return $this->_get_stat_cache_prop($path, 'permissions'); + return $this->get_stat_cache_prop($path, 'mode'); } /** @@ -2951,11 +2807,10 @@ class SFTP extends SSH2 * * @param string $path * @return mixed - * @access public */ - function fileowner($path) + public function fileowner($path) { - return $this->_get_stat_cache_prop($path, 'uid'); + return $this->get_stat_cache_prop($path, 'uid'); } /** @@ -2963,35 +2818,54 @@ class SFTP extends SSH2 * * @param string $path * @return mixed - * @access public */ - function filegroup($path) + public function filegroup($path) { - return $this->_get_stat_cache_prop($path, 'gid'); + return $this->get_stat_cache_prop($path, 'gid'); + } + + /** + * Recursively go through rawlist() output to get the total filesize + * + * @return int + */ + private static function recursiveFilesize(array $files) + { + $size = 0; + foreach ($files as $name => $file) { + if ($name == '.' || $name == '..') { + continue; + } + $size += is_array($file) ? + self::recursiveFilesize($file) : + $file->size; + } + return $size; } /** * Gets file size * * @param string $path + * @param bool $recursive * @return mixed - * @access public */ - function filesize($path) + public function filesize($path, $recursive = false) { - return $this->_get_stat_cache_prop($path, 'size'); + return !$recursive || $this->filetype($path) != 'dir' ? + $this->get_stat_cache_prop($path, 'size') : + self::recursiveFilesize($this->rawlist($path, true)); } /** * Gets file type * * @param string $path - * @return mixed - * @access public + * @return string|false */ - function filetype($path) + public function filetype($path) { - $type = $this->_get_stat_cache_prop($path, 'type'); + $type = $this->get_stat_cache_prop($path, 'type'); if ($type === false) { return false; } @@ -3022,11 +2896,10 @@ class SFTP extends SSH2 * @param string $path * @param string $prop * @return mixed - * @access private */ - function _get_stat_cache_prop($path, $prop) + private function get_stat_cache_prop($path, $prop) { - return $this->_get_xstat_cache_prop($path, $prop, 'stat'); + return $this->get_xstat_cache_prop($path, $prop, 'stat'); } /** @@ -3037,11 +2910,10 @@ class SFTP extends SSH2 * @param string $path * @param string $prop * @return mixed - * @access private */ - function _get_lstat_cache_prop($path, $prop) + private function get_lstat_cache_prop($path, $prop) { - return $this->_get_xstat_cache_prop($path, $prop, 'lstat'); + return $this->get_xstat_cache_prop($path, $prop, 'lstat'); } /** @@ -3051,20 +2923,19 @@ class SFTP extends SSH2 * * @param string $path * @param string $prop - * @param mixed $type + * @param string $type * @return mixed - * @access private */ - function _get_xstat_cache_prop($path, $prop, $type) + private function get_xstat_cache_prop($path, $prop, $type) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } if ($this->use_stat_cache) { - $path = $this->_realpath($path); + $path = $this->realpath($path); - $result = $this->_query_stat_cache($path); + $result = $this->query_stat_cache($path); if (is_object($result) && isset($result->$type)) { return $result->{$type}[$prop]; @@ -3088,22 +2959,22 @@ class SFTP extends SSH2 * @param string $oldname * @param string $newname * @return bool - * @access public + * @throws \UnexpectedValueException on receipt of unexpected packets */ - function rename($oldname, $newname) + public function rename($oldname, $newname) { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } - $oldname = $this->_realpath($oldname); - $newname = $this->_realpath($newname); + $oldname = $this->realpath($oldname); + $newname = $this->realpath($newname); if ($oldname === false || $newname === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 - $packet = pack('Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname); + $packet = Strings::packSSH2('ss', $oldname, $newname); if ($this->version >= 5) { /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-6.5 , @@ -3114,33 +2985,28 @@ class SFTP extends SSH2 SSH_FXP_RENAME_NATIVE 0x00000004 (none of these are currently supported) */ - $packet.= "\0\0\0\0"; - } - if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) { - return false; + $packet .= "\0\0\0\0"; } + $this->send_sftp_packet(NET_SFTP_RENAME, $packet); - $response = $this->_get_sftp_packet(); + $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - if (strlen($response) < 4) { - return false; - } - extract(unpack('Nstatus', $this->_string_shift($response, 4))); + list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { - $this->_logError($response, $status); + $this->logError($response, $status); return false; } // don't move the stat cache entry over since this operation could very well change the // atime and mtime attributes - //$this->_update_stat_cache($newname, $this->_query_stat_cache($oldname)); - $this->_remove_from_stat_cache($oldname); - $this->_remove_from_stat_cache($newname); + //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); + $this->remove_from_stat_cache($oldname); + $this->remove_from_stat_cache($newname); return true; } @@ -3154,18 +3020,13 @@ class SFTP extends SSH2 * @param int $flags * @param string $response * @return array - * @access private */ - function _parseTime($key, $flags, &$response) + private function parseTime($key, $flags, &$response) { - if (strlen($response) < 8) { - user_error('Malformed file attributes'); - return array(); - } - $attr = array(); - $attr[$key] = hexdec(bin2hex($this->_string_shift($response, 8))); + $attr = []; + list($attr[$key]) = Strings::unpackSSH2('Q', $response); if ($flags & NET_SFTP_ATTR_SUBSECOND_TIMES) { - $attr+= extract(unpack('N' . $key . '_nseconds', $this->_string_shift($response, 4))); + list($attr[$key . '-nseconds']) = Strings::unpackSSH2('N', $response); } return $attr; } @@ -3177,28 +3038,16 @@ class SFTP extends SSH2 * * @param string $response * @return array - * @access private */ - function _parseAttributes(&$response) + protected function parseAttributes(&$response) { if ($this->version >= 4) { - $length = 5; - $format = 'Nflags/Ctype'; + list($flags, $attr['type']) = Strings::unpackSSH2('NC', $response); } else { - $length = 4; - $format = 'Nflags'; + list($flags) = Strings::unpackSSH2('N', $response); } - $attr = array(); - if (strlen($response) < $length) { - user_error('Malformed file attributes'); - return array(); - } - extract(unpack($format, $this->_string_shift($response, $length))); - if (isset($type)) { - $attr['type'] = $type; - } - foreach ($this->attributes as $key => $value) { + foreach (self::$attributes as $key => $value) { switch ($flags & $key) { case NET_SFTP_ATTR_UIDGID: if ($this->version > 3) { @@ -3237,90 +3086,42 @@ class SFTP extends SSH2 // IEEE 754 binary64 "double precision" on such platforms and // as such can represent integers of at least 2^50 without loss // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. - $attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8))); + list($attr['size']) = Strings::unpackSSH2('Q', $response); break; - case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 or earlier) - if (strlen($response) < 8) { - user_error('Malformed file attributes'); - return $attr; - } - $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8)); + case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) + list($attr['uid'], $attr['gid']) = Strings::unpackSSH2('NN', $response); break; - case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - $attr+= unpack('Npermissions', $this->_string_shift($response, 4)); - // mode == permissions; permissions was the original array key and is retained for bc purposes. - // mode was added because that's the more industry standard terminology - $attr+= array('mode' => $attr['permissions']); - $fileType = $this->_parseMode($attr['permissions']); - if ($fileType !== false) { - $attr+= array('type' => $fileType); + case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 + list($attr['mode']) = Strings::unpackSSH2('N', $response); + $fileType = $this->parseMode($attr['mode']); + if ($this->version < 4 && $fileType !== false) { + $attr += ['type' => $fileType]; } break; - case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 + case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 if ($this->version >= 4) { - $attr+= $this->_parseTime('atime', $flags, $response); + $attr += $this->parseTime('atime', $flags, $response); break; } - if (strlen($response) < 8) { - user_error('Malformed file attributes'); - return $attr; - } - $attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8)); + list($attr['atime'], $attr['mtime']) = Strings::unpackSSH2('NN', $response); break; case NET_SFTP_ATTR_CREATETIME: // 0x00000010 (SFTPv4+) - $attr+= $this->_parseTime('createtime', $flags, $response); + $attr += $this->parseTime('createtime', $flags, $response); break; case NET_SFTP_ATTR_MODIFYTIME: // 0x00000020 - $attr+= $this->_parseTime('mtime', $flags, $response); + $attr += $this->parseTime('mtime', $flags, $response); break; case NET_SFTP_ATTR_ACL: // 0x00000040 // access control list // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7 // currently unsupported - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Ncount', $this->_string_shift($response, 4))); + list($count) = Strings::unpackSSH2('N', $response); for ($i = 0; $i < $count; $i++) { - if (strlen($response) < 16) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Ntype/Nflag/Nmask/Nlength', $this->_string_shift($response, 16))); - if (strlen($response) < $length) { - user_error('Malformed file attributes'); - return $attr; - } - $this->_string_shift($response, $length); // who + list($type, $flag, $mask, $who) = Strings::unpackSSH2('N3s', $result); } break; case NET_SFTP_ATTR_OWNERGROUP: // 0x00000080 - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - if (strlen($response) < $length) { - user_error('Malformed file attributes'); - return $attr; - } - $attr['owner'] = $this->_string_shift($response, $length); - - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - if (strlen($response) < $length) { - user_error('Malformed file attributes'); - return $attr; - } - $attr['group'] = $this->_string_shift($response, $length); + list($attr['owner'], $attr['$group']) = Strings::unpackSSH2('ss', $response); break; case NET_SFTP_ATTR_SUBSECOND_TIMES: // 0x00000100 break; @@ -3330,82 +3131,46 @@ class SFTP extends SSH2 // tells if you file is: // readonly, system, hidden, case inensitive, archive, encrypted, compressed, sparse // append only, immutable, sync - if (strlen($response) < 8) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nattrib-bits/Nattrib-bits-valid', $this->_string_shift($response, 8))); + list($attrib_bits, $attrib_bits_valid) = Strings::unpackSSH2('N2', $response); + // if we were actually gonna implement the above it ought to be + // $attr['attrib-bits'] and $attr['attrib-bits-valid'] + // eg. - instead of _ break; case NET_SFTP_ATTR_ALLOCATION_SIZE: // 0x00000400 (SFTPv6+) // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4 - // represents the number of bytes htat the file consumes on the disk. will + // represents the number of bytes that the file consumes on the disk. will // usually be larger than the 'size' field - $attr['allocation-size'] = hexdec(bin2hex($this->_string_shift($response, 8))); + list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response); break; case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800 // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10 // currently unsupported // tells if file is "known text", "guessed text", "known binary", "guessed binary" - extract(unpack('Ctext-hint', $this->_string_shift($response))); + list($text_hint) = Strings::unpackSSH2('C', $response); + // the above should be $attr['text-hint'] break; case NET_SFTP_ATTR_MIME_TYPE: // 0x00001000 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.11 - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - if (strlen($response) < $length) { - user_error('Malformed file attributes'); - return $attr; - } - $attr['mime-type'] = $this->_string_shift($response, $length); + list($attr['mime-type']) = Strings::unpackSSH2('s', $response); break; case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12 - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - $attr+= unpack('Nlink-count', $this->_string_shift($response, 4)); + list($attr['link-count']) = Strings::unpackSSH2('N', $response); break; case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13 - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - if (strlen($response) < $length) { - user_error('Malformed file attributes'); - return $attr; - } - $attr['untranslated-name'] = $this->_string_shift($response, $length); + list($attr['untranslated-name']) = Strings::unpackSSH2('s', $response); break; case NET_SFTP_ATTR_CTIME: // 0x00008000 // 'ctime' contains the last time the file attributes were changed. The // exact meaning of this field depends on the server. - $attr+= $this->_parseTime('ctime', $flags, $response); + $attr += $this->parseTime('ctime', $flags, $response); break; - case NET_SFTP_ATTR_EXTENDED: // 0x80000000 - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Ncount', $this->_string_shift($response, 4))); + case NET_SFTP_ATTR_EXTENDED: // 0x80000000 + list($count) = Strings::unpackSSH2('N', $response); for ($i = 0; $i < $count; $i++) { - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $key = $this->_string_shift($response, $length); - if (strlen($response) < 4) { - user_error('Malformed file attributes'); - return $attr; - } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $attr[$key] = $this->_string_shift($response, $length); + list($key, $value) = Strings::unpackSSH2('ss', $response); + $attr[$key] = $value; } } } @@ -3419,9 +3184,8 @@ class SFTP extends SSH2 * * @param int $mode * @return int - * @access private */ - function _parseMode($mode) + private function parseMode($mode) { // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 // see, also, http://linux.die.net/man/2/stat @@ -3466,9 +3230,8 @@ class SFTP extends SSH2 * * @param string $longname * @return mixed - * @access private */ - function _parseLongname($longname) + private function parseLongname($longname) { // http://en.wikipedia.org/wiki/Unix_file_types // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions @@ -3497,11 +3260,10 @@ class SFTP extends SSH2 * @param string $data * @param int $request_id * @see self::_get_sftp_packet() - * @see self::_send_channel_packet() - * @return bool - * @access private + * @see self::send_channel_packet() + * @return void */ - function _send_sftp_packet($type, $data, $request_id = 1) + private function send_sftp_packet($type, $data, $request_id = 1) { // in SSH2.php the timeout is cumulative per function call. eg. exec() will // timeout after 10s. but for SFTP.php it's cumulative per packet @@ -3509,50 +3271,30 @@ class SFTP extends SSH2 $packet = $this->use_request_id ? pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : - pack('NCa*', strlen($data) + 1, $type, $data); + pack('NCa*', strlen($data) + 1, $type, $data); - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 - $result = $this->_send_channel_packet(self::CHANNEL, $packet); - $stop = strtok(microtime(), ' ') + strtok(''); + $start = microtime(true); + $this->send_channel_packet(self::CHANNEL, $packet); + $stop = microtime(true); if (defined('NET_SFTP_LOGGING')) { - $packet_type = '-> ' . $this->packet_types[$type] . + $packet_type = '-> ' . self::$packet_types[$type] . ' (' . round($stop - $start, 4) . 's)'; - if (NET_SFTP_LOGGING == self::LOG_REALTIME) { - switch (PHP_SAPI) { - case 'cli': - $start = $stop = "\r\n"; - break; - default: - $start = '
';
-                        $stop = '
'; - } - echo $start . $this->_format_log(array($data), array($packet_type)) . $stop; - @flush(); - @ob_flush(); - } else { - $this->packet_type_log[] = $packet_type; - if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { - $this->packet_log[] = $data; - } - } + $this->append_log($packet_type, $data); } - - return $result; } /** * Resets a connection for re-use * * @param int $reason - * @access private */ - function _reset_connection($reason) + protected function reset_connection($reason) { - parent::_reset_connection($reason); + parent::reset_connection($reason); $this->use_request_id = false; $this->pwd = false; - $this->requestBuffer = array(); + $this->requestBuffer = []; } /** @@ -3566,9 +3308,8 @@ class SFTP extends SSH2 * * @see self::_send_sftp_packet() * @return string - * @access private */ - function _get_sftp_packet($request_id = null) + private function get_sftp_packet($request_id = null) { $this->channel_close = false; @@ -3583,11 +3324,11 @@ class SFTP extends SSH2 // timeout after 10s. but for SFTP.php it's cumulative per packet $this->curTimeout = $this->timeout; - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + $start = microtime(true); // SFTP packet length while (strlen($this->packet_buffer) < 4) { - $temp = $this->_get_channel_packet(self::CHANNEL, true); + $temp = $this->get_channel_packet(self::CHANNEL, true); if ($temp === true) { if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { $this->channel_close = true; @@ -3596,92 +3337,98 @@ class SFTP extends SSH2 $this->packet_buffer = ''; return false; } - if ($temp === false) { - return false; - } - $this->packet_buffer.= $temp; + $this->packet_buffer .= $temp; } if (strlen($this->packet_buffer) < 4) { - return false; + throw new \RuntimeException('Packet is too small'); } - extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4))); + extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); + /** @var integer $length */ + $tempLength = $length; - $tempLength-= strlen($this->packet_buffer); + $tempLength -= strlen($this->packet_buffer); // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) { - user_error('Invalid SFTP packet size'); - return false; + throw new \RuntimeException('Invalid Size'); } // SFTP packet type and data payload while ($tempLength > 0) { - $temp = $this->_get_channel_packet(self::CHANNEL, true); - if (is_bool($temp)) { + $temp = $this->get_channel_packet(self::CHANNEL, true); + if ($temp === true) { + if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { + $this->channel_close = true; + } $this->packet_type = false; $this->packet_buffer = ''; return false; } - $this->packet_buffer.= $temp; - $tempLength-= strlen($temp); + $this->packet_buffer .= $temp; + $tempLength -= strlen($temp); } - $stop = strtok(microtime(), ' ') + strtok(''); + $stop = microtime(true); - $this->packet_type = ord($this->_string_shift($this->packet_buffer)); + $this->packet_type = ord(Strings::shift($this->packet_buffer)); if ($this->use_request_id) { - extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id - $length-= 5; // account for the request id and the packet type + extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id + $length -= 5; // account for the request id and the packet type } else { - $length-= 1; // account for the packet type + $length -= 1; // account for the packet type } - $packet = $this->_string_shift($this->packet_buffer, $length); + $packet = Strings::shift($this->packet_buffer, $length); if (defined('NET_SFTP_LOGGING')) { - $packet_type = '<- ' . $this->packet_types[$this->packet_type] . + $packet_type = '<- ' . self::$packet_types[$this->packet_type] . ' (' . round($stop - $start, 4) . 's)'; - if (NET_SFTP_LOGGING == self::LOG_REALTIME) { - switch (PHP_SAPI) { - case 'cli': - $start = $stop = "\r\n"; - break; - default: - $start = '
';
-                        $stop = '
'; - } - echo $start . $this->_format_log(array($packet), array($packet_type)) . $stop; - @flush(); - @ob_flush(); - } else { - $this->packet_type_log[] = $packet_type; - if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { - $this->packet_log[] = $packet; - } - } + $this->append_log($packet_type, $packet); } if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) { - $this->requestBuffer[$packet_id] = array( + $this->requestBuffer[$packet_id] = [ 'packet_type' => $this->packet_type, 'packet' => $packet - ); - return $this->_get_sftp_packet($request_id); + ]; + return $this->get_sftp_packet($request_id); } return $packet; } + /** + * Logs data packets + * + * Makes sure that only the last 1MB worth of packets will be logged + * + * @param string $message_number + * @param string $message + */ + private function append_log($message_number, $message) + { + $this->append_log_helper( + NET_SFTP_LOGGING, + $message_number, + $message, + $this->packet_type_log, + $this->packet_log, + $this->log_size, + $this->realtime_log_file, + $this->realtime_log_wrap, + $this->realtime_log_size + ); + } + /** * Returns a log of the packets that have been sent and received. * - * Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') + * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') * - * @access public - * @return string or Array + * @return array|string|false */ - function getSFTPLog() + public function getSFTPLog() { if (!defined('NET_SFTP_LOGGING')) { return false; @@ -3689,7 +3436,7 @@ class SFTP extends SSH2 switch (NET_SFTP_LOGGING) { case self::LOG_COMPLEX: - return $this->_format_log($this->packet_log, $this->packet_type_log); + return $this->format_log($this->packet_log, $this->packet_type_log); break; //case self::LOG_SIMPLE: default: @@ -3701,9 +3448,8 @@ class SFTP extends SSH2 * Returns all errors * * @return array - * @access public */ - function getSFTPErrors() + public function getSFTPErrors() { return $this->sftp_errors; } @@ -3712,9 +3458,8 @@ class SFTP extends SSH2 * Returns the last error * * @return string - * @access public */ - function getLastSFTPError() + public function getLastSFTPError() { return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : ''; } @@ -3723,19 +3468,18 @@ class SFTP extends SSH2 * Get supported SFTP versions * * @return array - * @access public */ - function getSupportedVersions() + public function getSupportedVersions() { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } if (!$this->partial_init) { - $this->_partial_init_sftp_connection(); + $this->partial_init_sftp_connection(); } - $temp = array('version' => $this->defaultVersion); + $temp = ['version' => $this->defaultVersion]; if (isset($this->extensions['versions'])) { $temp['extensions'] = $this->extensions['versions']; } @@ -3745,12 +3489,11 @@ class SFTP extends SSH2 /** * Get supported SFTP versions * - * @return array - * @access public + * @return int|false */ - function getNegotiatedVersion() + public function getNegotiatedVersion() { - if (!$this->_precheck()) { + if (!$this->precheck()) { return false; } @@ -3765,9 +3508,8 @@ class SFTP extends SSH2 * unset the preferred version * * @param int $version - * @access public */ - function setPreferredVersion($version) + public function setPreferredVersion($version) { $this->preferredVersion = $version; } @@ -3776,21 +3518,19 @@ class SFTP extends SSH2 * Disconnect * * @param int $reason - * @return bool - * @access private + * @return false */ - function _disconnect($reason) + protected function disconnect_helper($reason) { $this->pwd = false; - parent::_disconnect($reason); + return parent::disconnect_helper($reason); } /** * Enable Date Preservation * - * @access public */ - function enableDatePreservation() + public function enableDatePreservation() { $this->preserveTime = true; } @@ -3798,9 +3538,8 @@ class SFTP extends SSH2 /** * Disable Date Preservation * - * @access public */ - function disableDatePreservation() + public function disableDatePreservation() { $this->preserveTime = false; } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php similarity index 84% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php index ec9e5841a..24047b4b0 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php @@ -7,25 +7,22 @@ * * PHP version 5 * - * @category Net - * @package SFTP * @author Jim Wigginton * @copyright 2013 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ -namespace phpseclib\Net\SFTP; +namespace phpseclib3\Net\SFTP; -use phpseclib\Crypt\RSA; -use phpseclib\Net\SFTP; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Net\SFTP; +use phpseclib3\Net\SSH2; /** * SFTP Stream Wrapper * - * @package SFTP * @author Jim Wigginton - * @access public */ class Stream { @@ -36,90 +33,80 @@ class Stream * * @var array */ - static $instances; + public static $instances; /** * SFTP instance * * @var object - * @access private */ - var $sftp; + private $sftp; /** * Path * * @var string - * @access private */ - var $path; + private $path; /** * Mode * * @var string - * @access private */ - var $mode; + private $mode; /** * Position * * @var int - * @access private */ - var $pos; + private $pos; /** * Size * * @var int - * @access private */ - var $size; + private $size; /** * Directory entries * * @var array - * @access private */ - var $entries; + private $entries; /** * EOF flag * * @var bool - * @access private */ - var $eof; + private $eof; /** * Context resource * - * Technically this needs to be publically accessible so PHP can set it directly + * Technically this needs to be publicly accessible so PHP can set it directly * * @var resource - * @access public */ - var $context; + public $context; /** * Notification callback function * * @var callable - * @access public */ - var $notification; + private $notification; /** * Registers this class as a URL wrapper. * * @param string $protocol The wrapper name to be registered. * @return bool True on success, false otherwise. - * @access public */ - static function register($protocol = 'sftp') + public static function register($protocol = 'sftp') { if (in_array($protocol, stream_get_wrappers(), true)) { return false; @@ -130,9 +117,8 @@ class Stream /** * The Constructor * - * @access public */ - function __construct() + public function __construct() { if (defined('NET_SFTP_STREAM_LOGGING')) { echo "__construct()\r\n"; @@ -149,21 +135,20 @@ class Stream * * @param string $path * @return string - * @access private */ - function _parse_path($path) + protected function parse_path($path) { $orig = $path; - extract(parse_url($path) + array('port' => 22)); + extract(parse_url($path) + ['port' => 22]); if (isset($query)) { - $path.= '?' . $query; + $path .= '?' . $query; } elseif (preg_match('/(\?|\?#)$/', $orig)) { - $path.= '?'; + $path .= '?'; } if (isset($fragment)) { - $path.= '#' . $fragment; + $path .= '#' . $fragment; } elseif ($orig[strlen($orig) - 1] == '#') { - $path.= '#'; + $path .= '#'; } if (!isset($host)) { @@ -177,13 +162,12 @@ class Stream } } - if ($host[0] == '$') { - $host = substr($host, 1); - global ${$host}; - if (($$host instanceof SFTP) === false) { + if (preg_match('/^{[a-z0-9]+}$/i', $host)) { + $host = SSH2::getConnectionByResourceId($host); + if ($host === false) { return false; } - $this->sftp = $$host; + $this->sftp = $host; } else { if (isset($this->context)) { $context = stream_context_get_options($this->context); @@ -204,7 +188,7 @@ class Stream if (isset($context[$scheme]['password'])) { $pass = $context[$scheme]['password']; } - if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof RSA) { + if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof PrivateKey) { $pass = $context[$scheme]['privkey']; } @@ -212,7 +196,7 @@ class Stream return false; } - // casting $pass to a string is necessary in the event that it's a \phpseclib\Crypt\RSA object + // casting $pass to a string is necessary in the event that it's a \phpseclib3\Crypt\RSA object if (isset(self::$instances[$host][$port][$user][(string) $pass])) { $this->sftp = self::$instances[$host][$port][$user][(string) $pass]; } else { @@ -255,18 +239,17 @@ class Stream * @param int $options * @param string $opened_path * @return bool - * @access public */ - function _stream_open($path, $mode, $options, &$opened_path) + private function _stream_open($path, $mode, $options, &$opened_path) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } $this->path = $path; - $this->size = $this->sftp->size($path); + $this->size = $this->sftp->filesize($path); $this->mode = preg_replace('#[bt]$#', '', $mode); $this->eof = false; @@ -297,9 +280,8 @@ class Stream * * @param int $count * @return mixed - * @access public */ - function _stream_read($count) + private function _stream_read($count) { switch ($this->mode) { case 'w': @@ -329,7 +311,7 @@ class Stream $this->eof = true; return false; } - $this->pos+= strlen($result); + $this->pos += strlen($result); return $result; } @@ -338,10 +320,9 @@ class Stream * Write to stream * * @param string $data - * @return mixed - * @access public + * @return int|false */ - function _stream_write($data) + private function _stream_write($data) { switch ($this->mode) { case 'r': @@ -361,7 +342,7 @@ class Stream if ($result === false) { return false; } - $this->pos+= strlen($data); + $this->pos += strlen($data); if ($this->pos > $this->size) { $this->size = $this->pos; } @@ -373,9 +354,8 @@ class Stream * Retrieve the current position of a stream * * @return int - * @access public */ - function _stream_tell() + private function _stream_tell() { return $this->pos; } @@ -391,9 +371,8 @@ class Stream * will return false. do fread($fp, 1) and feof() will then return true. * * @return bool - * @access public */ - function _stream_eof() + private function _stream_eof() { return $this->eof; } @@ -404,9 +383,8 @@ class Stream * @param int $offset * @param int $whence * @return bool - * @access public */ - function _stream_seek($offset, $whence) + private function _stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: @@ -415,10 +393,10 @@ class Stream } break; case SEEK_CUR: - $offset+= $this->pos; + $offset += $this->pos; break; case SEEK_END: - $offset+= $this->size; + $offset += $this->size; } $this->pos = $offset; @@ -433,11 +411,10 @@ class Stream * @param int $option * @param mixed $var * @return bool - * @access public */ - function _stream_metadata($path, $option, $var) + private function _stream_metadata($path, $option, $var) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } @@ -467,9 +444,8 @@ class Stream * * @param int $cast_as * @return resource - * @access public */ - function _stream_cast($cast_as) + private function _stream_cast($cast_as) { return $this->sftp->fsock; } @@ -479,9 +455,8 @@ class Stream * * @param int $operation * @return bool - * @access public */ - function _stream_lock($operation) + private function _stream_lock($operation) { return false; } @@ -490,15 +465,14 @@ class Stream * Renames a file or directory * * Attempts to rename oldname to newname, moving it between directories if necessary. - * If newname exists, it will be overwritten. This is a departure from what \phpseclib\Net\SFTP + * If newname exists, it will be overwritten. This is a departure from what \phpseclib3\Net\SFTP * does. * * @param string $path_from * @param string $path_to * @return bool - * @access public */ - function _rename($path_from, $path_to) + private function _rename($path_from, $path_to) { $path1 = parse_url($path_from); $path2 = parse_url($path_to); @@ -507,7 +481,7 @@ class Stream return false; } - $path_from = $this->_parse_path($path_from); + $path_from = $this->parse_path($path_from); $path_to = parse_url($path_to); if ($path_from === false) { return false; @@ -548,11 +522,10 @@ class Stream * @param string $path * @param int $options * @return bool - * @access public */ - function _dir_opendir($path, $options) + private function _dir_opendir($path, $options) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } @@ -565,9 +538,8 @@ class Stream * Read entry from directory handle * * @return mixed - * @access public */ - function _dir_readdir() + private function _dir_readdir() { if (isset($this->entries[$this->pos])) { return $this->entries[$this->pos++]; @@ -579,9 +551,8 @@ class Stream * Rewind directory handle * * @return bool - * @access public */ - function _dir_rewinddir() + private function _dir_rewinddir() { $this->pos = 0; return true; @@ -591,9 +562,8 @@ class Stream * Close directory handle * * @return bool - * @access public */ - function _dir_closedir() + private function _dir_closedir() { return true; } @@ -607,11 +577,10 @@ class Stream * @param int $mode * @param int $options * @return bool - * @access public */ - function _mkdir($path, $mode, $options) + private function _mkdir($path, $mode, $options) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } @@ -630,11 +599,10 @@ class Stream * @param string $path * @param int $options * @return bool - * @access public */ - function _rmdir($path, $options) + private function _rmdir($path, $options) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } @@ -645,12 +613,11 @@ class Stream /** * Flushes the output * - * See . Always returns true because \phpseclib\Net\SFTP doesn't cache stuff before writing + * See . Always returns true because \phpseclib3\Net\SFTP doesn't cache stuff before writing * * @return bool - * @access public */ - function _stream_flush() + private function _stream_flush() { return true; } @@ -659,9 +626,8 @@ class Stream * Retrieve information about a file resource * * @return mixed - * @access public */ - function _stream_stat() + private function _stream_stat() { $results = $this->sftp->stat($this->path); if ($results === false) { @@ -675,11 +641,10 @@ class Stream * * @param string $path * @return bool - * @access public */ - function _unlink($path) + private function _unlink($path) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } @@ -690,18 +655,17 @@ class Stream /** * Retrieve information about a file * - * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib\Net\SFTP\Stream is quiet by default + * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib3\Net\SFTP\Stream is quiet by default * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll * cross that bridge when and if it's reached * * @param string $path * @param int $flags * @return mixed - * @access public */ - function _url_stat($path, $flags) + private function _url_stat($path, $flags) { - $path = $this->_parse_path($path); + $path = $this->parse_path($path); if ($path === false) { return false; } @@ -719,9 +683,8 @@ class Stream * * @param int $new_size * @return bool - * @access public */ - function _stream_truncate($new_size) + private function _stream_truncate($new_size) { if (!$this->sftp->truncate($this->path, $new_size)) { return false; @@ -737,15 +700,14 @@ class Stream * Change stream options * * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. - * The other two aren't supported because of limitations in \phpseclib\Net\SFTP. + * The other two aren't supported because of limitations in \phpseclib3\Net\SFTP. * * @param int $option * @param int $arg1 * @param int $arg2 * @return bool - * @access public */ - function _stream_set_option($option, $arg1, $arg2) + private function _stream_set_option($option, $arg1, $arg2) { return false; } @@ -753,9 +715,8 @@ class Stream /** * Close an resource * - * @access public */ - function _stream_close() + private function _stream_close() { } @@ -772,9 +733,8 @@ class Stream * @param string $name * @param array $arguments * @return mixed - * @access public */ - function __call($name, $arguments) + public function __call($name, array $arguments) { if (defined('NET_SFTP_STREAM_LOGGING')) { echo $name . '('; @@ -791,6 +751,6 @@ class Stream if (!method_exists($this, $name)) { return false; } - return call_user_func_array(array($this, $name), $arguments); + return $this->$name(...$arguments); } } diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php new file mode 100644 index 000000000..581b05966 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php @@ -0,0 +1,5337 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * + * login('username', $key)) { + * exit('Login Failed'); + * } + * + * echo $ssh->read('username@username:~$'); + * $ssh->write("ls -la\n"); + * echo $ssh->read('username@username:~$'); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Blowfish; +use phpseclib3\Crypt\ChaCha20; +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\Common\SymmetricKey; +use phpseclib3\Crypt\DH; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RC4; +use phpseclib3\Crypt\Rijndael; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\TripleDES; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. +use phpseclib3\Crypt\Twofish; +use phpseclib3\Exception\ConnectionClosedException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\NoSupportedAlgorithmsException; +use phpseclib3\Exception\UnableToConnectException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; +use phpseclib3\System\SSH\Agent; + +/** + * Pure-PHP implementation of SSHv2. + * + * @author Jim Wigginton + */ +class SSH2 +{ + /**#@+ + * Compression Types + * + */ + /** + * No compression + */ + const NET_SSH2_COMPRESSION_NONE = 1; + /** + * zlib compression + */ + const NET_SSH2_COMPRESSION_ZLIB = 2; + /** + * zlib@openssh.com + */ + const NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH = 3; + /**#@-*/ + + // Execution Bitmap Masks + const MASK_CONSTRUCTOR = 0x00000001; + const MASK_CONNECTED = 0x00000002; + const MASK_LOGIN_REQ = 0x00000004; + const MASK_LOGIN = 0x00000008; + const MASK_SHELL = 0x00000010; + const MASK_WINDOW_ADJUST = 0x00000020; + + /* + * Channel constants + * + * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer + * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with + * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a + * recipient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel + * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snippet: + * The 'recipient channel' is the channel number given in the original + * open request, and 'sender channel' is the channel number allocated by + * the other side. + * + * @see \phpseclib3\Net\SSH2::send_channel_packet() + * @see \phpseclib3\Net\SSH2::get_channel_packet() + */ + const CHANNEL_EXEC = 1; // PuTTy uses 0x100 + const CHANNEL_SHELL = 2; + const CHANNEL_SUBSYSTEM = 3; + const CHANNEL_AGENT_FORWARD = 4; + const CHANNEL_KEEP_ALIVE = 5; + + /** + * Returns the message numbers + * + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_SIMPLE = 1; + /** + * Returns the message content + * + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_COMPLEX = 2; + /** + * Outputs the content real-time + */ + const LOG_REALTIME = 3; + /** + * Dumps the content real-time to a file + */ + const LOG_REALTIME_FILE = 4; + /** + * Outputs the message numbers real-time + */ + const LOG_SIMPLE_REALTIME = 5; + /** + * Make sure that the log never gets larger than this + * + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_MAX_SIZE = 1048576; // 1024 * 1024 + + /** + * Returns when a string matching $expect exactly is found + * + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_SIMPLE = 1; + /** + * Returns when a string matching the regular expression $expect is found + * + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_REGEX = 2; + /** + * Returns whenever a data packet is received. + * + * Some data packets may only contain a single character so it may be necessary + * to call read() multiple times when using this option + * + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_NEXT = 3; + + /** + * The SSH identifier + * + * @var string + */ + private $identifier; + + /** + * The Socket Object + * + * @var resource|closed-resource|null + */ + public $fsock; + + /** + * Execution Bitmap + * + * The bits that are set represent functions that have been called already. This is used to determine + * if a requisite function has been successfully executed. If not, an error should be thrown. + * + * @var int + */ + protected $bitmap = 0; + + /** + * Error information + * + * @see self::getErrors() + * @see self::getLastError() + * @var array + */ + private $errors = []; + + /** + * Server Identifier + * + * @see self::getServerIdentification() + * @var string|false + */ + protected $server_identifier = false; + + /** + * Key Exchange Algorithms + * + * @see self::getKexAlgorithims() + * @var array|false + */ + private $kex_algorithms = false; + + /** + * Key Exchange Algorithm + * + * @see self::getMethodsNegotiated() + * @var string|false + */ + private $kex_algorithm = false; + + /** + * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + */ + private $kex_dh_group_size_min = 1536; + + /** + * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + */ + private $kex_dh_group_size_preferred = 2048; + + /** + * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + */ + private $kex_dh_group_size_max = 4096; + + /** + * Server Host Key Algorithms + * + * @see self::getServerHostKeyAlgorithms() + * @var array|false + */ + private $server_host_key_algorithms = false; + + /** + * Supported Private Key Algorithms + * + * In theory this should be the same as the Server Host Key Algorithms but, in practice, + * some servers (eg. Azure) will support rsa-sha2-512 as a server host key algorithm but + * not a private key algorithm + * + * @see self::privatekey_login() + * @var array|false + */ + private $supported_private_key_algorithms = false; + + /** + * Encryption Algorithms: Client to Server + * + * @see self::getEncryptionAlgorithmsClient2Server() + * @var array|false + */ + private $encryption_algorithms_client_to_server = false; + + /** + * Encryption Algorithms: Server to Client + * + * @see self::getEncryptionAlgorithmsServer2Client() + * @var array|false + */ + private $encryption_algorithms_server_to_client = false; + + /** + * MAC Algorithms: Client to Server + * + * @see self::getMACAlgorithmsClient2Server() + * @var array|false + */ + private $mac_algorithms_client_to_server = false; + + /** + * MAC Algorithms: Server to Client + * + * @see self::getMACAlgorithmsServer2Client() + * @var array|false + */ + private $mac_algorithms_server_to_client = false; + + /** + * Compression Algorithms: Client to Server + * + * @see self::getCompressionAlgorithmsClient2Server() + * @var array|false + */ + private $compression_algorithms_client_to_server = false; + + /** + * Compression Algorithms: Server to Client + * + * @see self::getCompressionAlgorithmsServer2Client() + * @var array|false + */ + private $compression_algorithms_server_to_client = false; + + /** + * Languages: Server to Client + * + * @see self::getLanguagesServer2Client() + * @var array|false + */ + private $languages_server_to_client = false; + + /** + * Languages: Client to Server + * + * @see self::getLanguagesClient2Server() + * @var array|false + */ + private $languages_client_to_server = false; + + /** + * Preferred Algorithms + * + * @see self::setPreferredAlgorithms() + * @var array + */ + private $preferred = []; + + /** + * Block Size for Server to Client Encryption + * + * "Note that the length of the concatenation of 'packet_length', + * 'padding_length', 'payload', and 'random padding' MUST be a multiple + * of the cipher block size or 8, whichever is larger. This constraint + * MUST be enforced, even when using stream ciphers." + * + * -- http://tools.ietf.org/html/rfc4253#section-6 + * + * @see self::__construct() + * @see self::_send_binary_packet() + * @var int + */ + private $encrypt_block_size = 8; + + /** + * Block Size for Client to Server Encryption + * + * @see self::__construct() + * @see self::_get_binary_packet() + * @var int + */ + private $decrypt_block_size = 8; + + /** + * Server to Client Encryption Object + * + * @see self::_get_binary_packet() + * @var SymmetricKey|false + */ + private $decrypt = false; + + /** + * Decryption Algorithm Name + * + * @var string|null + */ + private $decryptName; + + /** + * Decryption Invocation Counter + * + * Used by GCM + * + * @var string|null + */ + private $decryptInvocationCounter; + + /** + * Fixed Part of Nonce + * + * Used by GCM + * + * @var string|null + */ + private $decryptFixedPart; + + /** + * Server to Client Length Encryption Object + * + * @see self::_get_binary_packet() + * @var object + */ + private $lengthDecrypt = false; + + /** + * Client to Server Encryption Object + * + * @see self::_send_binary_packet() + * @var SymmetricKey|false + */ + private $encrypt = false; + + /** + * Encryption Algorithm Name + * + * @var string|null + */ + private $encryptName; + + /** + * Encryption Invocation Counter + * + * Used by GCM + * + * @var string|null + */ + private $encryptInvocationCounter; + + /** + * Fixed Part of Nonce + * + * Used by GCM + * + * @var string|null + */ + private $encryptFixedPart; + + /** + * Client to Server Length Encryption Object + * + * @see self::_send_binary_packet() + * @var object + */ + private $lengthEncrypt = false; + + /** + * Client to Server HMAC Object + * + * @see self::_send_binary_packet() + * @var object + */ + private $hmac_create = false; + + /** + * Client to Server HMAC Name + * + * @var string|false + */ + private $hmac_create_name; + + /** + * Client to Server ETM + * + * @var int|false + */ + private $hmac_create_etm; + + /** + * Server to Client HMAC Object + * + * @see self::_get_binary_packet() + * @var object + */ + private $hmac_check = false; + + /** + * Server to Client HMAC Name + * + * @var string|false + */ + private $hmac_check_name; + + /** + * Server to Client ETM + * + * @var int|false + */ + private $hmac_check_etm; + + /** + * Size of server to client HMAC + * + * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read. + * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is + * append it. + * + * @see self::_get_binary_packet() + * @var int + */ + private $hmac_size = false; + + /** + * Server Public Host Key + * + * @see self::getServerPublicHostKey() + * @var string + */ + private $server_public_host_key; + + /** + * Session identifier + * + * "The exchange hash H from the first key exchange is additionally + * used as the session identifier, which is a unique identifier for + * this connection." + * + * -- http://tools.ietf.org/html/rfc4253#section-7.2 + * + * @see self::_key_exchange() + * @var string + */ + private $session_id = false; + + /** + * Exchange hash + * + * The current exchange hash + * + * @see self::_key_exchange() + * @var string + */ + private $exchange_hash = false; + + /** + * Message Numbers + * + * @see self::__construct() + * @var array + * @access private + */ + private static $message_numbers = []; + + /** + * Disconnection Message 'reason codes' defined in RFC4253 + * + * @see self::__construct() + * @var array + * @access private + */ + private static $disconnect_reasons = []; + + /** + * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 + * + * @see self::__construct() + * @var array + * @access private + */ + private static $channel_open_failure_reasons = []; + + /** + * Terminal Modes + * + * @link http://tools.ietf.org/html/rfc4254#section-8 + * @see self::__construct() + * @var array + * @access private + */ + private static $terminal_modes = []; + + /** + * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes + * + * @link http://tools.ietf.org/html/rfc4254#section-5.2 + * @see self::__construct() + * @var array + * @access private + */ + private static $channel_extended_data_type_codes = []; + + /** + * Send Sequence Number + * + * See 'Section 6.4. Data Integrity' of rfc4253 for more info. + * + * @see self::_send_binary_packet() + * @var int + */ + private $send_seq_no = 0; + + /** + * Get Sequence Number + * + * See 'Section 6.4. Data Integrity' of rfc4253 for more info. + * + * @see self::_get_binary_packet() + * @var int + */ + private $get_seq_no = 0; + + /** + * Server Channels + * + * Maps client channels to server channels + * + * @see self::get_channel_packet() + * @see self::exec() + * @var array + */ + protected $server_channels = []; + + /** + * Channel Buffers + * + * If a client requests a packet from one channel but receives two packets from another those packets should + * be placed in a buffer + * + * @see self::get_channel_packet() + * @see self::exec() + * @var array + */ + private $channel_buffers = []; + + /** + * Channel Status + * + * Contains the type of the last sent message + * + * @see self::get_channel_packet() + * @var array + */ + protected $channel_status = []; + + /** + * The identifier of the interactive channel which was opened most recently + * + * @see self::getInteractiveChannelId() + * @var int + */ + private $channel_id_last_interactive = 0; + + /** + * Packet Size + * + * Maximum packet size indexed by channel + * + * @see self::send_channel_packet() + * @var array + */ + private $packet_size_client_to_server = []; + + /** + * Message Number Log + * + * @see self::getLog() + * @var array + */ + private $message_number_log = []; + + /** + * Message Log + * + * @see self::getLog() + * @var array + */ + private $message_log = []; + + /** + * The Window Size + * + * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) + * + * @var int + * @see self::send_channel_packet() + * @see self::exec() + */ + protected $window_size = 0x7FFFFFFF; + + /** + * What we resize the window to + * + * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes. + * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so + * we'll just do what PuTTY does + * + * @var int + * @see self::_send_channel_packet() + * @see self::exec() + */ + private $window_resize = 0x40000000; + + /** + * Window size, server to client + * + * Window size indexed by channel + * + * @see self::send_channel_packet() + * @var array + */ + protected $window_size_server_to_client = []; + + /** + * Window size, client to server + * + * Window size indexed by channel + * + * @see self::get_channel_packet() + * @var array + */ + private $window_size_client_to_server = []; + + /** + * Server signature + * + * Verified against $this->session_id + * + * @see self::getServerPublicHostKey() + * @var string + */ + private $signature = ''; + + /** + * Server signature format + * + * ssh-rsa or ssh-dss. + * + * @see self::getServerPublicHostKey() + * @var string + */ + private $signature_format = ''; + + /** + * Interactive Buffer + * + * @see self::read() + * @var string + */ + private $interactiveBuffer = ''; + + /** + * Current log size + * + * Should never exceed self::LOG_MAX_SIZE + * + * @see self::_send_binary_packet() + * @see self::_get_binary_packet() + * @var int + */ + private $log_size; + + /** + * Timeout + * + * @see self::setTimeout() + */ + protected $timeout; + + /** + * Current Timeout + * + * @see self::get_channel_packet() + */ + protected $curTimeout; + + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + */ + private $keepAlive; + + /** + * Real-time log file pointer + * + * @see self::_append_log() + * @var resource|closed-resource + */ + private $realtime_log_file; + + /** + * Real-time log file size + * + * @see self::_append_log() + * @var int + */ + private $realtime_log_size; + + /** + * Has the signature been validated? + * + * @see self::getServerPublicHostKey() + * @var bool + */ + private $signature_validated = false; + + /** + * Real-time log file wrap boolean + * + * @see self::_append_log() + * @var bool + */ + private $realtime_log_wrap; + + /** + * Flag to suppress stderr from output + * + * @see self::enableQuietMode() + */ + private $quiet_mode = false; + + /** + * Time of first network activity + * + * @var float + */ + private $last_packet; + + /** + * Exit status returned from ssh if any + * + * @var int + */ + private $exit_status; + + /** + * Flag to request a PTY when using exec() + * + * @var bool + * @see self::enablePTY() + */ + private $request_pty = false; + + /** + * Contents of stdError + * + * @var string + */ + private $stdErrorLog; + + /** + * The Last Interactive Response + * + * @see self::_keyboard_interactive_process() + * @var string + */ + private $last_interactive_response = ''; + + /** + * Keyboard Interactive Request / Responses + * + * @see self::_keyboard_interactive_process() + * @var array + */ + private $keyboard_requests_responses = []; + + /** + * Banner Message + * + * Quoting from the RFC, "in some jurisdictions, sending a warning message before + * authentication may be relevant for getting legal protection." + * + * @see self::_filter() + * @see self::getBannerMessage() + * @var string + */ + private $banner_message = ''; + + /** + * Did read() timeout or return normally? + * + * @see self::isTimeout() + * @var bool + */ + private $is_timeout = false; + + /** + * Log Boundary + * + * @see self::_format_log() + * @var string + */ + private $log_boundary = ':'; + + /** + * Log Long Width + * + * @see self::_format_log() + * @var int + */ + private $log_long_width = 65; + + /** + * Log Short Width + * + * @see self::_format_log() + * @var int + */ + private $log_short_width = 16; + + /** + * Hostname + * + * @see self::__construct() + * @see self::_connect() + * @var string + */ + private $host; + + /** + * Port Number + * + * @see self::__construct() + * @see self::_connect() + * @var int + */ + private $port; + + /** + * Number of columns for terminal window size + * + * @see self::getWindowColumns() + * @see self::setWindowColumns() + * @see self::setWindowSize() + * @var int + */ + private $windowColumns = 80; + + /** + * Number of columns for terminal window size + * + * @see self::getWindowRows() + * @see self::setWindowRows() + * @see self::setWindowSize() + * @var int + */ + private $windowRows = 24; + + /** + * Crypto Engine + * + * @see self::setCryptoEngine() + * @see self::_key_exchange() + * @var int + */ + private static $crypto_engine = false; + + /** + * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario + * + * @var Agent + */ + private $agent; + + /** + * Connection storage to replicates ssh2 extension functionality: + * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples} + * + * @var array> + */ + private static $connections; + + /** + * Send the identification string first? + * + * @var bool + */ + private $send_id_string_first = true; + + /** + * Send the key exchange initiation packet first? + * + * @var bool + */ + private $send_kex_first = true; + + /** + * Some versions of OpenSSH incorrectly calculate the key size + * + * @var bool + */ + private $bad_key_size_fix = false; + + /** + * Should we try to re-connect to re-establish keys? + * + * @var bool + */ + private $retry_connect = false; + + /** + * Binary Packet Buffer + * + * @var string|false + */ + private $binary_packet_buffer = false; + + /** + * Preferred Signature Format + * + * @var string|false + */ + protected $preferred_signature_format = false; + + /** + * Authentication Credentials + * + * @var array + */ + protected $auth = []; + + /** + * Terminal + * + * @var string + */ + private $term = 'vt100'; + + /** + * The authentication methods that may productively continue authentication. + * + * @see https://tools.ietf.org/html/rfc4252#section-5.1 + * @var array|null + */ + private $auth_methods_to_continue = null; + + /** + * Compression method + * + * @var int + */ + private $compress = self::NET_SSH2_COMPRESSION_NONE; + + /** + * Decompression method + * + * @var int + */ + private $decompress = self::NET_SSH2_COMPRESSION_NONE; + + /** + * Compression context + * + * @var resource|false|null + */ + private $compress_context; + + /** + * Decompression context + * + * @var resource|object + */ + private $decompress_context; + + /** + * Regenerate Compression Context + * + * @var bool + */ + private $regenerate_compression_context = false; + + /** + * Regenerate Decompression Context + * + * @var bool + */ + private $regenerate_decompression_context = false; + + /** + * Smart multi-factor authentication flag + * + * @var bool + */ + private $smartMFA = true; + + /** + * How many channels are currently opened + * + * @var int + */ + private $channelCount = 0; + + /** + * Does the server support multiple channels? If not then error out + * when multiple channels are attempted to be opened + * + * @var bool + */ + private $errorOnMultipleChannels; + + /** + * Default Constructor. + * + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host + * @param int $port + * @param int $timeout + * @see self::login() + */ + public function __construct($host, $port = 22, $timeout = 10) + { + if (empty(self::$message_numbers)) { + self::$message_numbers = [ + 1 => 'NET_SSH2_MSG_DISCONNECT', + 2 => 'NET_SSH2_MSG_IGNORE', + 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', + 4 => 'NET_SSH2_MSG_DEBUG', + 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', + 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', + 20 => 'NET_SSH2_MSG_KEXINIT', + 21 => 'NET_SSH2_MSG_NEWKEYS', + 30 => 'NET_SSH2_MSG_KEXDH_INIT', + 31 => 'NET_SSH2_MSG_KEXDH_REPLY', + 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', + 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', + 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', + 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', + + 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', + 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', + 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', + 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', + 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', + 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', + 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', + 94 => 'NET_SSH2_MSG_CHANNEL_DATA', + 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', + 96 => 'NET_SSH2_MSG_CHANNEL_EOF', + 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', + 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', + 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', + 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' + ]; + self::$disconnect_reasons = [ + 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', + 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', + 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', + 4 => 'NET_SSH2_DISCONNECT_RESERVED', + 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', + 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', + 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', + 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', + 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', + 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', + 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', + 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', + 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', + 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', + 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' + ]; + self::$channel_open_failure_reasons = [ + 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' + ]; + self::$terminal_modes = [ + 0 => 'NET_SSH2_TTY_OP_END' + ]; + self::$channel_extended_data_type_codes = [ + 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' + ]; + + self::define_array( + self::$message_numbers, + self::$disconnect_reasons, + self::$channel_open_failure_reasons, + self::$terminal_modes, + self::$channel_extended_data_type_codes, + [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], + [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], + [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', + 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], + // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} + [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', + 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', + 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', + 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', + 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], + // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) + [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', + 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] + ); + } + + /** + * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508 + * @var \WeakReference|SSH2 + */ + self::$connections[$this->getResourceId()] = class_exists('WeakReference') + ? \WeakReference::create($this) + : $this; + + if (is_resource($host)) { + $this->fsock = $host; + return; + } + + if (Strings::is_stringable($host)) { + $this->host = $host; + $this->port = $port; + $this->timeout = $timeout; + } + } + + /** + * Set Crypto Engine Mode + * + * Possible $engine values: + * OpenSSL, mcrypt, Eval, PHP + * + * @param int $engine + */ + public static function setCryptoEngine($engine) + { + self::$crypto_engine = $engine; + } + + /** + * Send Identification String First + * + * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, + * both sides MUST send an identification string". It does not say which side sends it first. In + * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendIdentificationStringFirst() + { + $this->send_id_string_first = true; + } + + /** + * Send Identification String Last + * + * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, + * both sides MUST send an identification string". It does not say which side sends it first. In + * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendIdentificationStringLast() + { + $this->send_id_string_first = false; + } + + /** + * Send SSH_MSG_KEXINIT First + * + * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending + * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory + * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendKEXINITFirst() + { + $this->send_kex_first = true; + } + + /** + * Send SSH_MSG_KEXINIT Last + * + * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending + * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory + * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendKEXINITLast() + { + $this->send_kex_first = false; + } + + /** + * stream_select wrapper + * + * Quoting https://stackoverflow.com/a/14262151/569976, + * "The general approach to `EINTR` is to simply handle the error and retry the operation again" + * + * This wrapper does that loop + */ + private static function stream_select(&$read, &$write, &$except, $seconds, $microseconds = null) + { + $remaining = $seconds + $microseconds / 1000000; + $start = microtime(true); + while (true) { + $result = @stream_select($read, $write, $except, $seconds, $microseconds); + if ($result !== false) { + return $result; + } + $elapsed = microtime(true) - $start; + $seconds = (int) ($remaining - floor($elapsed)); + $microseconds = (int) (1000000 * ($remaining - $seconds)); + if ($elapsed >= $remaining) { + return false; + } + } + } + + /** + * Connect to an SSHv2 server + * + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + private function connect() + { + if ($this->bitmap & self::MASK_CONSTRUCTOR) { + return; + } + + $this->bitmap |= self::MASK_CONSTRUCTOR; + + $this->curTimeout = $this->timeout; + + $this->last_packet = microtime(true); + + if (!is_resource($this->fsock)) { + $start = microtime(true); + // with stream_select a timeout of 0 means that no timeout takes place; + // with fsockopen a timeout of 0 means that you instantly timeout + // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0 + $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); + if (!$this->fsock) { + $host = $this->host . ':' . $this->port; + throw new UnableToConnectException(rtrim("Cannot connect to $host. Error $errno. $errstr")); + } + $elapsed = microtime(true) - $start; + + if ($this->curTimeout) { + $this->curTimeout -= $elapsed; + if ($this->curTimeout < 0) { + throw new \RuntimeException('Connection timed out whilst attempting to open socket connection'); + } + } + } + + $this->identifier = $this->generate_identifier(); + + if ($this->send_id_string_first) { + fputs($this->fsock, $this->identifier . "\r\n"); + } + + /* According to the SSH2 specs, + + "The server MAY send other lines of data before sending the version + string. Each line SHOULD be terminated by a Carriage Return and Line + Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded + in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients + MUST be able to process such lines." */ + $data = ''; + while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) { + $line = ''; + while (true) { + if ($this->curTimeout) { + if ($this->curTimeout < 0) { + throw new \RuntimeException('Connection timed out whilst receiving server identification string'); + } + $read = [$this->fsock]; + $write = $except = null; + $start = microtime(true); + $sec = (int) floor($this->curTimeout); + $usec = (int) (1000000 * ($this->curTimeout - $sec)); + if (static::stream_select($read, $write, $except, $sec, $usec) === false) { + throw new \RuntimeException('Connection timed out whilst receiving server identification string'); + } + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + } + + $temp = stream_get_line($this->fsock, 255, "\n"); + if ($temp === false) { + throw new \RuntimeException('Error reading from socket'); + } + if (strlen($temp) == 255) { + continue; + } + + $line .= "$temp\n"; + + // quoting RFC4253, "Implementers who wish to maintain + // compatibility with older, undocumented versions of this protocol may + // want to process the identification string without expecting the + // presence of the carriage return character for reasons described in + // Section 5 of this document." + + //if (substr($line, -2) == "\r\n") { + // break; + //} + + break; + } + + $data .= $line; + } + + if (feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed by server'); + } + + $extra = $matches[1]; + + if (defined('NET_SSH2_LOGGING')) { + $this->append_log('<-', $matches[0]); + $this->append_log('->', $this->identifier . "\r\n"); + } + + $this->server_identifier = trim($temp, "\r\n"); + if (strlen($extra)) { + $this->errors[] = $data; + } + + if (version_compare($matches[3], '1.99', '<')) { + $this->bitmap = 0; + throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); + } + + // Ubuntu's OpenSSH from 5.8 to 6.9 didn't work with multiple channels. see + // https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1334916 for more info. + // https://lists.ubuntu.com/archives/oneiric-changes/2011-July/005772.html discusses + // when consolekit was incorporated. + // https://marc.info/?l=openssh-unix-dev&m=163409903417589&w=2 discusses some of the + // issues with how Ubuntu incorporated consolekit + $pattern = '#^SSH-2\.0-OpenSSH_([\d.]+)[^ ]* Ubuntu-.*$#'; + $match = preg_match($pattern, $this->server_identifier, $matches); + $match = $match && version_compare('5.8', $matches[1], '<='); + $match = $match && version_compare('6.9', $matches[1], '>='); + $this->errorOnMultipleChannels = $match; + + if (!$this->send_id_string_first) { + fputs($this->fsock, $this->identifier . "\r\n"); + } + + if (!$this->send_kex_first) { + $response = $this->get_binary_packet(); + + if (is_bool($response) || !strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) { + $this->bitmap = 0; + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + } + + $this->key_exchange($response); + } + + if ($this->send_kex_first) { + $this->key_exchange(); + } + + $this->bitmap |= self::MASK_CONNECTED; + + return true; + } + + /** + * Generates the SSH identifier + * + * You should overwrite this method in your own class if you want to use another identifier + * + * @return string + */ + private function generate_identifier() + { + $identifier = 'SSH-2.0-phpseclib_3.0'; + + $ext = []; + if (extension_loaded('sodium')) { + $ext[] = 'libsodium'; + } + + if (extension_loaded('openssl')) { + $ext[] = 'openssl'; + } elseif (extension_loaded('mcrypt')) { + $ext[] = 'mcrypt'; + } + + if (extension_loaded('gmp')) { + $ext[] = 'gmp'; + } elseif (extension_loaded('bcmath')) { + $ext[] = 'bcmath'; + } + + if (!empty($ext)) { + $identifier .= ' (' . implode(', ', $ext) . ')'; + } + + return $identifier; + } + + /** + * Key Exchange + * + * @return bool + * @param string|bool $kexinit_payload_server optional + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible + */ + private function key_exchange($kexinit_payload_server = false) + { + $preferred = $this->preferred; + $send_kex = true; + + $kex_algorithms = isset($preferred['kex']) ? + $preferred['kex'] : + SSH2::getSupportedKEXAlgorithms(); + $server_host_key_algorithms = isset($preferred['hostkey']) ? + $preferred['hostkey'] : + SSH2::getSupportedHostKeyAlgorithms(); + $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? + $preferred['server_to_client']['crypt'] : + SSH2::getSupportedEncryptionAlgorithms(); + $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? + $preferred['client_to_server']['crypt'] : + SSH2::getSupportedEncryptionAlgorithms(); + $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? + $preferred['server_to_client']['mac'] : + SSH2::getSupportedMACAlgorithms(); + $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? + $preferred['client_to_server']['mac'] : + SSH2::getSupportedMACAlgorithms(); + $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? + $preferred['server_to_client']['comp'] : + SSH2::getSupportedCompressionAlgorithms(); + $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? + $preferred['client_to_server']['comp'] : + SSH2::getSupportedCompressionAlgorithms(); + + // some SSH servers have buggy implementations of some of the above algorithms + switch (true) { + case $this->server_identifier == 'SSH-2.0-SSHD': + case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK': + if (!isset($preferred['server_to_client']['mac'])) { + $s2c_mac_algorithms = array_values(array_diff( + $s2c_mac_algorithms, + ['hmac-sha1-96', 'hmac-md5-96'] + )); + } + if (!isset($preferred['client_to_server']['mac'])) { + $c2s_mac_algorithms = array_values(array_diff( + $c2s_mac_algorithms, + ['hmac-sha1-96', 'hmac-md5-96'] + )); + } + } + + $client_cookie = Random::string(16); + + $kexinit_payload_client = pack('Ca*', NET_SSH2_MSG_KEXINIT, $client_cookie); + $kexinit_payload_client .= Strings::packSSH2( + 'L10bN', + $kex_algorithms, + $server_host_key_algorithms, + $c2s_encryption_algorithms, + $s2c_encryption_algorithms, + $c2s_mac_algorithms, + $s2c_mac_algorithms, + $c2s_compression_algorithms, + $s2c_compression_algorithms, + [], // language, client to server + [], // language, server to client + false, // first_kex_packet_follows + 0 // reserved for future extension + ); + + if ($kexinit_payload_server === false) { + $this->send_binary_packet($kexinit_payload_client); + + $kexinit_payload_server = $this->get_binary_packet(); + + if ( + is_bool($kexinit_payload_server) + || !strlen($kexinit_payload_server) + || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT + ) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + } + + $send_kex = false; + } + + $response = $kexinit_payload_server; + Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) + $server_cookie = Strings::shift($response, 16); + + list( + $this->kex_algorithms, + $this->server_host_key_algorithms, + $this->encryption_algorithms_client_to_server, + $this->encryption_algorithms_server_to_client, + $this->mac_algorithms_client_to_server, + $this->mac_algorithms_server_to_client, + $this->compression_algorithms_client_to_server, + $this->compression_algorithms_server_to_client, + $this->languages_client_to_server, + $this->languages_server_to_client, + $first_kex_packet_follows + ) = Strings::unpackSSH2('L10C', $response); + + $this->supported_private_key_algorithms = $this->server_host_key_algorithms; + + if ($send_kex) { + $this->send_binary_packet($kexinit_payload_client); + } + + // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange + + // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the + // diffie-hellman key exchange as fast as possible + $decrypt = self::array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); + $decryptKeyLength = $this->encryption_algorithm_to_key_size($decrypt); + if ($decryptKeyLength === null) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found'); + } + + $encrypt = self::array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); + $encryptKeyLength = $this->encryption_algorithm_to_key_size($encrypt); + if ($encryptKeyLength === null) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); + } + + // through diffie-hellman key exchange a symmetric key is obtained + $this->kex_algorithm = self::array_intersect_first($kex_algorithms, $this->kex_algorithms); + if ($this->kex_algorithm === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); + } + + $server_host_key_algorithm = self::array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); + if ($server_host_key_algorithm === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); + } + + $mac_algorithm_out = self::array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); + if ($mac_algorithm_out === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); + } + + $mac_algorithm_in = self::array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); + if ($mac_algorithm_in === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); + } + + $compression_map = [ + 'none' => self::NET_SSH2_COMPRESSION_NONE, + 'zlib' => self::NET_SSH2_COMPRESSION_ZLIB, + 'zlib@openssh.com' => self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH + ]; + + $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); + if ($compression_algorithm_in === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); + } + $this->decompress = $compression_map[$compression_algorithm_in]; + + $compression_algorithm_out = self::array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_out === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); + } + $this->compress = $compression_map[$compression_algorithm_out]; + + switch ($this->kex_algorithm) { + case 'diffie-hellman-group15-sha512': + case 'diffie-hellman-group16-sha512': + case 'diffie-hellman-group17-sha512': + case 'diffie-hellman-group18-sha512': + case 'ecdh-sha2-nistp521': + $kexHash = new Hash('sha512'); + break; + case 'ecdh-sha2-nistp384': + $kexHash = new Hash('sha384'); + break; + case 'diffie-hellman-group-exchange-sha256': + case 'diffie-hellman-group14-sha256': + case 'ecdh-sha2-nistp256': + case 'curve25519-sha256@libssh.org': + case 'curve25519-sha256': + $kexHash = new Hash('sha256'); + break; + default: + $kexHash = new Hash('sha1'); + } + + // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. + + $exchange_hash_rfc4419 = ''; + + if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { + $curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? + 'Curve25519' : + substr($this->kex_algorithm, 10); + $ourPrivate = EC::createKey($curve); + $ourPublicBytes = $ourPrivate->getPublicKey()->getEncodedCoordinates(); + $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; + } else { + if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { + $dh_group_sizes_packed = pack( + 'NNN', + $this->kex_dh_group_size_min, + $this->kex_dh_group_size_preferred, + $this->kex_dh_group_size_max + ); + $packet = pack( + 'Ca*', + NET_SSH2_MSG_KEXDH_GEX_REQUEST, + $dh_group_sizes_packed + ); + $this->send_binary_packet($packet); + $this->updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); + + $response = $this->get_binary_packet(); + + list($type, $primeBytes, $gBytes) = Strings::unpackSSH2('Css', $response); + if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); + } + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); + $prime = new BigInteger($primeBytes, -256); + $g = new BigInteger($gBytes, -256); + + $exchange_hash_rfc4419 = $dh_group_sizes_packed . Strings::packSSH2( + 'ss', + $primeBytes, + $gBytes + ); + + $params = DH::createParameters($prime, $g); + $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; + } else { + $params = DH::createParameters($this->kex_algorithm); + $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; + } + + $keyLength = min($kexHash->getLengthInBytes(), max($encryptKeyLength, $decryptKeyLength)); + + $ourPrivate = DH::createKey($params, 16 * $keyLength); // 2 * 8 * $keyLength + $ourPublic = $ourPrivate->getPublicKey()->toBigInteger(); + $ourPublicBytes = $ourPublic->toBytes(true); + } + + $data = pack('CNa*', constant($clientKexInitMessage), strlen($ourPublicBytes), $ourPublicBytes); + + $this->send_binary_packet($data); + + switch ($clientKexInitMessage) { + case 'NET_SSH2_MSG_KEX_ECDH_INIT': + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); + break; + case 'NET_SSH2_MSG_KEXDH_GEX_INIT': + $this->updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); + } + + $response = $this->get_binary_packet(); + + list( + $type, + $server_public_host_key, + $theirPublicBytes, + $this->signature + ) = Strings::unpackSSH2('Csss', $response); + + if ($type != constant($serverKexReplyMessage)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException("Expected $serverKexReplyMessage"); + } + switch ($serverKexReplyMessage) { + case 'NET_SSH2_MSG_KEX_ECDH_REPLY': + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); + break; + case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': + $this->updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); + } + + $this->server_public_host_key = $server_public_host_key; + list($public_key_format) = Strings::unpackSSH2('s', $server_public_host_key); + if (strlen($this->signature) < 4) { + throw new \LengthException('The signature needs at least four bytes'); + } + $temp = unpack('Nlength', substr($this->signature, 0, 4)); + $this->signature_format = substr($this->signature, 4, $temp['length']); + + $keyBytes = DH::computeSecret($ourPrivate, $theirPublicBytes); + if (($keyBytes & "\xFF\x80") === "\x00\x00") { + $keyBytes = substr($keyBytes, 1); + } elseif (($keyBytes[0] & "\x80") === "\x80") { + $keyBytes = "\0$keyBytes"; + } + + $this->exchange_hash = Strings::packSSH2( + 's5', + $this->identifier, + $this->server_identifier, + $kexinit_payload_client, + $kexinit_payload_server, + $this->server_public_host_key + ); + $this->exchange_hash .= $exchange_hash_rfc4419; + $this->exchange_hash .= Strings::packSSH2( + 's3', + $ourPublicBytes, + $theirPublicBytes, + $keyBytes + ); + + $this->exchange_hash = $kexHash->hash($this->exchange_hash); + + if ($this->session_id === false) { + $this->session_id = $this->exchange_hash; + } + + switch ($server_host_key_algorithm) { + case 'rsa-sha2-256': + case 'rsa-sha2-512': + //case 'ssh-rsa': + $expected_key_format = 'ssh-rsa'; + break; + default: + $expected_key_format = $server_host_key_algorithm; + } + if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { + switch (true) { + case $this->signature_format == $server_host_key_algorithm: + case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': + case $this->signature_format != 'ssh-rsa': + $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new \RuntimeException('Server Host Key Algorithm Mismatch (' . $this->signature_format . ' vs ' . $server_host_key_algorithm . ')'); + } + } + + $packet = pack('C', NET_SSH2_MSG_NEWKEYS); + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + if ($type != NET_SSH2_MSG_NEWKEYS) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); + } + + $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); + + $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + if ($this->encrypt) { + if (self::$crypto_engine) { + $this->encrypt->setPreferredEngine(self::$crypto_engine); + } + if ($this->encrypt->getBlockLengthInBytes()) { + $this->encrypt_block_size = $this->encrypt->getBlockLengthInBytes(); + } + $this->encrypt->disablePadding(); + + if ($this->encrypt->usesIV()) { + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + while ($this->encrypt_block_size > strlen($iv)) { + $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); + } + $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); + } + + switch ($encrypt) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + $this->encryptFixedPart = substr($nonce, 0, 4); + $this->encryptInvocationCounter = substr($nonce, 4, 8); + // fall-through + case 'chacha20-poly1305@openssh.com': + break; + default: + $this->encrypt->enableContinuousBuffer(); + } + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); + while ($encryptKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + switch ($encrypt) { + case 'chacha20-poly1305@openssh.com': + $encryptKeyLength = 32; + $this->lengthEncrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + $this->lengthEncrypt->setKey(substr($key, 32, 32)); + } + $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); + $this->encryptName = $encrypt; + } + + $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + if ($this->decrypt) { + if (self::$crypto_engine) { + $this->decrypt->setPreferredEngine(self::$crypto_engine); + } + if ($this->decrypt->getBlockLengthInBytes()) { + $this->decrypt_block_size = $this->decrypt->getBlockLengthInBytes(); + } + $this->decrypt->disablePadding(); + + if ($this->decrypt->usesIV()) { + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + while ($this->decrypt_block_size > strlen($iv)) { + $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); + } + $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); + } + + switch ($decrypt) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + // see https://tools.ietf.org/html/rfc5647#section-7.1 + $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + $this->decryptFixedPart = substr($nonce, 0, 4); + $this->decryptInvocationCounter = substr($nonce, 4, 8); + // fall-through + case 'chacha20-poly1305@openssh.com': + break; + default: + $this->decrypt->enableContinuousBuffer(); + } + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); + while ($decryptKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + switch ($decrypt) { + case 'chacha20-poly1305@openssh.com': + $decryptKeyLength = 32; + $this->lengthDecrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + $this->lengthDecrypt->setKey(substr($key, 32, 32)); + } + $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); + $this->decryptName = $decrypt; + } + + /* The "arcfour128" algorithm is the RC4 cipher, as described in + [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream + generated by the cipher MUST be discarded, and the first byte of the + first encrypted packet MUST be encrypted using the 1537th byte of + keystream. + + -- http://tools.ietf.org/html/rfc4345#section-4 */ + if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') { + $this->encrypt->encrypt(str_repeat("\0", 1536)); + } + if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') { + $this->decrypt->decrypt(str_repeat("\0", 1536)); + } + + if (!$this->encrypt->usesNonce()) { + list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out); + } else { + $this->hmac_create = new \stdClass(); + $this->hmac_create_name = $mac_algorithm_out; + //$mac_algorithm_out = 'none'; + $createKeyLength = 0; + } + + if ($this->hmac_create instanceof Hash) { + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); + while ($createKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); + $this->hmac_create_name = $mac_algorithm_out; + $this->hmac_create_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out); + } + + if (!$this->decrypt->usesNonce()) { + list($this->hmac_check, $checkKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_in); + $this->hmac_size = $this->hmac_check->getLengthInBytes(); + } else { + $this->hmac_check = new \stdClass(); + $this->hmac_check_name = $mac_algorithm_in; + //$mac_algorithm_in = 'none'; + $checkKeyLength = 0; + $this->hmac_size = 0; + } + + if ($this->hmac_check instanceof Hash) { + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); + while ($checkKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); + $this->hmac_check_name = $mac_algorithm_in; + $this->hmac_check_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in); + } + + $this->regenerate_compression_context = $this->regenerate_decompression_context = true; + + return true; + } + + /** + * Maps an encryption algorithm name to the number of key bytes. + * + * @param string $algorithm Name of the encryption algorithm + * @return int|null Number of bytes as an integer or null for unknown + */ + private function encryption_algorithm_to_key_size($algorithm) + { + if ($this->bad_key_size_fix && self::bad_algorithm_candidate($algorithm)) { + return 16; + } + + switch ($algorithm) { + case 'none': + return 0; + case 'aes128-gcm@openssh.com': + case 'aes128-cbc': + case 'aes128-ctr': + case 'arcfour': + case 'arcfour128': + case 'blowfish-cbc': + case 'blowfish-ctr': + case 'twofish128-cbc': + case 'twofish128-ctr': + return 16; + case '3des-cbc': + case '3des-ctr': + case 'aes192-cbc': + case 'aes192-ctr': + case 'twofish192-cbc': + case 'twofish192-ctr': + return 24; + case 'aes256-gcm@openssh.com': + case 'aes256-cbc': + case 'aes256-ctr': + case 'arcfour256': + case 'twofish-cbc': + case 'twofish256-cbc': + case 'twofish256-ctr': + return 32; + case 'chacha20-poly1305@openssh.com': + return 64; + } + return null; + } + + /** + * Maps an encryption algorithm name to an instance of a subclass of + * \phpseclib3\Crypt\Common\SymmetricKey. + * + * @param string $algorithm Name of the encryption algorithm + * @return SymmetricKey|null + */ + private static function encryption_algorithm_to_crypt_instance($algorithm) + { + switch ($algorithm) { + case '3des-cbc': + return new TripleDES('cbc'); + case '3des-ctr': + return new TripleDES('ctr'); + case 'aes256-cbc': + case 'aes192-cbc': + case 'aes128-cbc': + return new Rijndael('cbc'); + case 'aes256-ctr': + case 'aes192-ctr': + case 'aes128-ctr': + return new Rijndael('ctr'); + case 'blowfish-cbc': + return new Blowfish('cbc'); + case 'blowfish-ctr': + return new Blowfish('ctr'); + case 'twofish128-cbc': + case 'twofish192-cbc': + case 'twofish256-cbc': + case 'twofish-cbc': + return new Twofish('cbc'); + case 'twofish128-ctr': + case 'twofish192-ctr': + case 'twofish256-ctr': + return new Twofish('ctr'); + case 'arcfour': + case 'arcfour128': + case 'arcfour256': + return new RC4(); + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + return new Rijndael('gcm'); + case 'chacha20-poly1305@openssh.com': + return new ChaCha20(); + } + return null; + } + + /** + * Maps an encryption algorithm name to an instance of a subclass of + * \phpseclib3\Crypt\Hash. + * + * @param string $algorithm Name of the encryption algorithm + * @return array{Hash, int}|null + */ + private static function mac_algorithm_to_hash_instance($algorithm) + { + switch ($algorithm) { + case 'umac-64@openssh.com': + case 'umac-64-etm@openssh.com': + return [new Hash('umac-64'), 16]; + case 'umac-128@openssh.com': + case 'umac-128-etm@openssh.com': + return [new Hash('umac-128'), 16]; + case 'hmac-sha2-512': + case 'hmac-sha2-512-etm@openssh.com': + return [new Hash('sha512'), 64]; + case 'hmac-sha2-256': + case 'hmac-sha2-256-etm@openssh.com': + return [new Hash('sha256'), 32]; + case 'hmac-sha1': + case 'hmac-sha1-etm@openssh.com': + return [new Hash('sha1'), 20]; + case 'hmac-sha1-96': + return [new Hash('sha1-96'), 20]; + case 'hmac-md5': + return [new Hash('md5'), 16]; + case 'hmac-md5-96': + return [new Hash('md5-96'), 16]; + } + } + + /* + * Tests whether or not proposed algorithm has a potential for issues + * + * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html + * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291 + * @param string $algorithm Name of the encryption algorithm + * @return bool + */ + private static function bad_algorithm_candidate($algorithm) + { + switch ($algorithm) { + case 'arcfour256': + case 'aes192-ctr': + case 'aes256-ctr': + return true; + } + + return false; + } + + /** + * Login + * + * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA|EC|DSA object, a \phpseclib3\System\SSH\Agent object or an array + * + * @param string $username + * @param string|PrivateKey|array[]|Agent|null ...$args + * @return bool + * @see self::_login() + */ + public function login($username, ...$args) + { + $this->auth[] = func_get_args(); + + // try logging with 'none' as an authentication method first since that's what + // PuTTY does + if (substr($this->server_identifier, 0, 15) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) { + if ($this->sublogin($username)) { + return true; + } + if (!count($args)) { + return false; + } + } + return $this->sublogin($username, ...$args); + } + + /** + * Login Helper + * + * @param string $username + * @param string|PrivateKey|array[]|Agent|null ...$args + * @return bool + * @see self::_login_helper() + */ + protected function sublogin($username, ...$args) + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + $this->connect(); + } + + if (empty($args)) { + return $this->login_helper($username); + } + + foreach ($args as $arg) { + switch (true) { + case $arg instanceof PublicKey: + throw new \UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object'); + case $arg instanceof PrivateKey: + case $arg instanceof Agent: + case is_array($arg): + case Strings::is_stringable($arg): + break; + default: + throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); + } + } + + while (count($args)) { + if (!$this->auth_methods_to_continue || !$this->smartMFA) { + $newargs = $args; + $args = []; + } else { + $newargs = []; + foreach ($this->auth_methods_to_continue as $method) { + switch ($method) { + case 'publickey': + foreach ($args as $key => $arg) { + if ($arg instanceof PrivateKey || $arg instanceof Agent) { + $newargs[] = $arg; + unset($args[$key]); + break; + } + } + break; + case 'keyboard-interactive': + $hasArray = $hasString = false; + foreach ($args as $arg) { + if ($hasArray || is_array($arg)) { + $hasArray = true; + break; + } + if ($hasString || Strings::is_stringable($arg)) { + $hasString = true; + break; + } + } + if ($hasArray && $hasString) { + foreach ($args as $key => $arg) { + if (is_array($arg)) { + $newargs[] = $arg; + break 2; + } + } + } + // fall-through + case 'password': + foreach ($args as $key => $arg) { + $newargs[] = $arg; + unset($args[$key]); + break; + } + } + } + } + + if (!count($newargs)) { + return false; + } + + foreach ($newargs as $arg) { + if ($this->login_helper($username, $arg)) { + return true; + } + } + } + return false; + } + + /** + * Login Helper + * + * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages.} + * + * @param string $username + * @param string|AsymmetricKey|array[]|Agent|null ...$args + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + private function login_helper($username, $password = null) + { + if (!($this->bitmap & self::MASK_CONNECTED)) { + return false; + } + + if (!($this->bitmap & self::MASK_LOGIN_REQ)) { + $packet = Strings::packSSH2('Cs', NET_SSH2_MSG_SERVICE_REQUEST, 'ssh-userauth'); + $this->send_binary_packet($packet); + + try { + $response = $this->get_binary_packet(); + } catch (\Exception $e) { + if ($this->retry_connect) { + $this->retry_connect = false; + $this->connect(); + return $this->login_helper($username, $password); + } + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type, $service) = Strings::unpackSSH2('Cs', $response); + if ($type != NET_SSH2_MSG_SERVICE_ACCEPT || $service != 'ssh-userauth') { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); + } + $this->bitmap |= self::MASK_LOGIN_REQ; + } + + if (strlen($this->last_interactive_response)) { + return !Strings::is_stringable($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password); + } + + if ($password instanceof PrivateKey) { + return $this->privatekey_login($username, $password); + } + + if ($password instanceof Agent) { + return $this->ssh_agent_login($username, $password); + } + + if (is_array($password)) { + if ($this->keyboard_interactive_login($username, $password)) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } + return false; + } + + if (!isset($password)) { + $packet = Strings::packSSH2( + 'Cs3', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'none' + ); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($auth_methods) = Strings::unpackSSH2('L', $response); + $this->auth_methods_to_continue = $auth_methods; + // fall-through + default: + return false; + } + } + + $packet = Strings::packSSH2( + 'Cs3bs', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'password', + false, + $password + ); + + // remove the username and password from the logged packet + if (!defined('NET_SSH2_LOGGING')) { + $logged = null; + } else { + $logged = Strings::packSSH2( + 'Cs3bs', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'password', + false, + 'password' + ); + } + + $this->send_binary_packet($packet, $logged); + + $response = $this->get_binary_packet(); + if ($response === false) { + return false; + } + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); + + list($message) = Strings::unpackSSH2('s', $response); + $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $message; + + return $this->disconnect_helper(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); + case NET_SSH2_MSG_USERAUTH_FAILURE: + // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees + // multi-factor authentication + list($auth_methods, $partial_success) = Strings::unpackSSH2('Lb', $response); + $this->auth_methods_to_continue = $auth_methods; + if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { + if ($this->keyboard_interactive_login($username, $password)) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } + return false; + } + return false; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + } + + return false; + } + + /** + * Login via keyboard-interactive authentication + * + * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator. + * + * @param string $username + * @param string|array $password + * @return bool + */ + private function keyboard_interactive_login($username, $password) + { + $packet = Strings::packSSH2( + 'Cs5', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'keyboard-interactive', + '', // language tag + '' // submethods + ); + $this->send_binary_packet($packet); + + return $this->keyboard_interactive_process($password); + } + + /** + * Handle the keyboard-interactive requests / responses. + * + * @param string|array ...$responses + * @return bool + * @throws \RuntimeException on connection error + */ + private function keyboard_interactive_process(...$responses) + { + if (strlen($this->last_interactive_response)) { + $response = $this->last_interactive_response; + } else { + $orig = $response = $this->get_binary_packet(); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: + list( + , // name; may be empty + , // instruction; may be empty + , // language tag; may be empty + $num_prompts + ) = Strings::unpackSSH2('s3N', $response); + + for ($i = 0; $i < count($responses); $i++) { + if (is_array($responses[$i])) { + foreach ($responses[$i] as $key => $value) { + $this->keyboard_requests_responses[$key] = $value; + } + unset($responses[$i]); + } + } + $responses = array_values($responses); + + if (isset($this->keyboard_requests_responses)) { + for ($i = 0; $i < $num_prompts; $i++) { + list( + $prompt, // prompt - ie. "Password: "; must not be empty + // echo + ) = Strings::unpackSSH2('sC', $response); + foreach ($this->keyboard_requests_responses as $key => $value) { + if (substr($prompt, 0, strlen($key)) == $key) { + $responses[] = $value; + break; + } + } + } + } + + // see http://tools.ietf.org/html/rfc4256#section-3.2 + if (strlen($this->last_interactive_response)) { + $this->last_interactive_response = ''; + } else { + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); + } + + if (!count($responses) && $num_prompts) { + $this->last_interactive_response = $orig; + return false; + } + + /* + After obtaining the requested information from the user, the client + MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. + */ + // see http://tools.ietf.org/html/rfc4256#section-3.4 + $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); + for ($i = 0; $i < count($responses); $i++) { + $packet .= Strings::packSSH2('s', $responses[$i]); + $logged .= Strings::packSSH2('s', 'dummy-answer'); + } + + $this->send_binary_packet($packet, $logged); + + $this->updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); + + /* + After receiving the response, the server MUST send either an + SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another + SSH_MSG_USERAUTH_INFO_REQUEST message. + */ + // maybe phpseclib should force close the connection after x request / responses? unless something like that is done + // there could be an infinite loop of request / responses. + return $this->keyboard_interactive_process(); + case NET_SSH2_MSG_USERAUTH_SUCCESS: + return true; + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($auth_methods) = Strings::unpackSSH2('L', $response); + $this->auth_methods_to_continue = $auth_methods; + return false; + } + + return false; + } + + /** + * Login with an ssh-agent provided key + * + * @param string $username + * @param \phpseclib3\System\SSH\Agent $agent + * @return bool + */ + private function ssh_agent_login($username, Agent $agent) + { + $this->agent = $agent; + $keys = $agent->requestIdentities(); + foreach ($keys as $key) { + if ($this->privatekey_login($username, $key)) { + return true; + } + } + + return false; + } + + /** + * Login with an RSA private key + * + * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages.} + * + * @param string $username + * @param \phpseclib3\Crypt\Common\PrivateKey $privatekey + * @return bool + * @throws \RuntimeException on connection error + */ + private function privatekey_login($username, PrivateKey $privatekey) + { + $publickey = $privatekey->getPublicKey(); + + if ($publickey instanceof RSA) { + $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); + $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; + if (isset($this->preferred['hostkey'])) { + $algos = array_intersect($this->preferred['hostkey'], $algos); + } + $algo = self::array_intersect_first($algos, $this->supported_private_key_algorithms); + switch ($algo) { + case 'rsa-sha2-512': + $hash = 'sha512'; + $signatureType = 'rsa-sha2-512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + $signatureType = 'rsa-sha2-256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $signatureType = 'ssh-rsa'; + } + } elseif ($publickey instanceof EC) { + $privatekey = $privatekey->withSignatureFormat('SSH2'); + $curveName = $privatekey->getCurve(); + switch ($curveName) { + case 'Ed25519': + $hash = 'sha512'; + $signatureType = 'ssh-ed25519'; + break; + case 'secp256r1': // nistp256 + $hash = 'sha256'; + $signatureType = 'ecdsa-sha2-nistp256'; + break; + case 'secp384r1': // nistp384 + $hash = 'sha384'; + $signatureType = 'ecdsa-sha2-nistp384'; + break; + case 'secp521r1': // nistp521 + $hash = 'sha512'; + $signatureType = 'ecdsa-sha2-nistp521'; + break; + default: + if (is_array($curveName)) { + throw new UnsupportedCurveException('Specified Curves are not supported by SSH2'); + } + throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported by phpseclib3\'s SSH2 implementation'); + } + } elseif ($publickey instanceof DSA) { + $privatekey = $privatekey->withSignatureFormat('SSH2'); + $hash = 'sha1'; + $signatureType = 'ssh-dss'; + } else { + throw new UnsupportedAlgorithmException('Please use either an RSA key, an EC one or a DSA key'); + } + + $publickeyStr = $publickey->toString('OpenSSH', ['binary' => true]); + + $part1 = Strings::packSSH2( + 'Csss', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'publickey' + ); + $part2 = Strings::packSSH2('ss', $signatureType, $publickeyStr); + + $packet = $part1 . chr(0) . $part2; + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($auth_methods) = Strings::unpackSSH2('L', $response); + if (in_array('publickey', $auth_methods) && substr($signatureType, 0, 9) == 'rsa-sha2-') { + $this->supported_private_key_algorithms = array_diff($this->supported_private_key_algorithms, ['rsa-sha2-256', 'rsa-sha2-512']); + return $this->privatekey_login($username, $privatekey); + } + $this->auth_methods_to_continue = $auth_methods; + $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE'; + return false; + case NET_SSH2_MSG_USERAUTH_PK_OK: + // we'll just take it on faith that the public key blob and the public key algorithm name are as + // they should be + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); + break; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new ConnectionClosedException('Unexpected response to publickey authentication pt 1'); + } + + $packet = $part1 . chr(1) . $part2; + $privatekey = $privatekey->withHash($hash); + $signature = $privatekey->sign(Strings::packSSH2('s', $this->session_id) . $packet); + if ($publickey instanceof RSA) { + $signature = Strings::packSSH2('ss', $signatureType, $signature); + } + $packet .= Strings::packSSH2('s', $signature); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_FAILURE: + // either the login is bad or the server employs multi-factor authentication + list($auth_methods) = Strings::unpackSSH2('L', $response); + $this->auth_methods_to_continue = $auth_methods; + return false; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + } + + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new ConnectionClosedException('Unexpected response to publickey authentication pt 2'); + } + + /** + * Return the currently configured timeout + * + * @return int + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Set Timeout + * + * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. + * Setting $timeout to false or 0 will mean there is no timeout. + * + * @param mixed $timeout + */ + public function setTimeout($timeout) + { + $this->timeout = $this->curTimeout = $timeout; + } + + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param int $interval + */ + public function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + + /** + * Get the output from stdError + * + */ + public function getStdError() + { + return $this->stdErrorLog; + } + + /** + * Execute Command + * + * If $callback is set to false then \phpseclib3\Net\SSH2::get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. + * In all likelihood, this is not a feature you want to be taking advantage of. + * + * @param string $command + * @return string|bool + * @psalm-return ($callback is callable ? bool : string|bool) + * @throws \RuntimeException on connection error + */ + public function exec($command, callable $callback = null) + { + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + $this->stdErrorLog = ''; + + if (!$this->isAuthenticated()) { + return false; + } + + //if ($this->isPTYOpen()) { + // throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); + //} + + $this->openChannel(self::CHANNEL_EXEC); + + if ($this->request_pty === true) { + $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); + $packet = Strings::packSSH2( + 'CNsCsN4s', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_EXEC], + 'pty-req', + 1, + $this->term, + $this->windowColumns, + $this->windowRows, + 0, + 0, + $terminal_modes + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; + if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to request pseudo-terminal'); + } + } + + // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things + // down. the one place where it might be desirable is if you're doing something like \phpseclib3\Net\SSH2::exec('ping localhost &'). + // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then + // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but + // neither will your script. + + // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by + // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the + // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_EXEC], + 'exec', + 1, + $command + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { + return false; + } + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; + + if ($this->request_pty === true) { + $this->channel_id_last_interactive = self::CHANNEL_EXEC; + return true; + } + + $output = ''; + while (true) { + $temp = $this->get_channel_packet(self::CHANNEL_EXEC); + switch (true) { + case $temp === true: + return is_callable($callback) ? true : $output; + case $temp === false: + return false; + default: + if (is_callable($callback)) { + if ($callback($temp) === true) { + $this->close_channel(self::CHANNEL_EXEC); + return true; + } + } else { + $output .= $temp; + } + } + } + } + + /** + * How many channels are currently open? + * + * @return int + */ + public function getOpenChannelCount() + { + return $this->channelCount; + } + + /** + * Opens a channel + * + * @param string $channel + * @param bool $skip_extended + * @return bool + */ + protected function openChannel($channel, $skip_extended = false) + { + if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) { + throw new \RuntimeException('Please close the channel (' . $channel . ') before trying to open it again'); + } + + $this->channelCount++; + + if ($this->channelCount > 1 && $this->errorOnMultipleChannels) { + throw new \RuntimeException("Ubuntu's OpenSSH from 5.8 to 6.9 doesn't work with multiple channels"); + } + + // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to + // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, + // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. + // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info + $this->window_size_server_to_client[$channel] = $this->window_size; + // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy + // uses 0x4000, that's what will be used here, as well. + $packet_size = 0x4000; + + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + $channel, + $this->window_size_server_to_client[$channel], + $packet_size + ); + + $this->send_binary_packet($packet); + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_OPEN; + + return $this->get_channel_packet($channel, $skip_extended); + } + + /** + * Creates an interactive shell + * + * Returns bool(true) if the shell was opened. + * Returns bool(false) if the shell was already open. + * + * @see self::isShellOpen() + * @see self::read() + * @see self::write() + * @return bool + * @throws InsufficientSetupException if not authenticated + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + public function openShell() + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + $this->openChannel(self::CHANNEL_SHELL); + + $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); + $packet = Strings::packSSH2( + 'CNsbsN4s', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SHELL], + 'pty-req', + true, // want reply + $this->term, + $this->windowColumns, + $this->windowRows, + 0, + 0, + $terminal_modes + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$this->get_channel_packet(self::CHANNEL_SHELL)) { + throw new \RuntimeException('Unable to request pty'); + } + + $packet = Strings::packSSH2( + 'CNsb', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SHELL], + 'shell', + true // want reply + ); + $this->send_binary_packet($packet); + + $response = $this->get_channel_packet(self::CHANNEL_SHELL); + if ($response === false) { + throw new \RuntimeException('Unable to request shell'); + } + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; + + $this->channel_id_last_interactive = self::CHANNEL_SHELL; + + $this->bitmap |= self::MASK_SHELL; + + return true; + } + + /** + * Return the channel to be used with read(), write(), and reset(), if none were specified + * @deprecated for lack of transparency in intended channel target, to be potentially replaced + * with method which guarantees open-ness of all yielded channels and throws + * error for multiple open channels + * @see self::read() + * @see self::write() + * @return int + */ + private function get_interactive_channel() + { + switch (true) { + case $this->is_channel_status_data(self::CHANNEL_SUBSYSTEM): + return self::CHANNEL_SUBSYSTEM; + case $this->is_channel_status_data(self::CHANNEL_EXEC): + return self::CHANNEL_EXEC; + default: + return self::CHANNEL_SHELL; + } + } + + /** + * Indicates the DATA status on the given channel + * + * @param int $channel The channel number to evaluate + * @return bool + */ + private function is_channel_status_data($channel) + { + return isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA; + } + + /** + * Return an available open channel + * + * @return int + */ + private function get_open_channel() + { + $channel = self::CHANNEL_EXEC; + do { + if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) { + return $channel; + } + } while ($channel++ < self::CHANNEL_SUBSYSTEM); + + return false; + } + + /** + * Request agent forwarding of remote server + * + * @return bool + */ + public function requestAgentForwarding() + { + $request_channel = $this->get_open_channel(); + if ($request_channel === false) { + return false; + } + + $packet = Strings::packSSH2( + 'CNsC', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[$request_channel], + 'auth-agent-req@openssh.com', + 1 + ); + + $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $this->send_binary_packet($packet); + + if (!$this->get_channel_packet($request_channel)) { + return false; + } + + $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; + + return true; + } + + /** + * Returns the output of an interactive shell + * + * Returns when there's a match for $expect, which can take the form of a string literal or, + * if $mode == self::READ_REGEX, a regular expression. + * + * If not specifying a channel, an open interactive channel will be selected, or, if there are + * no open channels, an interactive shell will be created. If there are multiple open + * interactive channels, a legacy behavior will apply in which channel selection prioritizes + * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive + * channels, callers are discouraged from relying on this legacy behavior and should specify + * the intended channel. + * + * @see self::write() + * @param string $expect + * @param int $mode One of the self::READ_* constants + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return string|bool|null + * @throws \RuntimeException on connection error + * @throws InsufficientSetupException on unexpected channel status, possibly due to closure + */ + public function read($expect = '', $mode = self::READ_SIMPLE, $channel = null) + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + + if (!$this->is_channel_status_data($channel) && empty($this->channel_buffers[$channel])) { + if ($channel != self::CHANNEL_SHELL) { + throw new InsufficientSetupException('Data is not available on channel'); + } elseif (!$this->openShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + } + + if ($mode == self::READ_NEXT) { + return $this->get_channel_packet($channel); + } + + $match = $expect; + while (true) { + if ($mode == self::READ_REGEX) { + preg_match($expect, substr($this->interactiveBuffer, -1024), $matches); + $match = isset($matches[0]) ? $matches[0] : ''; + } + $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; + if ($pos !== false) { + return Strings::shift($this->interactiveBuffer, $pos + strlen($match)); + } + $response = $this->get_channel_packet($channel); + if ($response === true) { + return Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); + } + + $this->interactiveBuffer .= $response; + } + } + + /** + * Inputs a command into an interactive shell. + * + * If not specifying a channel, an open interactive channel will be selected, or, if there are + * no open channels, an interactive shell will be created. If there are multiple open + * interactive channels, a legacy behavior will apply in which channel selection prioritizes + * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive + * channels, callers are discouraged from relying on this legacy behavior and should specify + * the intended channel. + * + * @see SSH2::read() + * @param string $cmd + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return void + * @throws \RuntimeException on connection error + * @throws InsufficientSetupException on unexpected channel status, possibly due to closure + */ + public function write($cmd, $channel = null) + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + + if (!$this->is_channel_status_data($channel)) { + if ($channel != self::CHANNEL_SHELL) { + throw new InsufficientSetupException('Data is not available on channel'); + } elseif (!$this->openShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + } + + $this->send_channel_packet($channel, $cmd); + } + + /** + * Start a subsystem. + * + * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept + * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened. + * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and + * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented + * if there's sufficient demand for such a feature. + * + * @see self::stopSubsystem() + * @param string $subsystem + * @return bool + */ + public function startSubsystem($subsystem) + { + $this->openChannel(self::CHANNEL_SUBSYSTEM); + + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SUBSYSTEM], + 'subsystem', + 1, + $subsystem + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$this->get_channel_packet(self::CHANNEL_SUBSYSTEM)) { + return false; + } + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; + + $this->channel_id_last_interactive = self::CHANNEL_SUBSYSTEM; + + return true; + } + + /** + * Stops a subsystem. + * + * @see self::startSubsystem() + * @return bool + */ + public function stopSubsystem() + { + if ($this->isInteractiveChannelOpen(self::CHANNEL_SUBSYSTEM)) { + $this->close_channel(self::CHANNEL_SUBSYSTEM); + } + return true; + } + + /** + * Closes a channel + * + * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call + * + * If not specifying a channel, an open interactive channel will be selected. If there are + * multiple open interactive channels, a legacy behavior will apply in which channel selection + * prioritizes an active subsystem, the exec pty, and, lastly, the shell. If using multiple + * interactive channels, callers are discouraged from relying on this legacy behavior and + * should specify the intended channel. + * + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return void + */ + public function reset($channel = null) + { + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + if ($this->isInteractiveChannelOpen($channel)) { + $this->close_channel($channel); + } + } + + /** + * Is timeout? + * + * Did exec() or read() return because they timed out or because they encountered the end? + * + */ + public function isTimeout() + { + return $this->is_timeout; + } + + /** + * Disconnect + * + */ + public function disconnect() + { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { + fclose($this->realtime_log_file); + } + unset(self::$connections[$this->getResourceId()]); + } + + /** + * Destructor. + * + * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call + * disconnect(). + * + */ + public function __destruct() + { + $this->disconnect(); + } + + /** + * Is the connection still active? + * + * @return bool + */ + public function isConnected() + { + return ($this->bitmap & self::MASK_CONNECTED) && is_resource($this->fsock) && !feof($this->fsock); + } + + /** + * Have you successfully been logged in? + * + * @return bool + */ + public function isAuthenticated() + { + return (bool) ($this->bitmap & self::MASK_LOGIN); + } + + /** + * Is the interactive shell active? + * + * @return bool + */ + public function isShellOpen() + { + return $this->isInteractiveChannelOpen(self::CHANNEL_SHELL); + } + + /** + * Is the exec pty active? + * + * @return bool + */ + public function isPTYOpen() + { + return $this->isInteractiveChannelOpen(self::CHANNEL_EXEC); + } + + /** + * Is the given interactive channel active? + * + * @param int $channel Channel id returned by self::getInteractiveChannelId() + * @return bool + */ + public function isInteractiveChannelOpen($channel) + { + return $this->isAuthenticated() && $this->is_channel_status_data($channel); + } + + /** + * Returns a channel identifier, presently of the last interactive channel opened, regardless of current status. + * Returns 0 if no interactive channel has been opened. + * + * @see self::isInteractiveChannelOpen() + * @return int + */ + public function getInteractiveChannelId() + { + return $this->channel_id_last_interactive; + } + + /** + * Pings a server connection, or tries to reconnect if the connection has gone down + * + * Inspired by http://php.net/manual/en/mysqli.ping.php + * + * @return bool + */ + public function ping() + { + if (!$this->isAuthenticated()) { + if (!empty($this->auth)) { + return $this->reconnect(); + } + return false; + } + + try { + $this->openChannel(self::CHANNEL_KEEP_ALIVE); + } catch (\RuntimeException $e) { + return $this->reconnect(); + } + + $this->close_channel(self::CHANNEL_KEEP_ALIVE); + return true; + } + + /** + * In situ reconnect method + * + * @return boolean + */ + private function reconnect() + { + $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); + $this->retry_connect = true; + $this->connect(); + foreach ($this->auth as $auth) { + $result = $this->login(...$auth); + } + return $result; + } + + /** + * Resets a connection for re-use + * + * @param int $reason + */ + protected function reset_connection($reason) + { + $this->disconnect_helper($reason); + $this->decrypt = $this->encrypt = false; + $this->decrypt_block_size = $this->encrypt_block_size = 8; + $this->hmac_check = $this->hmac_create = false; + $this->hmac_size = false; + $this->session_id = false; + $this->retry_connect = true; + $this->get_seq_no = $this->send_seq_no = 0; + } + + /** + * Gets Binary Packets + * + * See '6. Binary Packet Protocol' of rfc4253 for more info. + * + * @see self::_send_binary_packet() + * @param bool $skip_channel_filter + * @return bool|string + */ + private function get_binary_packet($skip_channel_filter = false) + { + if ($skip_channel_filter) { + if (!is_resource($this->fsock)) { + throw new \InvalidArgumentException('fsock is not a resource.'); + } + $read = [$this->fsock]; + $write = $except = null; + + if (!$this->curTimeout) { + if ($this->keepAlive <= 0) { + static::stream_select($read, $write, $except, null); + } else { + if (!static::stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->get_binary_packet(true); + } + } + } else { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return true; + } + + $start = microtime(true); + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!static::stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + return $this->get_binary_packet(true); + } + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + } + + $sec = (int) floor($this->curTimeout); + $usec = (int) (1000000 * ($this->curTimeout - $sec)); + + // this can return a "stream_select(): unable to select [4]: Interrupted system call" error + if (!static::stream_select($read, $write, $except, $sec, $usec)) { + $this->is_timeout = true; + return true; + } + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + } + } + + if (!is_resource($this->fsock) || feof($this->fsock)) { + $this->bitmap = 0; + $str = 'Connection closed (by server) prematurely'; + if (isset($elapsed)) { + $str .= ' ' . $elapsed . 's'; + } + throw new ConnectionClosedException($str); + } + + $start = microtime(true); + $raw = stream_get_contents($this->fsock, $this->decrypt_block_size); + + if (!strlen($raw)) { + $this->bitmap = 0; + throw new ConnectionClosedException('No data received from server'); + } + + if ($this->decrypt) { + switch ($this->decryptName) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $this->decrypt->setNonce( + $this->decryptFixedPart . + $this->decryptInvocationCounter + ); + Strings::increment_str($this->decryptInvocationCounter); + $this->decrypt->setAAD($temp = Strings::shift($raw, 4)); + extract(unpack('Npacket_length', $temp)); + /** + * @var integer $packet_length + */ + + $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $tag = stream_get_contents($this->fsock, $this->decrypt_block_size); + $this->decrypt->setTag($tag); + $raw = $this->decrypt->decrypt($raw); + $raw = $temp . $raw; + $remaining_length = 0; + break; + case 'chacha20-poly1305@openssh.com': + // This should be impossible, but we are checking anyway to narrow the type for Psalm. + if (!($this->decrypt instanceof ChaCha20)) { + throw new \LogicException('$this->decrypt is not a ' . ChaCha20::class); + } + + $nonce = pack('N2', 0, $this->get_seq_no); + + $this->lengthDecrypt->setNonce($nonce); + $temp = $this->lengthDecrypt->decrypt($aad = Strings::shift($raw, 4)); + extract(unpack('Npacket_length', $temp)); + /** + * @var integer $packet_length + */ + + $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $tag = stream_get_contents($this->fsock, 16); + + $this->decrypt->setNonce($nonce); + $this->decrypt->setCounter(0); + // this is the same approach that's implemented in Salsa20::createPoly1305Key() + // but we don't want to use the same AEAD construction that RFC8439 describes + // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) + $this->decrypt->setPoly1305Key( + $this->decrypt->encrypt(str_repeat("\0", 32)) + ); + $this->decrypt->setAAD($aad); + $this->decrypt->setCounter(1); + $this->decrypt->setTag($tag); + $raw = $this->decrypt->decrypt($raw); + $raw = $temp . $raw; + $remaining_length = 0; + break; + default: + if (!$this->hmac_check instanceof Hash || !$this->hmac_check_etm) { + $raw = $this->decrypt->decrypt($raw); + break; + } + extract(unpack('Npacket_length', $temp = Strings::shift($raw, 4))); + /** + * @var integer $packet_length + */ + $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $encrypted = $temp . $raw; + $raw = $temp . $this->decrypt->decrypt($raw); + $remaining_length = 0; + } + } + + if (strlen($raw) < 5) { + $this->bitmap = 0; + throw new \RuntimeException('Plaintext is too short'); + } + extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5))); + /** + * @var integer $packet_length + * @var integer $padding_length + */ + + if (!isset($remaining_length)) { + $remaining_length = $packet_length + 4 - $this->decrypt_block_size; + } + + $buffer = $this->read_remaining_bytes($remaining_length); + + if (!isset($stop)) { + $stop = microtime(true); + } + if (strlen($buffer)) { + $raw .= $this->decrypt ? $this->decrypt->decrypt($buffer) : $buffer; + } + + $payload = Strings::shift($raw, $packet_length - $padding_length - 1); + $padding = Strings::shift($raw, $padding_length); // should leave $raw empty + + if ($this->hmac_check instanceof Hash) { + $hmac = stream_get_contents($this->fsock, $this->hmac_size); + if ($hmac === false || strlen($hmac) != $this->hmac_size) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Error reading socket'); + } + + $reconstructed = !$this->hmac_check_etm ? + pack('NCa*', $packet_length, $padding_length, $payload . $padding) : + $encrypted; + if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); + if ($hmac != $this->hmac_check->hash($reconstructed)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Invalid UMAC'); + } + } else { + if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Invalid HMAC'); + } + } + } + + switch ($this->decompress) { + case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: + if (!$this->isAuthenticated()) { + break; + } + // fall-through + case self::NET_SSH2_COMPRESSION_ZLIB: + if ($this->regenerate_decompression_context) { + $this->regenerate_decompression_context = false; + + $cmf = ord($payload[0]); + $cm = $cmf & 0x0F; + if ($cm != 8) { // deflate + user_error("Only CM = 8 ('deflate') is supported ($cm)"); + } + $cinfo = ($cmf & 0xF0) >> 4; + if ($cinfo > 7) { + user_error("CINFO above 7 is not allowed ($cinfo)"); + } + $windowSize = 1 << ($cinfo + 8); + + $flg = ord($payload[1]); + //$fcheck = $flg && 0x0F; + if ((($cmf << 8) | $flg) % 31) { + user_error('fcheck failed'); + } + $fdict = boolval($flg & 0x20); + $flevel = ($flg & 0xC0) >> 6; + + $this->decompress_context = inflate_init(ZLIB_ENCODING_RAW, ['window' => $cinfo + 8]); + $payload = substr($payload, 2); + } + if ($this->decompress_context) { + $payload = inflate_add($this->decompress_context, $payload, ZLIB_PARTIAL_FLUSH); + } + } + + $this->get_seq_no++; + + if (defined('NET_SSH2_LOGGING')) { + $current = microtime(true); + $message_number = isset(self::$message_numbers[ord($payload[0])]) ? self::$message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; + $message_number = '<- ' . $message_number . + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; + $this->append_log($message_number, $payload); + $this->last_packet = $current; + } + + return $this->filter($payload, $skip_channel_filter); + } + + /** + * Read Remaining Bytes + * + * @see self::get_binary_packet() + * @param int $remaining_length + * @return string + */ + private function read_remaining_bytes($remaining_length) + { + if (!$remaining_length) { + return ''; + } + + $adjustLength = false; + if ($this->decrypt) { + switch (true) { + case $this->decryptName == 'aes128-gcm@openssh.com': + case $this->decryptName == 'aes256-gcm@openssh.com': + case $this->decryptName == 'chacha20-poly1305@openssh.com': + case $this->hmac_check instanceof Hash && $this->hmac_check_etm: + $remaining_length += $this->decrypt_block_size - 4; + $adjustLength = true; + } + } + + // quoting , + // "implementations SHOULD check that the packet length is reasonable" + // PuTTY uses 0x9000 as the actual max packet size and so to shall we + // don't do this when GCM mode is used since GCM mode doesn't encrypt the length + if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { + if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decryptName : '') && !($this->bitmap & SSH2::MASK_LOGIN)) { + $this->bad_key_size_fix = true; + $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + return false; + } + throw new \RuntimeException('Invalid size'); + } + + if ($adjustLength) { + $remaining_length -= $this->decrypt_block_size - 4; + } + + $buffer = ''; + while ($remaining_length > 0) { + $temp = stream_get_contents($this->fsock, $remaining_length); + if ($temp === false || feof($this->fsock)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new \RuntimeException('Error reading from socket'); + } + $buffer .= $temp; + $remaining_length -= strlen($temp); + } + + return $buffer; + } + + /** + * Filter Binary Packets + * + * Because some binary packets need to be ignored... + * + * @see self::_get_binary_packet() + * @param string $payload + * @param bool $skip_channel_filter + * @return string|bool + */ + private function filter($payload, $skip_channel_filter) + { + switch (ord($payload[0])) { + case NET_SSH2_MSG_DISCONNECT: + Strings::shift($payload, 1); + list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); + $this->errors[] = 'SSH_MSG_DISCONNECT: ' . self::$disconnect_reasons[$reason_code] . "\r\n$message"; + $this->bitmap = 0; + return false; + case NET_SSH2_MSG_IGNORE: + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_DEBUG: + Strings::shift($payload, 2); // second byte is "always_display" + list($message) = Strings::unpackSSH2('s', $payload); + $this->errors[] = "SSH_MSG_DEBUG: $message"; + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_UNIMPLEMENTED: + return false; + case NET_SSH2_MSG_KEXINIT: + if ($this->session_id !== false) { + if (!$this->key_exchange($payload)) { + $this->bitmap = 0; + return false; + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + + // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in + if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && !is_bool($payload) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { + Strings::shift($payload, 1); + list($this->banner_message) = Strings::unpackSSH2('s', $payload); + $payload = $this->get_binary_packet(); + } + + // only called when we've already logged in + if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { + if (is_bool($payload)) { + return $payload; + } + + switch (ord($payload[0])) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + if (strlen($payload) == 31) { + extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { + if (ord(substr($payload, 9 + $length))) { // want reply + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + break; + case NET_SSH2_MSG_CHANNEL_DATA: + case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: + case NET_SSH2_MSG_CHANNEL_CLOSE: + case NET_SSH2_MSG_CHANNEL_EOF: + if (!$skip_channel_filter && !empty($this->server_channels)) { + $this->binary_packet_buffer = $payload; + $this->get_channel_packet(true); + $payload = $this->get_binary_packet(); + } + break; + case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 + Strings::shift($payload, 1); + list($request_name) = Strings::unpackSSH2('s', $payload); + $this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name"; + + try { + $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE)); + } catch (\RuntimeException $e) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 + Strings::shift($payload, 1); + list($data, $server_channel) = Strings::unpackSSH2('sN', $payload); + switch ($data) { + case 'auth-agent': + case 'auth-agent@openssh.com': + if (isset($this->agent)) { + $new_channel = self::CHANNEL_AGENT_FORWARD; + + list( + $remote_window_size, + $remote_maximum_packet_size + ) = Strings::unpackSSH2('NN', $payload); + + $this->packet_size_client_to_server[$new_channel] = $remote_window_size; + $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; + $this->window_size_client_to_server[$new_channel] = $this->window_size; + + $packet_size = 0x4000; + + $packet = pack( + 'CN4', + NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, + $server_channel, + $new_channel, + $packet_size, + $packet_size + ); + + $this->server_channels[$new_channel] = $server_channel; + $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; + $this->send_binary_packet($packet); + } + break; + default: + $packet = Strings::packSSH2( + 'CN2ss', + NET_SSH2_MSG_CHANNEL_OPEN_FAILURE, + $server_channel, + NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, + '', // description + '' // language tag + ); + + try { + $this->send_binary_packet($packet); + } catch (\RuntimeException $e) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + } + + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: + Strings::shift($payload, 1); + list($channel, $window_size) = Strings::unpackSSH2('NN', $payload); + + $this->window_size_client_to_server[$channel] += $window_size; + + $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->get_binary_packet($skip_channel_filter); + } + } + + return $payload; + } + + /** + * Enable Quiet Mode + * + * Suppress stderr from output + * + */ + public function enableQuietMode() + { + $this->quiet_mode = true; + } + + /** + * Disable Quiet Mode + * + * Show stderr in output + * + */ + public function disableQuietMode() + { + $this->quiet_mode = false; + } + + /** + * Returns whether Quiet Mode is enabled or not + * + * @see self::enableQuietMode() + * @see self::disableQuietMode() + * @return bool + */ + public function isQuietModeEnabled() + { + return $this->quiet_mode; + } + + /** + * Enable request-pty when using exec() + * + */ + public function enablePTY() + { + $this->request_pty = true; + } + + /** + * Disable request-pty when using exec() + * + */ + public function disablePTY() + { + if ($this->isPTYOpen()) { + $this->close_channel(self::CHANNEL_EXEC); + } + $this->request_pty = false; + } + + /** + * Returns whether request-pty is enabled or not + * + * @see self::enablePTY() + * @see self::disablePTY() + * @return bool + */ + public function isPTYEnabled() + { + return $this->request_pty; + } + + /** + * Gets channel data + * + * Returns the data as a string. bool(true) is returned if: + * + * - the server closes the channel + * - if the connection times out + * - if the channel status is CHANNEL_OPEN and the response was CHANNEL_OPEN_CONFIRMATION + * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_SUCCESS + * - if the channel status is CHANNEL_CLOSE and the response was CHANNEL_CLOSE + * + * bool(false) is returned if: + * + * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_FAILURE + * + * @param int $client_channel + * @param bool $skip_extended + * @return mixed + * @throws \RuntimeException on connection error + */ + protected function get_channel_packet($client_channel, $skip_extended = false) + { + if (!empty($this->channel_buffers[$client_channel])) { + switch ($this->channel_status[$client_channel]) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + foreach ($this->channel_buffers[$client_channel] as $i => $packet) { + switch (ord($packet[0])) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + case NET_SSH2_MSG_CHANNEL_FAILURE: + unset($this->channel_buffers[$client_channel][$i]); + return substr($packet, 1); + } + } + break; + default: + return substr(array_shift($this->channel_buffers[$client_channel]), 1); + } + } + + while (true) { + if ($this->binary_packet_buffer !== false) { + $response = $this->binary_packet_buffer; + $this->binary_packet_buffer = false; + } else { + $response = $this->get_binary_packet(true); + if ($response === true && $this->is_timeout) { + if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { + $this->close_channel($client_channel); + } + return true; + } + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + } + + if ($client_channel == -1 && $response === true) { + return true; + } + list($type, $channel) = Strings::unpackSSH2('CN', $response); + + // will not be setup yet on incoming channel open request + if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { + $this->window_size_server_to_client[$channel] -= strlen($response); + + // resize the window, if appropriate + if ($this->window_size_server_to_client[$channel] < 0) { + // PuTTY does something more analogous to the following: + //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { + $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); + $this->send_binary_packet($packet); + $this->window_size_server_to_client[$channel] += $this->window_resize; + } + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: + /* + if ($client_channel == self::CHANNEL_EXEC) { + $this->send_channel_packet($client_channel, chr(0)); + } + */ + // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR + list($data_type_code, $data) = Strings::unpackSSH2('Ns', $response); + $this->stdErrorLog .= $data; + if ($skip_extended || $this->quiet_mode) { + continue 2; + } + if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) { + return $data; + } + $this->channel_buffers[$channel][] = chr($type) . $data; + + continue 2; + case NET_SSH2_MSG_CHANNEL_REQUEST: + if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) { + continue 2; + } + list($value) = Strings::unpackSSH2('s', $response); + switch ($value) { + case 'exit-signal': + list( + , // FALSE + $signal_name, + , // core dumped + $error_message + ) = Strings::unpackSSH2('bsbs', $response); + + $this->errors[] = "SSH_MSG_CHANNEL_REQUEST (exit-signal): $signal_name"; + if (strlen($error_message)) { + $this->errors[count($this->errors) - 1] .= "\r\n$error_message"; + } + + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF; + + continue 3; + case 'exit-status': + list(, $this->exit_status) = Strings::unpackSSH2('CN', $response); + + // "The client MAY ignore these messages." + // -- http://tools.ietf.org/html/rfc4254#section-6.10 + + continue 3; + default: + // "Some systems may not implement signals, in which case they SHOULD ignore this message." + // -- http://tools.ietf.org/html/rfc4254#section-6.9 + continue 3; + } + } + + switch ($this->channel_status[$channel]) { + case NET_SSH2_MSG_CHANNEL_OPEN: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: + list( + $this->server_channels[$channel], + $window_size, + $this->packet_size_client_to_server[$channel] + ) = Strings::unpackSSH2('NNN', $response); + + if ($window_size < 0) { + $window_size &= 0x7FFFFFFF; + $window_size += 0x80000000; + } + $this->window_size_client_to_server[$channel] = $window_size; + $result = $client_channel == $channel ? true : $this->get_channel_packet($client_channel, $skip_extended); + $this->on_channel_open(); + return $result; + case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to open channel'); + default: + if ($client_channel == $channel) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unexpected response to open request'); + } + return $this->get_channel_packet($client_channel, $skip_extended); + } + break; + case NET_SSH2_MSG_CHANNEL_REQUEST: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + return true; + case NET_SSH2_MSG_CHANNEL_FAILURE: + return false; + case NET_SSH2_MSG_CHANNEL_DATA: + list($data) = Strings::unpackSSH2('s', $response); + $this->channel_buffers[$channel][] = chr($type) . $data; + return $this->get_channel_packet($client_channel, $skip_extended); + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to fulfill channel request'); + } + case NET_SSH2_MSG_CHANNEL_CLOSE: + if ($client_channel == $channel && $type == NET_SSH2_MSG_CHANNEL_CLOSE) { + return true; + } + return $this->get_channel_packet($client_channel, $skip_extended); + } + } + + // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_DATA: + /* + if ($channel == self::CHANNEL_EXEC) { + // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server + // this actually seems to make things twice as fast. more to the point, the message right after + // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. + // in OpenSSH it slows things down but only by a couple thousandths of a second. + $this->send_channel_packet($channel, chr(0)); + } + */ + list($data) = Strings::unpackSSH2('s', $response); + + if ($channel == self::CHANNEL_AGENT_FORWARD) { + $agent_response = $this->agent->forwardData($data); + if (!is_bool($agent_response)) { + $this->send_channel_packet($channel, $agent_response); + } + break; + } + + if ($client_channel == $channel) { + return $data; + } + $this->channel_buffers[$channel][] = chr($type) . $data; + break; + case NET_SSH2_MSG_CHANNEL_CLOSE: + $this->curTimeout = 5; + + $this->close_channel_bitmap($channel); + + if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + } + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + $this->channelCount--; + + if ($client_channel == $channel) { + return true; + } + // fall-through + case NET_SSH2_MSG_CHANNEL_EOF: + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException("Error reading channel data ($type)"); + } + } + } + + /** + * Sends Binary Packets + * + * See '6. Binary Packet Protocol' of rfc4253 for more info. + * + * @param string $data + * @param string $logged + * @see self::_get_binary_packet() + * @return void + */ + protected function send_binary_packet($data, $logged = null) + { + if (!is_resource($this->fsock) || feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed prematurely'); + } + + if (!isset($logged)) { + $logged = $data; + } + + switch ($this->compress) { + case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: + if (!$this->isAuthenticated()) { + break; + } + // fall-through + case self::NET_SSH2_COMPRESSION_ZLIB: + if (!$this->regenerate_compression_context) { + $header = ''; + } else { + $this->regenerate_compression_context = false; + $this->compress_context = deflate_init(ZLIB_ENCODING_RAW, ['window' => 15]); + $header = "\x78\x9C"; + } + if ($this->compress_context) { + $data = $header . deflate_add($this->compress_context, $data, ZLIB_PARTIAL_FLUSH); + } + } + + // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 + $packet_length = strlen($data) + 9; + if ($this->encrypt && $this->encrypt->usesNonce()) { + $packet_length -= 4; + } + // round up to the nearest $this->encrypt_block_size + $packet_length += (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; + // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length + $padding_length = $packet_length - strlen($data) - 5; + switch (true) { + case $this->encrypt && $this->encrypt->usesNonce(): + case $this->hmac_create instanceof Hash && $this->hmac_create_etm: + $padding_length += 4; + $packet_length += 4; + } + + $padding = Random::string($padding_length); + + // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself + $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); + + $hmac = ''; + if ($this->hmac_create instanceof Hash && !$this->hmac_create_etm) { + if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); + $hmac = $this->hmac_create->hash($packet); + } else { + $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); + } + } + + if ($this->encrypt) { + switch ($this->encryptName) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $this->encrypt->setNonce( + $this->encryptFixedPart . + $this->encryptInvocationCounter + ); + Strings::increment_str($this->encryptInvocationCounter); + $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF")); + $packet = $temp . $this->encrypt->encrypt(substr($packet, 4)); + break; + case 'chacha20-poly1305@openssh.com': + // This should be impossible, but we are checking anyway to narrow the type for Psalm. + if (!($this->encrypt instanceof ChaCha20)) { + throw new \LogicException('$this->encrypt is not a ' . ChaCha20::class); + } + + $nonce = pack('N2', 0, $this->send_seq_no); + + $this->encrypt->setNonce($nonce); + $this->lengthEncrypt->setNonce($nonce); + + $length = $this->lengthEncrypt->encrypt($packet & "\xFF\xFF\xFF\xFF"); + + $this->encrypt->setCounter(0); + // this is the same approach that's implemented in Salsa20::createPoly1305Key() + // but we don't want to use the same AEAD construction that RFC8439 describes + // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) + $this->encrypt->setPoly1305Key( + $this->encrypt->encrypt(str_repeat("\0", 32)) + ); + $this->encrypt->setAAD($length); + $this->encrypt->setCounter(1); + $packet = $length . $this->encrypt->encrypt(substr($packet, 4)); + break; + default: + $packet = $this->hmac_create instanceof Hash && $this->hmac_create_etm ? + ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) : + $this->encrypt->encrypt($packet); + } + } + + if ($this->hmac_create instanceof Hash && $this->hmac_create_etm) { + if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); + $hmac = $this->hmac_create->hash($packet); + } else { + $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); + } + } + + $this->send_seq_no++; + + $packet .= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; + + $start = microtime(true); + $sent = @fputs($this->fsock, $packet); + $stop = microtime(true); + + if (defined('NET_SSH2_LOGGING')) { + $current = microtime(true); + $message_number = isset(self::$message_numbers[ord($logged[0])]) ? self::$message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; + $message_number = '-> ' . $message_number . + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; + $this->append_log($message_number, $logged); + $this->last_packet = $current; + } + + if (strlen($packet) != $sent) { + $this->bitmap = 0; + $message = $sent === false ? + 'Unable to write ' . strlen($packet) . ' bytes' : + "Only $sent of " . strlen($packet) . " bytes were sent"; + throw new \RuntimeException($message); + } + } + + /** + * Logs data packets + * + * Makes sure that only the last 1MB worth of packets will be logged + * + * @param string $message_number + * @param string $message + */ + private function append_log($message_number, $message) + { + $this->append_log_helper( + NET_SSH2_LOGGING, + $message_number, + $message, + $this->message_number_log, + $this->message_log, + $this->log_size, + $this->realtime_log_file, + $this->realtime_log_wrap, + $this->realtime_log_size + ); + } + + /** + * Logs data packet helper + * + * @param int $constant + * @param string $message_number + * @param string $message + * @param array &$message_number_log + * @param array &$message_log + * @param int &$log_size + * @param resource &$realtime_log_file + * @param bool &$realtime_log_wrap + * @param int &$realtime_log_size + */ + protected function append_log_helper($constant, $message_number, $message, array &$message_number_log, array &$message_log, &$log_size, &$realtime_log_file, &$realtime_log_wrap, &$realtime_log_size) + { + // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) + if (strlen($message_number) > 2) { + Strings::shift($message); + } + + switch ($constant) { + // useful for benchmarks + case self::LOG_SIMPLE: + $message_number_log[] = $message_number; + break; + case self::LOG_SIMPLE_REALTIME: + echo $message_number; + echo PHP_SAPI == 'cli' ? "\r\n" : '
'; + @flush(); + @ob_flush(); + break; + // the most useful log for SSH2 + case self::LOG_COMPLEX: + $message_number_log[] = $message_number; + $log_size += strlen($message); + $message_log[] = $message; + while ($log_size > self::LOG_MAX_SIZE) { + $log_size -= strlen(array_shift($message_log)); + array_shift($message_number_log); + } + break; + // dump the output out realtime; packets may be interspersed with non packets, + // passwords won't be filtered out and select other packets may not be correctly + // identified + case self::LOG_REALTIME: + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
';
+                        $stop = '
'; + } + echo $start . $this->format_log([$message], [$message_number]) . $stop; + @flush(); + @ob_flush(); + break; + // basically the same thing as self::LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILENAME + // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. + // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily + // at the beginning of the file + case self::LOG_REALTIME_FILE: + if (!isset($realtime_log_file)) { + // PHP doesn't seem to like using constants in fopen() + $filename = NET_SSH2_LOG_REALTIME_FILENAME; + $fp = fopen($filename, 'w'); + $realtime_log_file = $fp; + } + if (!is_resource($realtime_log_file)) { + break; + } + $entry = $this->format_log([$message], [$message_number]); + if ($realtime_log_wrap) { + $temp = "<<< START >>>\r\n"; + $entry .= $temp; + fseek($realtime_log_file, ftell($realtime_log_file) - strlen($temp)); + } + $realtime_log_size += strlen($entry); + if ($realtime_log_size > self::LOG_MAX_SIZE) { + fseek($realtime_log_file, 0); + $realtime_log_size = strlen($entry); + $realtime_log_wrap = true; + } + fputs($realtime_log_file, $entry); + } + } + + /** + * Sends channel data + * + * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate + * + * @param int $client_channel + * @param string $data + * @return void + */ + protected function send_channel_packet($client_channel, $data) + { + while (strlen($data)) { + if (!$this->window_size_client_to_server[$client_channel]) { + $this->bitmap ^= self::MASK_WINDOW_ADJUST; + // using an invalid channel will let the buffers be built up for the valid channels + $this->get_channel_packet(-1); + $this->bitmap ^= self::MASK_WINDOW_ADJUST; + } + + /* The maximum amount of data allowed is determined by the maximum + packet size for the channel, and the current window size, whichever + is smaller. + -- http://tools.ietf.org/html/rfc4254#section-5.2 */ + $max_size = min( + $this->packet_size_client_to_server[$client_channel], + $this->window_size_client_to_server[$client_channel] + ); + + $temp = Strings::shift($data, $max_size); + $packet = Strings::packSSH2( + 'CNs', + NET_SSH2_MSG_CHANNEL_DATA, + $this->server_channels[$client_channel], + $temp + ); + $this->window_size_client_to_server[$client_channel] -= strlen($temp); + $this->send_binary_packet($packet); + } + } + + /** + * Closes and flushes a channel + * + * \phpseclib3\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server + * and for SFTP channels are presumably closed when the client disconnects. This functions is intended + * for SCP more than anything. + * + * @param int $client_channel + * @param bool $want_reply + * @return void + */ + private function close_channel($client_channel, $want_reply = false) + { + // see http://tools.ietf.org/html/rfc4254#section-5.3 + + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + + if (!$want_reply) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + } + + $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + $this->channelCount--; + + $this->curTimeout = 5; + + while (!is_bool($this->get_channel_packet($client_channel))) { + } + + if ($want_reply) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + } + + $this->close_channel_bitmap($client_channel); + } + + /** + * Maintains execution state bitmap in response to channel closure + * + * @param int $client_channel The channel number to maintain closure status of + * @return void + */ + private function close_channel_bitmap($client_channel) + { + switch ($client_channel) { + case self::CHANNEL_SHELL: + // Shell status has been maintained in the bitmap for backwards + // compatibility sake, but can be removed going forward + if ($this->bitmap & self::MASK_SHELL) { + $this->bitmap &= ~self::MASK_SHELL; + } + break; + } + } + + /** + * Disconnect + * + * @param int $reason + * @return false + */ + protected function disconnect_helper($reason) + { + if ($this->bitmap & self::MASK_CONNECTED) { + $data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', ''); + try { + $this->send_binary_packet($data); + } catch (\Exception $e) { + } + } + + $this->bitmap = 0; + if (is_resource($this->fsock) && get_resource_type($this->fsock) === 'stream') { + fclose($this->fsock); + } + + return false; + } + + /** + * Define Array + * + * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of + * named constants from it, using the value as the name of the constant and the index as the value of the constant. + * If any of the constants that would be defined already exists, none of the constants will be defined. + * + * @param mixed[] ...$args + * @access protected + */ + protected static function define_array(...$args) + { + foreach ($args as $arg) { + foreach ($arg as $key => $value) { + if (!defined($value)) { + define($value, $key); + } else { + break 2; + } + } + } + } + + /** + * Returns a log of the packets that have been sent and received. + * + * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') + * + * @return array|false|string + */ + public function getLog() + { + if (!defined('NET_SSH2_LOGGING')) { + return false; + } + + switch (NET_SSH2_LOGGING) { + case self::LOG_SIMPLE: + return $this->message_number_log; + case self::LOG_COMPLEX: + $log = $this->format_log($this->message_log, $this->message_number_log); + return PHP_SAPI == 'cli' ? $log : '
' . $log . '
'; + default: + return false; + } + } + + /** + * Formats a log for printing + * + * @param array $message_log + * @param array $message_number_log + * @return string + */ + protected function format_log(array $message_log, array $message_number_log) + { + $output = ''; + for ($i = 0; $i < count($message_log); $i++) { + $output .= $message_number_log[$i] . "\r\n"; + $current_log = $message_log[$i]; + $j = 0; + do { + if (strlen($current_log)) { + $output .= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; + } + $fragment = Strings::shift($current_log, $this->log_short_width); + $hex = substr(preg_replace_callback('#.#s', function ($matches) { + return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); + }, $fragment), strlen($this->log_boundary)); + // replace non ASCII printable characters with dots + // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters + // also replace < with a . since < messes up the output on web browsers + $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); + $output .= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; + $j++; + } while (strlen($current_log)); + $output .= "\r\n"; + } + + return $output; + } + + /** + * Helper function for agent->on_channel_open() + * + * Used when channels are created to inform agent + * of said channel opening. Must be called after + * channel open confirmation received + * + */ + private function on_channel_open() + { + if (isset($this->agent)) { + $this->agent->registerChannelOpen($this); + } + } + + /** + * Returns the first value of the intersection of two arrays or false if + * the intersection is empty. The order is defined by the first parameter. + * + * @param array $array1 + * @param array $array2 + * @return mixed False if intersection is empty, else intersected value. + */ + private static function array_intersect_first(array $array1, array $array2) + { + foreach ($array1 as $value) { + if (in_array($value, $array2)) { + return $value; + } + } + return false; + } + + /** + * Returns all errors + * + * @return string[] + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Returns the last error + * + * @return string + */ + public function getLastError() + { + $count = count($this->errors); + + if ($count > 0) { + return $this->errors[$count - 1]; + } + } + + /** + * Return the server identification. + * + * @return string|false + */ + public function getServerIdentification() + { + $this->connect(); + + return $this->server_identifier; + } + + /** + * Returns a list of algorithms the server supports + * + * @return array + */ + public function getServerAlgorithms() + { + $this->connect(); + + return [ + 'kex' => $this->kex_algorithms, + 'hostkey' => $this->server_host_key_algorithms, + 'client_to_server' => [ + 'crypt' => $this->encryption_algorithms_client_to_server, + 'mac' => $this->mac_algorithms_client_to_server, + 'comp' => $this->compression_algorithms_client_to_server, + 'lang' => $this->languages_client_to_server + ], + 'server_to_client' => [ + 'crypt' => $this->encryption_algorithms_server_to_client, + 'mac' => $this->mac_algorithms_server_to_client, + 'comp' => $this->compression_algorithms_server_to_client, + 'lang' => $this->languages_server_to_client + ] + ]; + } + + /** + * Returns a list of KEX algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedKEXAlgorithms() + { + $kex_algorithms = [ + // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using + // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the + // libssh repository for more information. + 'curve25519-sha256', + 'curve25519-sha256@libssh.org', + + 'ecdh-sha2-nistp256', // RFC 5656 + 'ecdh-sha2-nistp384', // RFC 5656 + 'ecdh-sha2-nistp521', // RFC 5656 + + 'diffie-hellman-group-exchange-sha256',// RFC 4419 + 'diffie-hellman-group-exchange-sha1', // RFC 4419 + + // Diffie-Hellman Key Agreement (DH) using integer modulo prime + // groups. + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', // REQUIRED + 'diffie-hellman-group15-sha512', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group17-sha512', + 'diffie-hellman-group18-sha512', + + 'diffie-hellman-group1-sha1', // REQUIRED + ]; + + return $kex_algorithms; + } + + /** + * Returns a list of host key algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedHostKeyAlgorithms() + { + return [ + 'ssh-ed25519', // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-02 + 'ecdsa-sha2-nistp256', // RFC 5656 + 'ecdsa-sha2-nistp384', // RFC 5656 + 'ecdsa-sha2-nistp521', // RFC 5656 + 'rsa-sha2-256', // RFC 8332 + 'rsa-sha2-512', // RFC 8332 + 'ssh-rsa', // RECOMMENDED sign Raw RSA Key + 'ssh-dss' // REQUIRED sign Raw DSS Key + ]; + } + + /** + * Returns a list of symmetric key algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedEncryptionAlgorithms() + { + $algos = [ + // from : + 'aes128-gcm@openssh.com', + 'aes256-gcm@openssh.com', + + // from : + 'arcfour256', + 'arcfour128', + + //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key + + // CTR modes from : + 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key + 'aes192-ctr', // RECOMMENDED AES with 192-bit key + 'aes256-ctr', // RECOMMENDED AES with 256-bit key + + // from : + // one of the big benefits of chacha20-poly1305 is speed. the problem is... + // libsodium doesn't generate the poly1305 keys in the way ssh does and openssl's PHP bindings don't even + // seem to support poly1305 currently. so even if libsodium or openssl are being used for the chacha20 + // part, pure-PHP has to be used for the poly1305 part and that's gonna cause a big slow down. + // speed-wise it winds up being faster to use AES (when openssl or mcrypt are available) and some HMAC + // (which is always gonna be super fast to compute thanks to the hash extension, which + // "is bundled and compiled into PHP by default") + 'chacha20-poly1305@openssh.com', + + 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key + 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key + 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key + + 'aes128-cbc', // RECOMMENDED AES with a 128-bit key + 'aes192-cbc', // OPTIONAL AES with a 192-bit key + 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key + + 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key + 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key + 'twofish256-cbc', + 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc" + // (this is being retained for historical reasons) + + 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode + + 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode + + '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode + + '3des-cbc', // REQUIRED three-key 3DES in CBC mode + + //'none' // OPTIONAL no encryption; NOT RECOMMENDED + ]; + + if (self::$crypto_engine) { + $engines = [self::$crypto_engine]; + } else { + $engines = [ + 'libsodium', + 'OpenSSL (GCM)', + 'OpenSSL', + 'mcrypt', + 'Eval', + 'PHP' + ]; + } + + $ciphers = []; + + foreach ($engines as $engine) { + foreach ($algos as $algo) { + $obj = self::encryption_algorithm_to_crypt_instance($algo); + if ($obj instanceof Rijndael) { + $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); + } + switch ($algo) { + case 'chacha20-poly1305@openssh.com': + case 'arcfour128': + case 'arcfour256': + if ($engine != 'Eval') { + continue 2; + } + break; + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + if ($engine == 'OpenSSL') { + continue 2; + } + $obj->setNonce('dummydummydu'); + } + if ($obj->isValidEngine($engine)) { + $algos = array_diff($algos, [$algo]); + $ciphers[] = $algo; + } + } + } + + return $ciphers; + } + + /** + * Returns a list of MAC algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedMACAlgorithms() + { + return [ + 'hmac-sha2-256-etm@openssh.com', + 'hmac-sha2-512-etm@openssh.com', + 'umac-64-etm@openssh.com', + 'umac-128-etm@openssh.com', + 'hmac-sha1-etm@openssh.com', + + // from : + 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) + 'hmac-sha2-512',// OPTIONAL HMAC-SHA512 (digest length = key length = 64) + + // from : + 'umac-64@openssh.com', + 'umac-128@openssh.com', + + 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) + 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) + 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) + 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) + //'none' // OPTIONAL no MAC; NOT RECOMMENDED + ]; + } + + /** + * Returns a list of compression algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedCompressionAlgorithms() + { + $algos = ['none']; // REQUIRED no compression + if (function_exists('deflate_init')) { + $algos[] = 'zlib@openssh.com'; // https://datatracker.ietf.org/doc/html/draft-miller-secsh-compression-delayed + $algos[] = 'zlib'; + } + return $algos; + } + + /** + * Return list of negotiated algorithms + * + * Uses the same format as https://www.php.net/ssh2-methods-negotiated + * + * @return array + */ + public function getAlgorithmsNegotiated() + { + $this->connect(); + + $compression_map = [ + self::NET_SSH2_COMPRESSION_NONE => 'none', + self::NET_SSH2_COMPRESSION_ZLIB => 'zlib', + self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com' + ]; + + return [ + 'kex' => $this->kex_algorithm, + 'hostkey' => $this->signature_format, + 'client_to_server' => [ + 'crypt' => $this->encryptName, + 'mac' => $this->hmac_create_name, + 'comp' => $compression_map[$this->compress], + ], + 'server_to_client' => [ + 'crypt' => $this->decryptName, + 'mac' => $this->hmac_check_name, + 'comp' => $compression_map[$this->decompress], + ] + ]; + } + + /** + * Force multiple channels (even if phpseclib has decided to disable them) + */ + public function forceMultipleChannels() + { + $this->errorOnMultipleChannels = false; + } + + /** + * Allows you to set the terminal + * + * @param string $term + */ + public function setTerminal($term) + { + $this->term = $term; + } + + /** + * Accepts an associative array with up to four parameters as described at + * + * + * @param array $methods + */ + public function setPreferredAlgorithms(array $methods) + { + $preferred = $methods; + + if (isset($preferred['kex'])) { + $preferred['kex'] = array_intersect( + $preferred['kex'], + static::getSupportedKEXAlgorithms() + ); + } + + if (isset($preferred['hostkey'])) { + $preferred['hostkey'] = array_intersect( + $preferred['hostkey'], + static::getSupportedHostKeyAlgorithms() + ); + } + + $keys = ['client_to_server', 'server_to_client']; + foreach ($keys as $key) { + if (isset($preferred[$key])) { + $a = &$preferred[$key]; + if (isset($a['crypt'])) { + $a['crypt'] = array_intersect( + $a['crypt'], + static::getSupportedEncryptionAlgorithms() + ); + } + if (isset($a['comp'])) { + $a['comp'] = array_intersect( + $a['comp'], + static::getSupportedCompressionAlgorithms() + ); + } + if (isset($a['mac'])) { + $a['mac'] = array_intersect( + $a['mac'], + static::getSupportedMACAlgorithms() + ); + } + } + } + + $keys = [ + 'kex', + 'hostkey', + 'client_to_server/crypt', + 'client_to_server/comp', + 'client_to_server/mac', + 'server_to_client/crypt', + 'server_to_client/comp', + 'server_to_client/mac', + ]; + foreach ($keys as $key) { + $p = $preferred; + $m = $methods; + + $subkeys = explode('/', $key); + foreach ($subkeys as $subkey) { + if (!isset($p[$subkey])) { + continue 2; + } + $p = $p[$subkey]; + $m = $m[$subkey]; + } + + if (count($p) != count($m)) { + $diff = array_diff($m, $p); + $msg = count($diff) == 1 ? + ' is not a supported algorithm' : + ' are not supported algorithms'; + throw new UnsupportedAlgorithmException(implode(', ', $diff) . $msg); + } + } + + $this->preferred = $preferred; + } + + /** + * Returns the banner message. + * + * Quoting from the RFC, "in some jurisdictions, sending a warning message before + * authentication may be relevant for getting legal protection." + * + * @return string + */ + public function getBannerMessage() + { + return $this->banner_message; + } + + /** + * Returns the server public host key. + * + * Caching this the first time you connect to a server and checking the result on subsequent connections + * is recommended. Returns false if the server signature is not signed correctly with the public host key. + * + * @return string|false + * @throws \RuntimeException on badly formatted keys + * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format + */ + public function getServerPublicHostKey() + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + $this->connect(); + } + + $signature = $this->signature; + $server_public_host_key = base64_encode($this->server_public_host_key); + + if ($this->signature_validated) { + return $this->bitmap ? + $this->signature_format . ' ' . $server_public_host_key : + false; + } + + $this->signature_validated = true; + + switch ($this->signature_format) { + case 'ssh-ed25519': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + $key = EC::loadFormat('OpenSSH', $server_public_host_key) + ->withSignatureFormat('SSH2'); + switch ($this->signature_format) { + case 'ssh-ed25519': + $hash = 'sha512'; + break; + case 'ecdsa-sha2-nistp256': + $hash = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + $hash = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + $hash = 'sha512'; + } + $key = $key->withHash($hash); + break; + case 'ssh-dss': + $key = DSA::loadFormat('OpenSSH', $server_public_host_key) + ->withSignatureFormat('SSH2') + ->withHash('sha1'); + break; + case 'ssh-rsa': + case 'rsa-sha2-256': + case 'rsa-sha2-512': + // could be ssh-rsa, rsa-sha2-256, rsa-sha2-512 + // we don't check here because we already checked in key_exchange + // some signatures have the type embedded within the message and some don't + list(, $signature) = Strings::unpackSSH2('ss', $signature); + + $key = RSA::loadFormat('OpenSSH', $server_public_host_key) + ->withPadding(RSA::SIGNATURE_PKCS1); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + } + $key = $key->withHash($hash); + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new NoSupportedAlgorithmsException('Unsupported signature format'); + } + + if (!$key->verify($this->exchange_hash, $signature)) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + }; + + return $this->signature_format . ' ' . $server_public_host_key; + } + + /** + * Returns the exit status of an SSH command or false. + * + * @return false|int + */ + public function getExitStatus() + { + if (is_null($this->exit_status)) { + return false; + } + return $this->exit_status; + } + + /** + * Returns the number of columns for the terminal window size. + * + * @return int + */ + public function getWindowColumns() + { + return $this->windowColumns; + } + + /** + * Returns the number of rows for the terminal window size. + * + * @return int + */ + public function getWindowRows() + { + return $this->windowRows; + } + + /** + * Sets the number of columns for the terminal window size. + * + * @param int $value + */ + public function setWindowColumns($value) + { + $this->windowColumns = $value; + } + + /** + * Sets the number of rows for the terminal window size. + * + * @param int $value + */ + public function setWindowRows($value) + { + $this->windowRows = $value; + } + + /** + * Sets the number of columns and rows for the terminal window size. + * + * @param int $columns + * @param int $rows + */ + public function setWindowSize($columns = 80, $rows = 24) + { + $this->windowColumns = $columns; + $this->windowRows = $rows; + } + + /** + * To String Magic Method + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->getResourceId(); + } + + /** + * Get Resource ID + * + * We use {} because that symbols should not be in URL according to + * {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}. + * It will safe us from any conflicts, because otherwise regexp will + * match all alphanumeric domains. + * + * @return string + */ + public function getResourceId() + { + return '{' . spl_object_hash($this) . '}'; + } + + /** + * Return existing connection + * + * @param string $id + * + * @return bool|SSH2 will return false if no such connection + */ + public static function getConnectionByResourceId($id) + { + if (isset(self::$connections[$id])) { + return self::$connections[$id] instanceof \WeakReference ? self::$connections[$id]->get() : self::$connections[$id]; + } + return false; + } + + /** + * Return all excising connections + * + * @return array + */ + public static function getConnections() + { + if (!class_exists('WeakReference')) { + /** @var array */ + return self::$connections; + } + $temp = []; + foreach (self::$connections as $key => $ref) { + $temp[$key] = $ref->get(); + } + return $temp; + } + + /* + * Update packet types in log history + * + * @param string $old + * @param string $new + */ + private function updateLogHistory($old, $new) + { + if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { + $this->message_number_log[count($this->message_number_log) - 1] = str_replace( + $old, + $new, + $this->message_number_log[count($this->message_number_log) - 1] + ); + } + } + + /** + * Return the list of authentication methods that may productively continue authentication. + * + * @see https://tools.ietf.org/html/rfc4252#section-5.1 + * @return array|null + */ + public function getAuthMethodsToContinue() + { + return $this->auth_methods_to_continue; + } + + /** + * Enables "smart" multi-factor authentication (MFA) + */ + public function enableSmartMFA() + { + $this->smartMFA = true; + } + + /** + * Disables "smart" multi-factor authentication (MFA) + */ + public function disableSmartMFA() + { + $this->smartMFA = false; + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php new file mode 100644 index 000000000..26ca32275 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php @@ -0,0 +1,286 @@ + + * login('username', $agent)) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2014 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Net\SSH2; +use phpseclib3\System\SSH\Agent\Identity; + +/** + * Pure-PHP ssh-agent client identity factory + * + * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects + * + * @author Jim Wigginton + */ +class Agent +{ + use Common\Traits\ReadBytes; + + // Message numbers + + // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) + const SSH_AGENTC_REQUEST_IDENTITIES = 11; + // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). + const SSH_AGENT_IDENTITIES_ANSWER = 12; + // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) + const SSH_AGENTC_SIGN_REQUEST = 13; + // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) + const SSH_AGENT_SIGN_RESPONSE = 14; + + // Agent forwarding status + + // no forwarding requested and not active + const FORWARD_NONE = 0; + // request agent forwarding when opportune + const FORWARD_REQUEST = 1; + // forwarding has been request and is active + const FORWARD_ACTIVE = 2; + + /** + * Unused + */ + const SSH_AGENT_FAILURE = 5; + + /** + * Socket Resource + * + * @var resource + */ + private $fsock; + + /** + * Agent forwarding status + * + * @var int + */ + private $forward_status = self::FORWARD_NONE; + + /** + * Buffer for accumulating forwarded authentication + * agent data arriving on SSH data channel destined + * for agent unix socket + * + * @var string + */ + private $socket_buffer = ''; + + /** + * Tracking the number of bytes we are expecting + * to arrive for the agent socket on the SSH data + * channel + * + * @var int + */ + private $expected_bytes = 0; + + /** + * Default Constructor + * + * @return \phpseclib3\System\SSH\Agent + * @throws \phpseclib3\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found + * @throws \RuntimeException on connection errors + */ + public function __construct($address = null) + { + if (!$address) { + switch (true) { + case isset($_SERVER['SSH_AUTH_SOCK']): + $address = $_SERVER['SSH_AUTH_SOCK']; + break; + case isset($_ENV['SSH_AUTH_SOCK']): + $address = $_ENV['SSH_AUTH_SOCK']; + break; + default: + throw new BadConfigurationException('SSH_AUTH_SOCK not found'); + } + } + + if (in_array('unix', stream_get_transports())) { + $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); + if (!$this->fsock) { + throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); + } + } else { + if (substr($address, 0, 9) != '\\\\.\\pipe\\' || strpos(substr($address, 9), '\\') !== false) { + throw new \RuntimeException('Address is not formatted as a named pipe should be'); + } + + $this->fsock = fopen($address, 'r+b'); + if (!$this->fsock) { + throw new \RuntimeException('Unable to open address'); + } + } + } + + /** + * Request Identities + * + * See "2.5.2 Requesting a list of protocol 2 keys" + * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects + * + * @return array + * @throws \RuntimeException on receipt of unexpected packets + */ + public function requestIdentities() + { + if (!$this->fsock) { + return []; + } + + $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); + if (strlen($packet) != fputs($this->fsock, $packet)) { + throw new \RuntimeException('Connection closed while requesting identities'); + } + + $length = current(unpack('N', $this->readBytes(4))); + $packet = $this->readBytes($length); + + list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); + if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { + throw new \RuntimeException('Unable to request identities'); + } + + $identities = []; + for ($i = 0; $i < $keyCount; $i++) { + list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); + $temp = $key_blob; + list($key_type) = Strings::unpackSSH2('s', $temp); + switch ($key_type) { + case 'ssh-rsa': + case 'ssh-dss': + case 'ssh-ed25519': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + $key = PublicKeyLoader::load($key_type . ' ' . base64_encode($key_blob)); + } + // resources are passed by reference by default + if (isset($key)) { + $identity = (new Identity($this->fsock)) + ->withPublicKey($key) + ->withPublicKeyBlob($key_blob); + $identities[] = $identity; + unset($key); + } + } + + return $identities; + } + + /** + * Signal that agent forwarding should + * be requested when a channel is opened + * + * @return void + */ + public function startSSHForwarding() + { + if ($this->forward_status == self::FORWARD_NONE) { + $this->forward_status = self::FORWARD_REQUEST; + } + } + + /** + * Request agent forwarding of remote server + * + * @param \phpseclib3\Net\SSH2 $ssh + * @return bool + */ + private function request_forwarding(SSH2 $ssh) + { + if (!$ssh->requestAgentForwarding()) { + return false; + } + + $this->forward_status = self::FORWARD_ACTIVE; + + return true; + } + + /** + * On successful channel open + * + * This method is called upon successful channel + * open to give the SSH Agent an opportunity + * to take further action. i.e. request agent forwarding + * + * @param \phpseclib3\Net\SSH2 $ssh + */ + public function registerChannelOpen(SSH2 $ssh) + { + if ($this->forward_status == self::FORWARD_REQUEST) { + $this->request_forwarding($ssh); + } + } + + /** + * Forward data to SSH Agent and return data reply + * + * @param string $data + * @return string Data from SSH Agent + * @throws \RuntimeException on connection errors + */ + public function forwardData($data) + { + if ($this->expected_bytes > 0) { + $this->socket_buffer .= $data; + $this->expected_bytes -= strlen($data); + } else { + $agent_data_bytes = current(unpack('N', $data)); + $current_data_bytes = strlen($data); + $this->socket_buffer = $data; + if ($current_data_bytes != $agent_data_bytes + 4) { + $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes; + return false; + } + } + + if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { + throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); + } + + $this->socket_buffer = ''; + $this->expected_bytes = 0; + + $agent_reply_bytes = current(unpack('N', $this->readBytes(4))); + + $agent_reply_data = $this->readBytes($agent_reply_bytes); + $agent_reply_data = current(unpack('a*', $agent_reply_data)); + + return pack('Na*', $agent_reply_bytes, $agent_reply_data); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php new file mode 100644 index 000000000..653e8ea5d --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php @@ -0,0 +1,320 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH\Agent; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\System\SSH\Agent; +use phpseclib3\System\SSH\Common\Traits\ReadBytes; + +/** + * Pure-PHP ssh-agent client identity object + * + * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class. + * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA + * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. + * The methods in this interface would be getPublicKey and sign since those are the + * methods phpseclib looks for to perform public key authentication. + * + * @author Jim Wigginton + * @internal + */ +class Identity implements PrivateKey +{ + use ReadBytes; + + // Signature Flags + // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 + const SSH_AGENT_RSA2_256 = 2; + const SSH_AGENT_RSA2_512 = 4; + + /** + * Key Object + * + * @var PublicKey + * @see self::getPublicKey() + */ + private $key; + + /** + * Key Blob + * + * @var string + * @see self::sign() + */ + private $key_blob; + + /** + * Socket Resource + * + * @var resource + * @see self::sign() + */ + private $fsock; + + /** + * Signature flags + * + * @var int + * @see self::sign() + * @see self::setHash() + */ + private $flags = 0; + + /** + * Curve Aliases + * + * @var array + */ + private static $curveAliases = [ + 'secp256r1' => 'nistp256', + 'secp384r1' => 'nistp384', + 'secp521r1' => 'nistp521', + 'Ed25519' => 'Ed25519' + ]; + + /** + * Default Constructor. + * + * @param resource $fsock + */ + public function __construct($fsock) + { + $this->fsock = $fsock; + } + + /** + * Set Public Key + * + * Called by \phpseclib3\System\SSH\Agent::requestIdentities() + * + * @param \phpseclib3\Crypt\Common\PublicKey $key + */ + public function withPublicKey(PublicKey $key) + { + if ($key instanceof EC) { + if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) { + throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519'); + } + } + + $new = clone $this; + $new->key = $key; + return $new; + } + + /** + * Set Public Key + * + * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key + * but this saves a small amount of computation. + * + * @param string $key_blob + */ + public function withPublicKeyBlob($key_blob) + { + $new = clone $this; + $new->key_blob = $key_blob; + return $new; + } + + /** + * Get Public Key + * + * Wrapper for $this->key->getPublicKey() + * + * @param string $type optional + * @return mixed + */ + public function getPublicKey($type = 'PKCS8') + { + return $this->key; + } + + /** + * Sets the hash + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + $hash = strtolower($hash); + + if ($this->key instanceof RSA) { + $new->flags = 0; + switch ($hash) { + case 'sha1': + break; + case 'sha256': + $new->flags = self::SSH_AGENT_RSA2_256; + break; + case 'sha512': + $new->flags = self::SSH_AGENT_RSA2_512; + break; + default: + throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512'); + } + } + if ($this->key instanceof EC) { + switch ($this->key->getCurve()) { + case 'secp256r1': + $expectedHash = 'sha256'; + break; + case 'secp384r1': + $expectedHash = 'sha384'; + break; + //case 'secp521r1': + //case 'Ed25519': + default: + $expectedHash = 'sha512'; + } + if ($hash != $expectedHash) { + throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$this->key->getCurve()] . ' is ' . $expectedHash); + } + } + if ($this->key instanceof DSA) { + if ($hash != 'sha1') { + throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1'); + } + } + return $new; + } + + /** + * Sets the padding + * + * Only PKCS1 padding is supported + * + * @param string $padding + */ + public function withPadding($padding) + { + if (!$this->key instanceof RSA) { + throw new UnsupportedAlgorithmException('Only RSA keys support padding'); + } + if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) { + throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures'); + } + return $this; + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @param string $format + */ + public function withSignatureFormat($format) + { + if ($this->key instanceof RSA) { + throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting'); + } + if ($format != 'SSH2') { + throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported'); + } + + return $this; + } + + /** + * Returns the curve + * + * Returns a string if it's a named curve, an array if not + * + * @return string|array + */ + public function getCurve() + { + if (!$this->key instanceof EC) { + throw new UnsupportedAlgorithmException('Only EC keys have curves'); + } + + return $this->key->getCurve(); + } + + /** + * Create a signature + * + * See "2.6.2 Protocol 2 private key signature request" + * + * @param string $message + * @return string + * @throws \RuntimeException on connection errors + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + */ + public function sign($message) + { + // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE + $packet = Strings::packSSH2( + 'CssN', + Agent::SSH_AGENTC_SIGN_REQUEST, + $this->key_blob, + $message, + $this->flags + ); + $packet = Strings::packSSH2('s', $packet); + if (strlen($packet) != fputs($this->fsock, $packet)) { + throw new \RuntimeException('Connection closed during signing'); + } + + $length = current(unpack('N', $this->readBytes(4))); + $packet = $this->readBytes($length); + + list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); + if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { + throw new \RuntimeException('Unable to retrieve signature'); + } + + if (!$this->key instanceof RSA) { + return $signature_blob; + } + + list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); + + return $signature_blob; + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + } + + /** + * Sets the password + * + * @param string|bool $password + * @return never + */ + public function withPassword($password = false) + { + throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + } +} diff --git a/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php new file mode 100644 index 000000000..6fd032bd4 --- /dev/null +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php @@ -0,0 +1,37 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH\Common\Traits; + +/** + * ReadBytes trait + * + * @author Jim Wigginton + */ +trait ReadBytes +{ + /** + * Read data + * + * @param int $length + * @throws \RuntimeException on connection errors + */ + public function readBytes($length) + { + $temp = fread($this->fsock, $length); + if (strlen($temp) != $length) { + throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); + } + return $temp; + } +} diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php similarity index 68% rename from libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php rename to libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php index 547688f9f..517106c3a 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php +++ b/libraries/phpseclib3/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php @@ -1,7 +1,12 @@ .sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_length select{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;padding:4px}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{border:1px solid #aaa;border-radius:3px;padding:5px;background-color:transparent;margin-left:3px}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, white 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, white 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, white 0%, #dcdcdc 100%);background:-o-linear-gradient(top, white 0%, #dcdcdc 100%);background:linear-gradient(to bottom, white 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));background:-webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);background:-moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);background:-ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);background:-o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);background:linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:.5em}} + + +@keyframes dtb-spinner{100%{transform:rotate(360deg)}}@-o-keyframes dtb-spinner{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes dtb-spinner{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dtb-spinner{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes dtb-spinner{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}div.dataTables_wrapper{position:relative}div.dt-buttons{position:initial}div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border:2px solid #111;box-shadow:3px 4px 10px 1px rgba(0, 0, 0, 0.3);border-radius:3px;text-align:center;z-index:21}div.dt-button-info h2{padding:.5em;margin:0;font-weight:normal;border-bottom:1px solid #ddd;background-color:#f3f3f3}div.dt-button-info>div{padding:1em}div.dtb-popover-close{position:absolute;top:10px;right:10px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}button.dtb-hide-drop{display:none !important}div.dt-button-collection-title{text-align:center;padding:.3em 0 .5em;margin-left:.5em;margin-right:.5em;font-size:.9em}div.dt-button-collection-title:empty{display:none}span.dt-button-spacer{display:inline-block;margin:.5em;white-space:nowrap}span.dt-button-spacer.bar{border-left:1px solid rgba(0, 0, 0, 0.3);vertical-align:middle;padding-left:.5em}span.dt-button-spacer.bar:empty{height:1em;width:1px;padding-left:0}div.dt-button-collection span.dt-button-spacer{width:100%;font-size:.9em;text-align:center;margin:.5em 0}div.dt-button-collection span.dt-button-spacer:empty{height:0;width:100%}div.dt-button-collection span.dt-button-spacer.bar{border-left:none;border-bottom:1px solid rgba(0, 0, 0, 0.3);padding-left:0}button.dt-button,div.dt-button,a.dt-button,input.dt-button{position:relative;display:inline-block;box-sizing:border-box;margin-left:.167em;margin-right:.167em;margin-bottom:.333em;padding:.5em 1em;border:1px solid rgba(0, 0, 0, 0.3);border-radius:2px;cursor:pointer;font-size:.88em;line-height:1.6em;color:black;white-space:nowrap;overflow:hidden;background-color:rgba(0, 0, 0, 0.1);background:-webkit-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-moz-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-ms-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-o-linear-gradient(top, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:linear-gradient(to bottom, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="rgba(230, 230, 230, 0.1)", EndColorStr="rgba(0, 0, 0, 0.1)");-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;outline:none;text-overflow:ellipsis}button.dt-button:first-child,div.dt-button:first-child,a.dt-button:first-child,input.dt-button:first-child{margin-left:0}button.dt-button.disabled,div.dt-button.disabled,a.dt-button.disabled,input.dt-button.disabled{cursor:default;opacity:.4}button.dt-button:active:not(.disabled),button.dt-button.active:not(.disabled),div.dt-button:active:not(.disabled),div.dt-button.active:not(.disabled),a.dt-button:active:not(.disabled),a.dt-button.active:not(.disabled),input.dt-button:active:not(.disabled),input.dt-button.active:not(.disabled){background-color:rgba(0, 0, 0, 0.1);background:-webkit-linear-gradient(top, rgba(179, 179, 179, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-moz-linear-gradient(top, rgba(179, 179, 179, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-ms-linear-gradient(top, rgba(179, 179, 179, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-o-linear-gradient(top, rgba(179, 179, 179, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:linear-gradient(to bottom, rgba(179, 179, 179, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="rgba(179, 179, 179, 0.1)", EndColorStr="rgba(0, 0, 0, 0.1)");box-shadow:inset 1px 1px 3px #999}button.dt-button:active:not(.disabled):hover:not(.disabled),button.dt-button.active:not(.disabled):hover:not(.disabled),div.dt-button:active:not(.disabled):hover:not(.disabled),div.dt-button.active:not(.disabled):hover:not(.disabled),a.dt-button:active:not(.disabled):hover:not(.disabled),a.dt-button.active:not(.disabled):hover:not(.disabled),input.dt-button:active:not(.disabled):hover:not(.disabled),input.dt-button.active:not(.disabled):hover:not(.disabled){box-shadow:inset 1px 1px 3px #999;background-color:rgba(0, 0, 0, 0.1);background:-webkit-linear-gradient(top, rgba(128, 128, 128, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-moz-linear-gradient(top, rgba(128, 128, 128, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-ms-linear-gradient(top, rgba(128, 128, 128, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-o-linear-gradient(top, rgba(128, 128, 128, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:linear-gradient(to bottom, rgba(128, 128, 128, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="rgba(128, 128, 128, 0.1)", EndColorStr="rgba(0, 0, 0, 0.1)")}button.dt-button:hover,div.dt-button:hover,a.dt-button:hover,input.dt-button:hover{text-decoration:none}button.dt-button:hover:not(.disabled),div.dt-button:hover:not(.disabled),a.dt-button:hover:not(.disabled),input.dt-button:hover:not(.disabled){border:1px solid #666;background-color:rgba(0, 0, 0, 0.1);background:-webkit-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-moz-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-ms-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:-o-linear-gradient(top, rgba(153, 153, 153, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);background:linear-gradient(to bottom, rgba(153, 153, 153, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="rgba(153, 153, 153, 0.1)", EndColorStr="rgba(0, 0, 0, 0.1)")}button.dt-button:focus:not(.disabled),div.dt-button:focus:not(.disabled),a.dt-button:focus:not(.disabled),input.dt-button:focus:not(.disabled){border:1px solid #426c9e;text-shadow:0 1px 0 #c4def1;outline:none;background-color:#79ace9;background:-webkit-linear-gradient(top, #d1e2f7 0%, #79ace9 100%);background:-moz-linear-gradient(top, #d1e2f7 0%, #79ace9 100%);background:-ms-linear-gradient(top, #d1e2f7 0%, #79ace9 100%);background:-o-linear-gradient(top, #d1e2f7 0%, #79ace9 100%);background:linear-gradient(to bottom, #d1e2f7 0%, #79ace9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="#d1e2f7", EndColorStr="#79ace9")}button.dt-button span.dt-down-arrow,div.dt-button span.dt-down-arrow,a.dt-button span.dt-down-arrow,input.dt-button span.dt-down-arrow{position:relative;top:-2px;color:rgba(70, 70, 70, 0.75);font-size:8px;padding-left:10px;line-height:1em}.dt-button embed{outline:none}div.dt-buttons{float:left}div.dt-buttons.buttons-right{float:right}div.dataTables_layout_cell div.dt-buttons{float:none}div.dataTables_layout_cell div.dt-buttons.buttons-right{float:none}div.dt-btn-split-wrapper{display:inline-block}div.dt-button-collection{position:absolute;top:0;left:0;width:200px;margin-top:3px;margin-bottom:3px;padding:4px 4px 2px 4px;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.4);background-color:white;overflow:hidden;z-index:2002;border-radius:5px;box-shadow:3px 4px 10px 1px rgba(0, 0, 0, 0.3);box-sizing:border-box}div.dt-button-collection button.dt-button,div.dt-button-collection div.dt-button,div.dt-button-collection a.dt-button{position:relative;left:0;right:0;width:100%;display:block;float:none;margin:4px 0 2px 0}div.dt-button-collection button.dt-button:active:not(.disabled),div.dt-button-collection button.dt-button.active:not(.disabled),div.dt-button-collection div.dt-button:active:not(.disabled),div.dt-button-collection div.dt-button.active:not(.disabled),div.dt-button-collection a.dt-button:active:not(.disabled),div.dt-button-collection a.dt-button.active:not(.disabled){background-color:#dadada;background:-webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:-moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:-ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:-o-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:linear-gradient(to bottom, #f0f0f0 0%, #dadada 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="#f0f0f0", EndColorStr="#dadada");box-shadow:inset 1px 1px 3px #666}div.dt-button-collection button.dt-button:first-child,div.dt-button-collection div.dt-button:first-child,div.dt-button-collection a.dt-button:first-child{margin-top:0;border-top-left-radius:3px;border-top-right-radius:3px}div.dt-button-collection button.dt-button:last-child,div.dt-button-collection div.dt-button:last-child,div.dt-button-collection a.dt-button:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}div.dt-button-collection div.dt-btn-split-wrapper{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:stretch;margin:4px 0 2px 0}div.dt-button-collection div.dt-btn-split-wrapper button.dt-button{margin:0;display:inline-block;width:0;flex-grow:1;flex-shrink:0;flex-basis:50px;border-radius:0}div.dt-button-collection div.dt-btn-split-wrapper button.dt-btn-split-drop{min-width:20px;flex-grow:0;flex-shrink:0;flex-basis:0}div.dt-button-collection div.dt-btn-split-wrapper:first-child{margin-top:0}div.dt-button-collection div.dt-btn-split-wrapper:first-child button.dt-button{border-top-left-radius:3px}div.dt-button-collection div.dt-btn-split-wrapper:first-child button.dt-btn-split-drop{border-top-right-radius:3px}div.dt-button-collection div.dt-btn-split-wrapper:last-child button.dt-button{border-bottom-left-radius:3px}div.dt-button-collection div.dt-btn-split-wrapper:last-child button.dt-btn-split-drop{border-bottom-right-radius:3px}div.dt-button-collection div.dt-btn-split-wrapper:active:not(.disabled) button.dt-button,div.dt-button-collection div.dt-btn-split-wrapper.active:not(.disabled) button.dt-button{background-color:#dadada;background:-webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:-moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:-ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:-o-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background:linear-gradient(to bottom, #f0f0f0 0%, #dadada 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr="#f0f0f0", EndColorStr="#dadada");box-shadow:inset 0px 0px 4px #666}div.dt-button-collection div.dt-btn-split-wrapper:active:not(.disabled) button.dt-btn-split-drop,div.dt-button-collection div.dt-btn-split-wrapper.active:not(.disabled) button.dt-btn-split-drop{box-shadow:none}div.dt-button-collection.fixed .dt-button:first-child{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}div.dt-button-collection.fixed .dt-button:last-child{border-bottom-left-radius:0;border-bottom-right-radius:0}div.dt-button-collection.fixed{position:fixed;display:block;top:50%;left:50%;margin-left:-75px;border-radius:5px;background-color:white}div.dt-button-collection.fixed.two-column{margin-left:-200px}div.dt-button-collection.fixed.three-column{margin-left:-225px}div.dt-button-collection.fixed.four-column{margin-left:-300px}div.dt-button-collection.fixed.columns{margin-left:-409px}@media screen and (max-width: 1024px){div.dt-button-collection.fixed.columns{margin-left:-308px}}@media screen and (max-width: 640px){div.dt-button-collection.fixed.columns{margin-left:-203px}}@media screen and (max-width: 460px){div.dt-button-collection.fixed.columns{margin-left:-100px}}div.dt-button-collection.fixed>:last-child{max-height:100vh;overflow:auto}div.dt-button-collection.two-column>:last-child,div.dt-button-collection.three-column>:last-child,div.dt-button-collection.four-column>:last-child{display:block !important;-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px}div.dt-button-collection.two-column>:last-child>*,div.dt-button-collection.three-column>:last-child>*,div.dt-button-collection.four-column>:last-child>*{-webkit-column-break-inside:avoid;break-inside:avoid}div.dt-button-collection.two-column{width:400px}div.dt-button-collection.two-column>:last-child{padding-bottom:1px;column-count:2}div.dt-button-collection.three-column{width:450px}div.dt-button-collection.three-column>:last-child{padding-bottom:1px;column-count:3}div.dt-button-collection.four-column{width:600px}div.dt-button-collection.four-column>:last-child{padding-bottom:1px;column-count:4}div.dt-button-collection .dt-button{border-radius:0}div.dt-button-collection.columns{width:auto}div.dt-button-collection.columns>:last-child{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:6px;width:818px;padding-bottom:1px}div.dt-button-collection.columns>:last-child .dt-button{min-width:200px;flex:0 1;margin:0}div.dt-button-collection.columns.dtb-b3>:last-child,div.dt-button-collection.columns.dtb-b2>:last-child,div.dt-button-collection.columns.dtb-b1>:last-child{justify-content:space-between}div.dt-button-collection.columns.dtb-b3 .dt-button{flex:1 1 32%}div.dt-button-collection.columns.dtb-b2 .dt-button{flex:1 1 48%}div.dt-button-collection.columns.dtb-b1 .dt-button{flex:1 1 100%}@media screen and (max-width: 1024px){div.dt-button-collection.columns>:last-child{width:612px}}@media screen and (max-width: 640px){div.dt-button-collection.columns>:last-child{width:406px}div.dt-button-collection.columns.dtb-b3 .dt-button{flex:0 1 32%}}@media screen and (max-width: 460px){div.dt-button-collection.columns>:last-child{width:200px}}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.7);background:-ms-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);background:-moz-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);background:-o-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);background:-webkit-gradient(radial, center center, 0, center center, 497, color-stop(0, rgba(0, 0, 0, 0.3)), color-stop(1, rgba(0, 0, 0, 0.7)));background:-webkit-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);background:radial-gradient(ellipse farthest-corner at center, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);z-index:2001}@media screen and (max-width: 640px){div.dt-buttons{float:none !important;text-align:center}}button.dt-button.processing,div.dt-button.processing,a.dt-button.processing{color:rgba(0, 0, 0, 0.2)}button.dt-button.processing:after,div.dt-button.processing:after,a.dt-button.processing:after{position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;box-sizing:border-box;display:block;content:" ";border:2px solid #282828;border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:dtb-spinner 1500ms infinite linear;-o-animation:dtb-spinner 1500ms infinite linear;-ms-animation:dtb-spinner 1500ms infinite linear;-webkit-animation:dtb-spinner 1500ms infinite linear;-moz-animation:dtb-spinner 1500ms infinite linear}button.dt-btn-split-drop{margin-left:calc(-1px - .333em);padding-bottom:calc(.5em - 1px);border-radius:0px 1px 1px 0px;color:rgba(70, 70, 70, 0.9);border-left:none}button.dt-btn-split-drop span.dt-btn-split-drop-arrow{position:relative;top:-1px;left:-2px;font-size:8px}button.dt-btn-split-drop:hover{z-index:2}button.buttons-split{border-right:1px solid rgba(70, 70, 70, 0);border-radius:1px 0px 0px 1px}button.dt-btn-split-drop-button{background-color:white}button.dt-btn-split-drop-button:hover{background-color:white} + + +table.DTCR_clonedTable.dataTable{position:absolute !important;background-color:rgba(255, 255, 255, 0.7);z-index:202}div.DTCR_pointer{width:1px;background-color:#0259c4;z-index:201} + + +div.dt-datetime{position:absolute;background-color:white;z-index:2050;border:1px solid #ccc;box-shadow:0 5px 15px -5px rgba(0, 0, 0, 0.5);padding:0 20px 6px 20px;width:275px}div.dt-datetime.inline{position:relative;box-shadow:none}div.dt-datetime div.dt-datetime-title{text-align:center;padding:5px 0px 3px}div.dt-datetime div.dt-datetime-buttons{text-align:center}div.dt-datetime div.dt-datetime-buttons a{display:inline-block;padding:0 .5em .5em .5em;margin:0;font-size:.9em}div.dt-datetime div.dt-datetime-buttons a:hover{text-decoration:underline}div.dt-datetime table{border-spacing:0;margin:12px 0;width:100%}div.dt-datetime table.dt-datetime-table-nospace{margin-top:-12px}div.dt-datetime table th{font-size:.8em;color:#777;font-weight:normal;width:14.285714286%;padding:0 0 4px 0;text-align:center}div.dt-datetime table td{font-size:.9em;color:#444;padding:0}div.dt-datetime table td.selectable{text-align:center;background:#f5f5f5}div.dt-datetime table td.selectable.disabled{color:#aaa;background:white}div.dt-datetime table td.selectable.disabled button:hover{color:#aaa;background:white}div.dt-datetime table td.selectable.now{background-color:#ddd}div.dt-datetime table td.selectable.now button{font-weight:bold}div.dt-datetime table td.selectable.selected button{background:#4e6ca3;color:white;border-radius:2px}div.dt-datetime table td.selectable button:hover{background:#ff8000;color:white;border-radius:2px}div.dt-datetime table td.dt-datetime-week{font-size:.7em}div.dt-datetime table button{width:100%;box-sizing:border-box;border:none;background:transparent;font-size:inherit;color:inherit;text-align:center;padding:4px 0;cursor:pointer;margin:0}div.dt-datetime table button span{display:inline-block;min-width:14px;text-align:right}div.dt-datetime table.weekNumber th{width:12.5%}div.dt-datetime div.dt-datetime-calendar table{margin-top:0}div.dt-datetime div.dt-datetime-label{position:relative;display:inline-block;height:30px;padding:5px 6px;border:1px solid transparent;box-sizing:border-box;cursor:pointer}div.dt-datetime div.dt-datetime-label:hover{border:1px solid #ddd;border-radius:2px;background-color:#f5f5f5}div.dt-datetime div.dt-datetime-label select{position:absolute;top:6px;left:0;cursor:pointer;opacity:0}div.dt-datetime.horizontal{width:550px}div.dt-datetime.horizontal div.dt-datetime-date,div.dt-datetime.horizontal div.dt-datetime-time{width:48%}div.dt-datetime.horizontal div.dt-datetime-time{margin-left:4%}div.dt-datetime div.dt-datetime-date{position:relative;float:left;width:100%}div.dt-datetime div.dt-datetime-time{position:relative;float:left;width:100%;text-align:center}div.dt-datetime div.dt-datetime-time>span{vertical-align:middle}div.dt-datetime div.dt-datetime-time th{text-align:left}div.dt-datetime div.dt-datetime-time div.dt-datetime-timeblock{display:inline-block;vertical-align:middle}div.dt-datetime div.dt-datetime-iconLeft,div.dt-datetime div.dt-datetime-iconRight,div.dt-datetime div.dt-datetime-iconUp,div.dt-datetime div.dt-datetime-iconDown{width:30px;height:30px;background-position:center;background-repeat:no-repeat;opacity:.3;overflow:hidden;box-sizing:border-box}div.dt-datetime div.dt-datetime-iconLeft:hover,div.dt-datetime div.dt-datetime-iconRight:hover,div.dt-datetime div.dt-datetime-iconUp:hover,div.dt-datetime div.dt-datetime-iconDown:hover{border:1px solid #ccc;border-radius:2px;background-color:#f0f0f0;opacity:.6}div.dt-datetime div.dt-datetime-iconLeft button,div.dt-datetime div.dt-datetime-iconRight button,div.dt-datetime div.dt-datetime-iconUp button,div.dt-datetime div.dt-datetime-iconDown button{border:none;background:transparent;text-indent:30px;height:100%;width:100%;cursor:pointer}div.dt-datetime div.dt-datetime-iconLeft{position:absolute;top:5px;left:5px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==")}div.dt-datetime div.dt-datetime-iconRight{position:absolute;top:5px;right:5px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=")}div.dt-datetime div.dt-datetime-iconUp{height:20px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAALCAMAAABf9c24AAAAFVBMVEX///99fX1+fn57e3t6enoAAAAAAAC73bqPAAAABnRSTlMAYmJkZt92bnysAAAAL0lEQVR4AWOgJmBhxCvLyopHnpmVjY2VCadeoCxIHrcsWJ4RlyxCHlMWCTBRJxwAjrIBDMWSiM0AAAAASUVORK5CYII=")}div.dt-datetime div.dt-datetime-iconDown{height:20px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAALCAMAAABf9c24AAAAFVBMVEX///99fX1+fn57e3t6enoAAAAAAAC73bqPAAAABnRSTlMAYmJkZt92bnysAAAAMElEQVR4AWOgDmBiRQIsmPKMrGxQgJDFlEfIYpoPk8Utz8qM232MYFfhkQfKUg8AANefAQxecJ58AAAAAElFTkSuQmCC")}div.dt-datetime-error{clear:both;padding:0 1em;max-width:240px;font-size:11px;line-height:1.25em;text-align:center;color:#b11f1f} + + +table.dataTable.display tbody tr.DTFC_NoData{background-color:transparent}tr.even td{background-color:#fff}tr.odd td{background-color:#f9f9f9}tr.selected td{background-color:#a6b4cd}thead th{background-color:white}tfoot th{background-color:white}tr.dt-rowReorder-moving td.dtfc-fixed-left,tr.dt-rowReorder-moving td.dtfc-fixed-right{border-top:2px solid #555 !important;border-bottom:2px solid #555 !important}tr.dt-rowReorder-moving td.dtfc-fixed-left:first-child{border-left:2px solid #555 !important}tr.dt-rowReorder-moving td.dtfc-fixed-right:last-child{border-right:2px solid #555 !important} + + +table.fixedHeader-floating{background-color:white}table.fixedHeader-floating.no-footer{border-bottom-width:0}table.fixedHeader-locked{position:absolute !important;background-color:white}@media print{table.fixedHeader-floating{display:none}} + + +table.dataTable tbody th.focus,table.dataTable tbody td.focus{box-shadow:inset 0 0 1px 2px #36f}div.dtk-focus-alt table.dataTable tbody th.focus,div.dtk-focus-alt table.dataTable tbody td.focus{box-shadow:inset 0 0 1px 2px #ff8b33} + + +table.dataTable.dtr-inline.collapsed>tbody>tr>td.child,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty{cursor:default !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty:before{display:none !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control,table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control{position:relative;padding-left:30px;cursor:pointer}table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control:before{top:50%;left:5px;height:1em;width:1em;margin-top:-9px;display:block;position:absolute;color:white;border:.15em solid white;border-radius:1em;box-shadow:0 0 .2em #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td.dtr-control:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th.dtr-control:before{content:"-";background-color:#d33333}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td.dtr-control,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th.dtr-control{padding-left:27px}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td.dtr-control:before,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th.dtr-control:before{left:4px;height:14px;width:14px;border-radius:14px;line-height:14px;text-indent:3px}table.dataTable.dtr-column>tbody>tr>td.dtr-control,table.dataTable.dtr-column>tbody>tr>th.dtr-control,table.dataTable.dtr-column>tbody>tr>td.control,table.dataTable.dtr-column>tbody>tr>th.control{position:relative;cursor:pointer}table.dataTable.dtr-column>tbody>tr>td.dtr-control:before,table.dataTable.dtr-column>tbody>tr>th.dtr-control:before,table.dataTable.dtr-column>tbody>tr>td.control:before,table.dataTable.dtr-column>tbody>tr>th.control:before{top:50%;left:50%;height:.8em;width:.8em;margin-top:-0.5em;margin-left:-0.5em;display:block;position:absolute;color:white;border:.15em solid white;border-radius:1em;box-shadow:0 0 .2em #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable.dtr-column>tbody>tr.parent td.dtr-control:before,table.dataTable.dtr-column>tbody>tr.parent th.dtr-control:before,table.dataTable.dtr-column>tbody>tr.parent td.control:before,table.dataTable.dtr-column>tbody>tr.parent th.control:before{content:"-";background-color:#d33333}table.dataTable>tbody>tr.child{padding:.5em 1em}table.dataTable>tbody>tr.child:hover{background:transparent !important}table.dataTable>tbody>tr.child ul.dtr-details{display:inline-block;list-style-type:none;margin:0;padding:0}table.dataTable>tbody>tr.child ul.dtr-details>li{border-bottom:1px solid #efefef;padding:.5em 0}table.dataTable>tbody>tr.child ul.dtr-details>li:first-child{padding-top:0}table.dataTable>tbody>tr.child ul.dtr-details>li:last-child{border-bottom:none}table.dataTable>tbody>tr.child span.dtr-title{display:inline-block;min-width:75px;font-weight:bold}div.dtr-modal{position:fixed;box-sizing:border-box;top:0;left:0;height:100%;width:100%;z-index:100;padding:10em 1em}div.dtr-modal div.dtr-modal-display{position:absolute;top:0;left:0;bottom:0;right:0;width:50%;height:50%;overflow:auto;margin:auto;z-index:102;overflow:auto;background-color:#f5f5f7;border:1px solid black;border-radius:.5em;box-shadow:0 12px 30px rgba(0, 0, 0, 0.6)}div.dtr-modal div.dtr-modal-content{position:relative;padding:1em}div.dtr-modal div.dtr-modal-close{position:absolute;top:6px;right:6px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtr-modal div.dtr-modal-close:hover{background-color:#eaeaea}div.dtr-modal div.dtr-modal-background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:101;background:rgba(0, 0, 0, 0.6)}@media screen and (max-width: 767px){div.dtr-modal div.dtr-modal-display{width:95%}} + + +table.dataTable tr.dtrg-group td{background-color:#e0e0e0}table.dataTable tr.dtrg-group.dtrg-level-0 td{font-weight:bold}table.dataTable tr.dtrg-group.dtrg-level-1 td,table.dataTable tr.dtrg-group.dtrg-level-2 td,table.dataTable tr.dtrg-group.dtrg-level-3 td,table.dataTable tr.dtrg-group.dtrg-level-4 td,table.dataTable tr.dtrg-group.dtrg-level-5 td{background-color:#f0f0f0;padding-top:.25em;padding-bottom:.25em;padding-left:2em;font-size:.9em}table.dataTable tr.dtrg-group.dtrg-level-2 td{background-color:#f3f3f3;padding-left:2.5em}table.dataTable tr.dtrg-group.dtrg-level-3 td{background-color:#f3f3f3;padding-left:3em}table.dataTable tr.dtrg-group.dtrg-level-4 td{background-color:#f3f3f3;padding-left:3.5em}table.dataTable tr.dtrg-group.dtrg-level-5 td{background-color:#f3f3f3;padding-left:4em} + + +table.dt-rowReorder-float{position:absolute !important;opacity:.8;table-layout:fixed;outline:2px solid #888;outline-offset:-2px;z-index:2001}tr.dt-rowReorder-moving{outline:2px solid #555;outline-offset:-2px}body.dt-rowReorder-noOverflow{overflow-x:hidden}table.dataTable td.reorder{text-align:center;cursor:move} + + +div.dts{display:block !important}div.dts tbody th,div.dts tbody td{white-space:nowrap}div.dts div.dts_loading{z-index:1}div.dts div.dts_label{position:absolute;right:10px;background:rgba(0, 0, 0, 0.8);color:white;box-shadow:3px 3px 10px rgba(0, 0, 0, 0.5);text-align:right;border-radius:3px;padding:.4em;z-index:2;display:none}div.dts div.dataTables_scrollBody{background:repeating-linear-gradient(45deg, #edeeff, #edeeff 10px, white 10px, white 20px)}div.dts div.dataTables_scrollBody table{z-index:2}div.dts div.dataTables_paginate,div.dts div.dataTables_length{display:none} + + +div.dt-button-collection{overflow:visible !important;z-index:2002 !important}div.dt-button-collection div.dtsb-searchBuilder{width:99% !important;padding-left:10px !important;padding-right:10px !important}div.dt-button-collection.dtb-collection-closeable div.dtsb-titleRow{padding-right:40px}.dtsb-greyscale{border:1px solid #cecece !important}div.dtsb-logicContainer .dtsb-greyscale{border:none !important}div.dtsb-searchBuilder{justify-content:space-evenly;cursor:default;margin-bottom:1em;text-align:left}div.dtsb-searchBuilder button.dtsb-button,div.dtsb-searchBuilder select{font-size:1em}div.dtsb-searchBuilder div.dtsb-titleRow{justify-content:space-evenly;margin-bottom:.5em}div.dtsb-searchBuilder div.dtsb-titleRow div.dtsb-title{display:inline-block;padding-top:6px}div.dtsb-searchBuilder div.dtsb-titleRow div.dtsb-title:empty{display:inline}div.dtsb-searchBuilder div.dtsb-titleRow button.dtsb-clearAll{float:right;margin-bottom:.333em}div.dtsb-searchBuilder div.dtsb-vertical .dtsb-value,div.dtsb-searchBuilder div.dtsb-vertical .dtsb-data,div.dtsb-searchBuilder div.dtsb-vertical .dtsb-condition{display:block}div.dtsb-searchBuilder div.dtsb-group{position:relative;clear:both;margin-bottom:.8em}div.dtsb-searchBuilder div.dtsb-group button.dtsb-clearGroup{margin:2px;text-align:center;padding:0}div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-o-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);position:absolute;margin-top:.8em;margin-right:.8em}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria{margin-bottom:.8em}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-dropDown,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-input{padding:.4em;margin-right:.8em;max-width:20em;background-color:rgba(200, 200, 200, 0.3)}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-dropDown option.dtsb-notItalic,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-input option.dtsb-notItalic{font-style:normal}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-italic{font-style:italic}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer{float:right;display:inline-block}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-delete,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-right,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-left{margin-right:.8em}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-delete:last-child,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-right:last-child,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-left:last-child{margin-right:0}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria span.dtsp-joiner{margin-right:.8em}div.dtsb-searchBuilder button,div.dtsb-searchBuilder select,div.dtsb-searchBuilder input{background-color:#f9f9f9}div.dtsb-searchBuilder button.dtsb-button{position:relative;display:inline-block;box-sizing:border-box;padding:.5em 1em;border:1px solid rgba(0, 0, 0, 0.3);border-radius:2px;cursor:pointer;font-size:.88em;line-height:1.6em;color:black;white-space:nowrap;overflow:hidden;background-color:rgba(0, 0, 0, 0.1);background:linear-gradient(to bottom, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;outline:none;text-overflow:ellipsis}div.dtsb-searchBuilder button.dtsb-button:hover{background-color:#cecece !important;cursor:pointer}div.dtsb-searchBuilder div.dtsb-logicContainer{border:1px solid rgba(0, 0, 0, 0.3);background-color:rgba(0, 0, 0, 0.1);background:linear-gradient(to right, rgba(230, 230, 230, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%)}div.dtsb-searchBuilder div.dtsb-logicContainer button{border:1px solid transparent;background:transparent}div.dtsb-searchBuilder button.dtsb-clearGroup{min-width:2em;padding:0}div.dtsb-searchBuilder button.dtsb-iptbtn{min-width:100px;text-align:left}div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer{border:1px solid;border-color:#cecece;border-radius:3px;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start}div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer button.dtsb-logic{border:none;border-radius:0px;flex-grow:1;flex-shrink:0;flex-basis:3em;margin:0px}div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer button.dtsb-clearGroup{border:none;border-radius:0px;width:2em;margin:0px}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-dropDown,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-input{border:1px solid;border-radius:3px}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-condition{border-color:#48b13c}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-data{border-color:#e70f00}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-value,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-value{border-color:#0069ba}div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-condition option.dtsb-option,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-data option.dtsb-option,div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-value option.dtsb-option{background-color:white} + + +div.dtsp-topRow{display:flex;flex-direction:row;flex-wrap:nowrap;border:2px solid rgba(0, 0, 0, 0);border-radius:3px;justify-content:space-around;align-content:flex-start;align-items:flex-start;min-height:37px}div.dtsp-topRow input.dtsp-search{text-overflow:ellipsis;min-width:50px;flex-basis:90px;max-width:none}div.dtsp-topRow input.dtsp-search::placeholder{color:black}div.dtsp-topRow div.dtsp-subRow1{display:flex;flex-direction:row;flex-wrap:nowrap;flex:1 1 auto}div.dtsp-topRow div.dtsp-subRow1 div.dtsp-searchCont{position:relative;width:100%}div.dtsp-topRow div.dtsp-subRow1 div.dtsp-searchCont input.dtsp-disabledButton{padding-top:10px;padding-bottom:10px;background-color:transparent}div.dtsp-topRow div.dtsp-subRow1 input{padding-right:2em;width:100% !important;box-sizing:border-box;font-size:1em}div.dtsp-topRow div.dtsp-subRow1 button.dtsp-searchIcon{position:absolute;top:0;right:0;bottom:0;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAABbmlDQ1BpY2MAACiRdZE7SwNBFIU/EyWikRRaiFhsoWKhEBREO42FTZAQFYza7G5eQhKX3QQJtoKNhWAh2vgq/AfaCrYKgqAIIhb+Al+NhPVOEkiQZJbZ+3FmzmXmDHjCGTPrtAYhm8vb0bmQthxb0Xzv+PHRxRSabjrWTCQSpun4eaRF1YdR1av5voajM55wTGhpF54wLTsvPC0c3sxbineFe8y0Hhc+ER6x5YDCt0o3KvymOFXhL8X2YnQWPKqnlqpjo47NtJ0VHhYeyGYKZvU86ib+RG5pQWqfzH4coswRQsOgwDoZ8oxKzUlmjX3Bsm+eDfGY8rcoYosjRVq8I6IWpGtCalL0hHwZiir3/3k6yfGxSnd/CNpeXfdzEHz7UNpz3d9T1y2dgfcFrnM1/4bkNPkt+l5NGziGwDZc3tQ04wCudqD32dJtvSx5ZXqSSfi4gK4YdN9Dx2olq+o650+wuCVPdAeHRzAk+wNrfw8JaBFXEnV+AAAACXBIWXMAAA9hAAAPYQGoP6dpAAABMUlEQVQoU6XRr0vDQRjH8akoM4iIjqGoOIZ5oIjB5XWxajaYDGLSIhhNYjcPRDSJwbQNw+L+BNGgYYo/5pT5/shz8vDlBgMPXux7z3N3z+25VOofYyCyd4ZYCavI4gXPsRp9LqiDdrEMH+8wv8Vh8gBfWclFPOEUN3hAHjlMoRa7wTzBS5xgKLFglPkZLjDic6HyDsEMNvGR2Nxifoci3tEI+X770JU0XmPXIlax+LTPh83fFox1X6kxyzdjm9UcdXi9S+Vti6svfyNULhNR9TVsYNhW6Ff9KKCNR7/Zv6eeaQ+6+qcdpu9BqGlp1HFgud+FYdzzUcUExu0Q/cdzHGEFetIlXKPjK/sbqYoOftMiS+j9jzEJPd1Wt+5+kdR/9EM9ucIC5jCbyPc01Q32kfsBppYz3hYFcCwAAAAASUVORK5CYII=") !important;background-repeat:no-repeat;background-position:center;background-size:12px}div.dtsp-topRow div.dtsp-subRow2{white-space:nowrap;flex:0 0 auto}div.dtsp-topRow button.dtsp-nameButton{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAABcGlDQ1BpY2MAACiRdZHNSwJBGMYftTDS8FCHkA57sOigIAXRMQzyYh3UIKvL7rirwe66zK6IdA26dBA6RF36OvQf1DXoWhAERRAR9B/0dQnZ3nEFJXSG2ffHs/O8zDwD+DM6M+yBJGCYDs+mU9JaYV0KviNMM4QoEjKzreXcUh59x88jfKI+JESv/vt6jlBRtRngGyKeYxZ3iBeIMzXHErxHPMbKcpH4hDjO6YDEt0JXPH4TXPL4SzDPZxcBv+gplbpY6WJW5gbxNHHM0KusfR5xk7BqruaoRmlNwEYWaaQgQUEVW9DhIEHVpMx6+5It3woq5GH0tVAHJ0cJZfLGSa1SV5WqRrpKU0dd5P4/T1ubnfG6h1PA4Kvrfk4CwX2g2XDd31PXbZ4BgRfg2uz4K5TT/DfpjY4WOwYiO8DlTUdTDoCrXWD82ZK53JICtPyaBnxcACMFYPQeGN7wsmr/x/kTkN+mJ7oDDo+AKdof2fwDCBRoDkL8UccAAAAJcEhZcwAAD2EAAA9hAag/p2kAAAK2SURBVFgJ7ZY9j41BFICvryCExrJBQ6HyEYVEIREaUZDQIRoR2ViJKCioxV+gkVXYTVZEQiEUhG2EQnxUCh0FKolY4ut5XnM2cyfva3Pt5m7EPcmzZ2bemTNnzjkzd1utnvQi0IvAfxiBy5z5FoxO89kPY+8mbMjtzs47RXs5/WVpbAG6bWExt5PuIibvhVkwmC+ck3eK9ln6/fAddFojYzBVuYSBpcnIEvRaqOw2RcaN18FPuJH0JvRUxbT3wWf4ltiKPgfVidWlbGZgPozDFfgAC+EA/K2EI4cwcAJ+gPaeQ+VQU2SOMMGcPgPl/m/V2p50rrbRsRgt9Iv5h6xtpP22Bz7Ce1C+gFFxfKzOmShcU+Qmyh2w3w8rIJfddHTck66EukL/xPhj+JM8rHNmFys0Pg4v0up3aFNlwR9NYyodd3OL/C64zpsymcTFcf6ElM4YzjAWKYrJkaq8kE/yUYNP4BoYvS1QRo+hNtF5xfkTUjoTheukSFFMjlTFm6PjceOca/SMpKfeCR1L6Uzk/y2WIkVhNFJlJAZhP+hYns7b9D3IPuhY5mYrIv8OrQJvR5NYyNaW4jsU8pSGNySiVx4o5tXq3JkoXE/mg5R/M8dGJCJpKhaDcjBRdbI/Rm8g69c122om33BHmj2CHoV5qa9jUXBraJ+G1fAVjIBO1klc87ro1K4JZ/K35SWW3TwcyDd6TecqnAEd8cGq2+w84xvBm1n3vS0izKkkwh5XNC/GmFPqqAtPF89AOScKuemaNzoTV1SD5dtSbmLf1/RV+tC0WTgcj6R7HEtrVGWaqu/lYDZ/2pvxQ/kIyw/gFByHC9AHw910hv1aUUumyd8yy0QfhmEkfiNod0Xusct68J1qc8Tdux0Z97Q+hsDb+AYGYEbF/4Guw2Q/qDPqZG/zXgT+3Qj8AtKnfWhFwmuAAAAAAElFTkSuQmCC") !important;background-repeat:no-repeat;background-position:center;background-size:23px;vertical-align:bottom}div.dtsp-topRow button.dtsp-countButton{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABcGlDQ1BpY2MAACiRdZHNSwJBGMYftTDS8FCHkA57sOigIAXRMQzyYh3UIKvL7rirwe66zK6IdA26dBA6RF36OvQf1DXoWhAERRAR9B/0dQnZ3nEFJXSG2ffHs/O8zDwD+DM6M+yBJGCYDs+mU9JaYV0KviNMM4QoEjKzreXcUh59x88jfKI+JESv/vt6jlBRtRngGyKeYxZ3iBeIMzXHErxHPMbKcpH4hDjO6YDEt0JXPH4TXPL4SzDPZxcBv+gplbpY6WJW5gbxNHHM0KusfR5xk7BqruaoRmlNwEYWaaQgQUEVW9DhIEHVpMx6+5It3woq5GH0tVAHJ0cJZfLGSa1SV5WqRrpKU0dd5P4/T1ubnfG6h1PA4Kvrfk4CwX2g2XDd31PXbZ4BgRfg2uz4K5TT/DfpjY4WOwYiO8DlTUdTDoCrXWD82ZK53JICtPyaBnxcACMFYPQeGN7wsmr/x/kTkN+mJ7oDDo+AKdof2fwDCBRoDkL8UccAAAAJcEhZcwAAD2EAAA9hAag/p2kAAAG5SURBVEgN3VU9LwVBFF0fiYhofUSlEQkKhU7z/oBCQkIiGr9BgUbhVzy9BAnhFyjV/AYFiU5ICM7ZN+c5Zud5dm3lJmfmzrkz9+7cu3c3y/6jjOBSF8CxXS7FmTkbwqIJjDpJvTcmsJ4K3KPZUpyZsx0sxoB9J6mnAkyC7wGuuCFIipNtEcpcWExgXpOBc78vgj6N+QO4NVsjwdFM59tUIDxDrHMBOeIQ34C5ZDregXuAQm4YcI68nN9B3wr2PcwPAIPkN2EqtJH6b+QZm1ajjTx7BqwAr26Lb+C2Kvpbt0Mb2HAJ7NrGFGfmXO3DeA4UshDfQAVmH0gaUFg852TTTDvlxwBlCtxy9zXyBhQFaq0wMmIdRebrfgosA3zb2hKnqG0oqchp4QbuR8X0TjzABhbdOT8jnQ/atcgqpnfwOA7yqZyTU587ZkIGdesLTt2EkynOnbreMUUKMI/dA4B/QVOcO13CQh+5wWCgDwo/75u59odB/wjmfhbgvACcAOyZPHihMWAoIwxyCLgf1oxfgjzVbgBXSTzIN+f0pg6s5DkcesLMRpsBrgE2XO3CN64JFP7JtUeKHX4CKtRRXFZ+7dEAAAAASUVORK5CYII=") !important;background-repeat:no-repeat;background-position:center;background-size:18px;vertical-align:bottom}div.dtsp-topRow button.dtsp-collapseButton span.dtsp-caret{position:relative;top:2px;display:inline-block}div.dtsp-topRow button.dtsp-collapseButton.dtsp-rotated{transform:rotate(180deg)}div.dtsp-topRow.dtsp-bordered{border:2px solid #f0f0f0;border-radius:3px}div.dtsp-topRow.dtsp-bordered:hover{background-color:#f0f0f0;opacity:.6;border:2px solid #cfcfcf;border-radius:3px;cursor:pointer !important}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane table thead th,div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane table thead td{width:100% !important}div.dt-button-collection{z-index:2002}div.dt-button-collection.dtb-collection-closeable div.dtsp-titleRow{padding-right:25px}div.dtsp-columns-1{max-width:100%;margin:0px !important}div.dtsp-columns-2{max-width:49%;margin:0px !important}div.dtsp-columns-3{max-width:32%;margin:0px !important}div.dtsp-columns-4{max-width:24%;margin:0px !important}div.dtsp-columns-5{max-width:19%;margin:0px !important}div.dtsp-columns-6{max-width:16%;margin:0px !important}div.dtsp-columns-7{max-width:14%;margin:0px !important}div.dtsp-columns-8{min-width:12%;margin:0px !important}div.dtsp-columns-9{max-width:10.5%;margin:0px !important}div.dt-button-collection{float:none}div.dtsp-panesContainer{margin-bottom:1em}div.dtsp-panesContainer div.dataTables_wrapper{width:100%}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_layout_cell{padding:0}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollHead{display:none !important}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody{background:white !important;border-bottom:none}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody thead{display:none}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody table{table-layout:fixed}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody table tr>th,div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody table tr>td{padding:5px 10px}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody td.dtsp-nameColumn{width:100% !important}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody div.dtsp-nameCont{width:100%;display:flex;flex-direction:row;justify-content:flex-start;align-content:flex-start;align-items:flex-start}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody div.dtsp-nameCont span.dtsp-name,div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody div.dtsp-nameCont span.dtsp-pill{cursor:default}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody div.dtsp-nameCont span.dtsp-name{text-overflow:ellipsis;overflow:hidden;display:inline-block;vertical-align:middle;white-space:nowrap;flex-grow:1;text-align:left}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody div.dtsp-nameCont span.dtsp-pill{display:inline-block;background-color:#cfcfcf;text-align:center;border:1px solid #cfcfcf;border-radius:10px;width:auto;min-width:30px;color:black;font-size:.9em;padding:0 4px}div.dtsp-panesContainer div.dataTables_wrapper div.dataTables_scrollBody div.dtsp-nameCont span.dtsp-pill:empty{display:none}div.dtsp-panesContainer{clear:both;padding-left:0;padding-right:0;text-align:center}div.dtsp-panesContainer div.dtsp-searchPanes{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-content:flex-start;align-items:stretch;clear:both;text-align:left}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane{flex-grow:1;flex-shrink:0;font-size:.9em;margin-top:15px !important}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dataTables_wrapper{flex:1;box-sizing:border-box}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dataTables_wrapper div.dataTables_filter{display:none}div.dtsp-panesContainer div.dtsp-title{float:left;padding:10px 0}div.dtsp-panesContainer button.dtsp-clearAll,div.dtsp-panesContainer button.dtsp-collapseAll,div.dtsp-panesContainer button.dtsp-showAll{float:right;padding:10px}div.dtsp-hidden{display:none !important}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dataTables_wrapper{border:2px solid #f0f0f0;border-radius:4px}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dataTables_wrapper:hover{border:2px solid #cfcfcf}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dtsp-selected{border:2px solid #3276b1;border-radius:4px}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dtsp-selected:hover{border:2px solid #286092}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane div.dtsp-topRow div.dtsp-searchCont input.dtsp-search{border:none;padding-left:3px}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane input.dtsp-paneInputButton,div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane button.dtsp-paneButton{height:35px;width:35px;min-width:0;display:inline-block;margin:2px;border:0px solid transparent;background-color:transparent;margin-bottom:0px}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane input.dtsp-paneInputButton:hover,div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane button.dtsp-paneButton:hover{background-color:#f0f0f0;border-radius:2px;cursor:pointer}div.dtsp-panesContainer div.dtsp-searchPanes div.dtsp-searchPane button.dtsp-paneButton{opacity:.6}div.dtsp-panesContainer button.dtsp-clearAll,div.dtsp-panesContainer button.dtsp-collapseAll,div.dtsp-panesContainer button.dtsp-showAll{border:1px solid transparent;background-color:transparent}div.dtsp-panesContainer button.dtsp-clearAll:hover,div.dtsp-panesContainer button.dtsp-collapseAll:hover,div.dtsp-panesContainer button.dtsp-showAll:hover{background-color:#f0f0f0;border-radius:2px;cursor:pointer}div.dtsp-panesContainer button.dtsp-disabledButton{cursor:default !important;color:#7c7c7c}div.dtsp-panesContainer button.dtsp-disabledButton:hover{background-color:transparent}div.dtsp-panesContainer button.dtsp-disabledButton:focus{outline:none}div.dtsp-topRow.dtsp-bordered:hover button.dtsp-disabledButton{cursor:pointer !important;pointer-events:none}div.dtsp-topRow.dtsp-bordered:hover input.dtsp-paneInputButton{pointer-events:none}div.dtsp-narrow{flex-direction:column !important}div.dtsp-narrow div.dtsp-subRows{width:100%;text-align:right}@media screen and (max-width: 767px){div.dtsp-columns-4,div.dtsp-columns-5,div.dtsp-columns-6{max-width:31% !important;min-width:31% !important}}@media screen and (max-width: 640px){div.dtsp-searchPanes{flex-direction:column !important}div.dtsp-searchPane{max-width:98% !important;min-width:98% !important}} + + +table.dataTable tbody>tr.selected,table.dataTable tbody>tr>.selected{background-color:#b0bed9}table.dataTable.stripe tbody>tr.odd.selected,table.dataTable.stripe tbody>tr.odd>.selected,table.dataTable.display tbody>tr.odd.selected,table.dataTable.display tbody>tr.odd>.selected{background-color:#acbad4}table.dataTable.hover tbody>tr.selected:hover,table.dataTable.hover tbody>tr>.selected:hover,table.dataTable.display tbody>tr.selected:hover,table.dataTable.display tbody>tr>.selected:hover{background-color:#aab7d1}table.dataTable.order-column tbody>tr.selected>.sorting_1,table.dataTable.order-column tbody>tr.selected>.sorting_2,table.dataTable.order-column tbody>tr.selected>.sorting_3,table.dataTable.order-column tbody>tr>.selected,table.dataTable.display tbody>tr.selected>.sorting_1,table.dataTable.display tbody>tr.selected>.sorting_2,table.dataTable.display tbody>tr.selected>.sorting_3,table.dataTable.display tbody>tr>.selected{background-color:#acbad5}table.dataTable.display tbody>tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody>tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody>tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody>tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody>tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody>tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody>tr.odd>.selected,table.dataTable.order-column.stripe tbody>tr.odd>.selected{background-color:#a6b4cd}table.dataTable.display tbody>tr.even>.selected,table.dataTable.order-column.stripe tbody>tr.even>.selected{background-color:#acbad5}table.dataTable.display tbody>tr.selected:hover>.sorting_1,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody>tr.selected:hover>.sorting_2,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody>tr.selected:hover>.sorting_3,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_3{background-color:#a5b2cb}table.dataTable.display tbody>tr:hover>.selected,table.dataTable.display tbody>tr>.selected:hover,table.dataTable.order-column.hover tbody>tr:hover>.selected,table.dataTable.order-column.hover tbody>tr>.selected:hover{background-color:#a2aec7}table.dataTable tbody td.select-checkbox,table.dataTable tbody th.select-checkbox{position:relative}table.dataTable tbody td.select-checkbox:before,table.dataTable tbody td.select-checkbox:after,table.dataTable tbody th.select-checkbox:before,table.dataTable tbody th.select-checkbox:after{display:block;position:absolute;top:1.2em;left:50%;width:12px;height:12px;box-sizing:border-box}table.dataTable tbody td.select-checkbox:before,table.dataTable tbody th.select-checkbox:before{content:" ";margin-top:-6px;margin-left:-6px;border:1px solid black;border-radius:3px}table.dataTable tr.selected td.select-checkbox:after,table.dataTable tr.selected th.select-checkbox:after{content:"✓";font-size:20px;margin-top:-19px;margin-left:-6px;text-align:center;text-shadow:1px 1px #b0bed9,-1px -1px #b0bed9,1px -1px #b0bed9,-1px 1px #b0bed9}table.dataTable.compact tbody td.select-checkbox:before,table.dataTable.compact tbody th.select-checkbox:before{margin-top:-12px}table.dataTable.compact tr.selected td.select-checkbox:after,table.dataTable.compact tr.selected th.select-checkbox:after{margin-top:-16px}div.dataTables_wrapper span.select-info,div.dataTables_wrapper span.select-item{margin-left:.5em}@media screen and (max-width: 640px){div.dataTables_wrapper span.select-info,div.dataTables_wrapper span.select-item{margin-left:0;display:block}} + + +div.dtsr-confirmation,div.dtsr-creation{position:fixed;top:20%;left:50%;width:500px;background-color:white;margin-left:-250px;border-radius:6px;box-shadow:0 0 5px #555;border:2px solid #444;z-index:2003;box-sizing:border-box;padding:1em}div.dtsr-confirmation div.dtsr-confirmation-title-row,div.dtsr-creation div.dtsr-confirmation-title-row{text-align:left}div.dtsr-confirmation div.dtsr-confirmation-title-row h2,div.dtsr-creation div.dtsr-confirmation-title-row h2{border-bottom:0px;margin-top:0px;padding-top:0px}div.dtsr-confirmation div.dtsr-confirmation-text,div.dtsr-creation div.dtsr-confirmation-text{text-align:center}div.dtsr-confirmation div.dtsr-confirmation-buttons,div.dtsr-creation div.dtsr-confirmation-buttons{text-align:right;margin-top:1em}div.dtsr-confirmation div.dtsr-confirmation-buttons button.dtsr-confirmation-button,div.dtsr-creation div.dtsr-confirmation-buttons button.dtsr-confirmation-button{margin:0px}div.dtsr-confirmation div.dtsr-creation-text,div.dtsr-creation div.dtsr-creation-text{text-align:left;padding:0px;border:none}div.dtsr-confirmation div.dtsr-creation-text span,div.dtsr-creation div.dtsr-creation-text span{font-size:20px}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-left,div.dtsr-confirmation div.dtsr-creation-form div.dtsr-right,div.dtsr-creation div.dtsr-creation-form div.dtsr-left,div.dtsr-creation div.dtsr-creation-form div.dtsr-right{display:inline-block;width:50%}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-left,div.dtsr-creation div.dtsr-creation-form div.dtsr-left{text-align:right}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-right,div.dtsr-confirmation div.dtsr-creation-form div.dtsr-name-row,div.dtsr-creation div.dtsr-creation-form div.dtsr-right,div.dtsr-creation div.dtsr-creation-form div.dtsr-name-row{text-align:left}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-form-row label.dtsr-name-label,div.dtsr-creation div.dtsr-creation-form div.dtsr-form-row label.dtsr-name-label{width:33.3%;display:inline-block;text-align:right;padding-right:15px;padding-left:15px}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-form-row input.dtsr-name-input,div.dtsr-creation div.dtsr-creation-form div.dtsr-form-row input.dtsr-name-input{width:66.6%;display:inline-block}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-form-row input.dtsr-check-box,div.dtsr-creation div.dtsr-creation-form div.dtsr-form-row input.dtsr-check-box{margin-left:33.3%;margin-right:14px;display:inline-block}div.dtsr-confirmation div.dtsr-creation-form div.dtsr-form-row label.dtsr-toggle-title,div.dtsr-creation div.dtsr-creation-form div.dtsr-form-row label.dtsr-toggle-title{margin-right:-33.3%}div.dtsr-confirmation div.dtsr-confirmation-text,div.dtsr-creation div.dtsr-confirmation-text{text-align:left}div.dtsr-confirmation div.dtsr-confirmation-text label.dtsr-name-label,div.dtsr-creation div.dtsr-confirmation-text label.dtsr-name-label{width:auto;display:inline-block;text-align:right;padding-right:15px}div.dtsr-confirmation div.dtsr-confirmation-text input.dtsr-name-input,div.dtsr-creation div.dtsr-confirmation-text input.dtsr-name-input{width:66.6%;display:inline-block}div.dtsr-confirmation div.dtsr-confirmation-text input.dtsr-check-box,div.dtsr-creation div.dtsr-confirmation-text input.dtsr-check-box{margin-left:33.3%;margin-right:14px;display:inline-block}div.dtsr-confirmation div.dtsr-modal-foot,div.dtsr-creation div.dtsr-modal-foot{text-align:right;padding-top:10px}div.dtsr-confirmation span.dtsr-modal-error,div.dtsr-creation span.dtsr-modal-error{color:red;font-size:.9em}div.dtsr-creation{top:10%}div.dtsr-form-row{padding:10px}div.dtsr-check-row{padding-top:0px}div.dtsr-creation-text{padding:10px}div.dtsr-popover-close{position:absolute;top:10px;right:10px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtsr-background{z-index:2002;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.7);background:radial-gradient(ellipse farthest-corner at center, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%)}div.dt-button-collection h3{text-align:center;margin-top:4px;margin-bottom:8px;font-size:1.5em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}div.dt-button-collection span.dtsr-emptyStates{border-radius:5px;display:inline-block;line-height:1.6em;white-space:nowrap;text-align:center;vertical-align:middle;width:100%;padding-bottom:7px;padding-top:3px}div.dt-button-collection h3{font-size:1.1em}div.dtsr-creation-form div.dtsr-form-row input.dtsr-name-input{width:57% !important;padding:5px 4px;border:1px solid #aaa;border-radius:3px}div.dtsr-creation-form div.dtsr-form-row input.dtsr-check-box{margin-left:calc(33.3% + 30px) !important}div.dtsr-creation-form div.dtsr-form-row label.dtsr-toggle-title{margin-right:calc(-33.3% - 30px) !important} + + diff --git a/media/datatable/css/index.html b/media/datatable/css/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/media/datatable/css/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/datatable/index.html b/media/datatable/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/media/datatable/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/datatable/js/datatables.min.js b/media/datatable/js/datatables.min.js new file mode 100644 index 000000000..cd9d16380 --- /dev/null +++ b/media/datatable/js/datatables.min.js @@ -0,0 +1,1238 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#dt/jszip-2.5.0/dt-1.11.5/b-2.2.2/b-colvis-2.2.2/b-html5-2.2.2/b-print-2.2.2/cr-1.5.5/date-1.1.2/fc-4.0.2/fh-3.2.2/kt-2.6.4/r-2.2.9/rg-1.1.4/rr-1.2.8/sc-2.0.5/sb-1.3.2/sp-2.0.0/sl-1.3.4/sr-1.1.0 + * + * Included libraries: + * JSZip 2.5.0, DataTables 1.11.5, Buttons 2.2.2, Column visibility 2.2.2, HTML5 export 2.2.2, Print view 2.2.2, ColReorder 1.5.5, DateTime 1.1.2, FixedColumns 4.0.2, FixedHeader 3.2.2, KeyTable 2.6.4, Responsive 2.2.9, RowGroup 1.1.4, RowReorder 1.2.8, Scroller 2.0.5, SearchBuilder 1.3.2, SearchPanes 2.0.0, Select 1.3.4, StateRestore 1.1.0 + */ + +/*! + +JSZip - A Javascript class for generating and reading zip files + + +(c) 2009-2014 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.lengtha)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.compressionOptions=null,c.comment=null,c.unixPermissions=null,c.dosPermissions=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a,b){return e.deflateRaw(a,{level:b.level||-1})},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;gc;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a0?a.substring(0,b):""},x=function(a){return"/"!=a.slice(-1)&&(a+="/"),a},y=function(a,b){return b="undefined"!=typeof b?b:!1,a=x(a),this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},z=function(a,b,c){var f,g=new j;return a._data instanceof j?(g.uncompressedSize=a._data.uncompressedSize,g.crc32=a._data.crc32,0===g.uncompressedSize||a.dir?(b=i.STORE,g.compressedContent="",g.crc32=0):a._data.compressionMethod===b.magic?g.compressedContent=a._data.getCompressedContent():(f=a._data.getContent(),g.compressedContent=b.compress(d.transformTo(b.compressInputType,f),c))):(f=p(a),(!f||0===f.length||a.dir)&&(b=i.STORE,f=""),g.uncompressedSize=f.length,g.crc32=e(f),g.compressedContent=b.compress(d.transformTo(b.compressInputType,f),c)),g.compressedSize=g.compressedContent.length,g.compressionMethod=b.magic,g},A=function(a,b){var c=a;return a||(c=b?16893:33204),(65535&c)<<16},B=function(a){return 63&(a||0)},C=function(a,b,c,g,h){var i,j,k,m,n=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),o=b.comment||"",p=d.transformTo("string",l.utf8encode(o)),q=n.length!==b.name.length,r=p.length!==o.length,t=b.options,u="",v="",w="";k=b._initialMetadata.dir!==b.dir?b.dir:t.dir,m=b._initialMetadata.date!==b.date?b.date:t.date;var x=0,y=0;k&&(x|=16),"UNIX"===h?(y=798,x|=A(b.unixPermissions,k)):(y=20,x|=B(b.dosPermissions,k)),i=m.getHours(),i<<=6,i|=m.getMinutes(),i<<=5,i|=m.getSeconds()/2,j=m.getFullYear()-1980,j<<=4,j|=m.getMonth()+1,j<<=5,j|=m.getDate(),q&&(v=s(1,1)+s(e(n),4)+n,u+="up"+s(v.length,2)+v),r&&(w=s(1,1)+s(this.crc32(p),4)+p,u+="uc"+s(w.length,2)+w);var z="";z+="\n\x00",z+=q||r?"\x00\b":"\x00\x00",z+=c.compressionMethod,z+=s(i,2),z+=s(j,2),z+=s(c.crc32,4),z+=s(c.compressedSize,4),z+=s(c.uncompressedSize,4),z+=s(n.length,2),z+=s(u.length,2);var C=f.LOCAL_FILE_HEADER+z+n+u,D=f.CENTRAL_FILE_HEADER+s(y,2)+z+s(p.length,2)+"\x00\x00\x00\x00"+s(x,4)+s(g,4)+n+u+p;return{fileRecord:C,dirRecord:D,compressedObject:c}},D={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=y.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;cg&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;cb?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a>8;this.dir=16&this.externalFileAttributes?!0:!1,a===h&&(this.dosPermissions=63&this.externalFileAttributes),a===i&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileName.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead=hb&&(a.ins_h=(a.ins_h<=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<=hb&&(a.ins_h=(a.ins_h<4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindexk&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindexk&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<q&&(p+=B[f++]<>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<q&&(p+=B[f++]<>>=w,q-=w),15>q&&(p+=B[f++]<>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<q&&(p+=B[f++]<q&&(p+=B[f++]<k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whaven;){if(0===i)break a;i--,m+=e[g++]<>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<n;){if(0===i)break a;i--,m+=e[g++]<>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.haven;){if(0===i)break a;i--,m+=e[g++]<>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1); +break}for(c.back=0;Ab=c.lencode[m&(1<>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<n;){if(0===i)break a;i--,m+=e[g++]<=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++hh?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++jj){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)}); + +/*! + Copyright 2008-2021 SpryMedia Ltd. + + This source file is free software, available under the following license: + MIT license - http://datatables.net/license + + This source file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + + For details please refer to: http://www.datatables.net + DataTables 1.11.5 + ©2008-2021 SpryMedia Ltd - datatables.net/license +*/ +var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(l,z,A){l instanceof String&&(l=String(l));for(var q=l.length,E=0;E").css({position:"fixed",top:0,left:-1*l(z).scrollLeft(),height:1, +width:1,overflow:"hidden"}).append(l("
").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(l("
").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}l.extend(a.oBrowser,u.__browser);a.oScroll.iBarWidth=u.__browser.barWidth} +function Cb(a,b,c,d,e,h){var f=!1;if(c!==q){var g=c;f=!0}for(;d!==e;)a.hasOwnProperty(d)&&(g=f?b(g,a[d],d,a):a[d],f=!0,d+=h);return g}function Ya(a,b){var c=u.defaults.column,d=a.aoColumns.length;c=l.extend({},u.models.oColumn,c,{nTh:b?b:A.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=l.extend({},u.models.oSearch,c[d]);Ga(a,d,l(b).data())}function Ga(a,b,c){b=a.aoColumns[b]; +var d=a.oClasses,e=l(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var h=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);h&&(b.sWidthOrig=h[1])}c!==q&&null!==c&&(Ab(c),P(u.defaults.column,c,!0),c.mDataProp===q||c.mData||(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),c.sClass&&e.addClass(c.sClass),l.extend(b,c),X(b,c,"sWidth","sWidthOrig"),c.iDataSort!==q&&(b.aDataSort=[c.iDataSort]),X(b,c,"aDataSort"));var f=b.mData,g=na(f), +k=b.mRender?na(b.mRender):null;c=function(m){return"string"===typeof m&&-1!==m.indexOf("@")};b._bAttrSrc=l.isPlainObject(f)&&(c(f.sort)||c(f.type)||c(f.filter));b._setter=null;b.fnGetData=function(m,n,p){var t=g(m,n,q,p);return k&&n?k(t,n,m,p):t};b.fnSetData=function(m,n,p){return ha(f)(m,n,p)};"number"!==typeof f&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==l.inArray("asc",b.asSorting);c=-1!==l.inArray("desc",b.asSorting);b.bSortable&&(a||c)?a&&!c? +(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI):(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI="")}function sa(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Za(a);for(var c=0,d=b.length;cm[n])d(g.length+m[n],k);else if("string"===typeof m[n]){var p=0;for(f=g.length;pb&&a[e]--; -1!=d&&c===q&&a.splice(d,1)}function va(a,b,c,d){var e=a.aoData[b],h,f=function(k,m){for(;k.childNodes.length;)k.removeChild(k.firstChild);k.innerHTML=T(a,b,m,"display")};if("dom"!==c&&(c&&"auto"!==c||"dom"!==e.src)){var g=e.anCells;if(g)if(d!==q)f(g[d],d);else for(c=0,h=g.length;c").appendTo(d));var k=0;for(b=g.length;k=a.fnRecordsDisplay()?0:d,a.iInitDisplayStart=-1);c=F(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==l.inArray(!1,c))V(a,!1);else{c=[];var e=0;d=a.asStripeClasses;var h=d.length,f=a.oLanguage,g="ssp"==Q(a),k=a.aiDisplay,m=a._iDisplayStart,n=a.fnDisplayEnd();a.bDrawing=!0;if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,V(a,!1);else if(!g)a.iDraw++;else if(!a.bDestroying&&!b){Gb(a);return}if(0!==k.length)for(b=g?a.aoData.length:n,f=g?0:m;f",{"class":h?d[0]:""}).append(l("
",{valign:"top",colSpan:oa(a),"class":a.oClasses.sRowEmpty}).html(e))[0];F(a,"aoHeaderCallback","header",[l(a.nTHead).children("tr")[0],db(a),m,n,k]);F(a,"aoFooterCallback", +"footer",[l(a.nTFoot).children("tr")[0],db(a),m,n,k]);d=l(a.nTBody);d.children().detach();d.append(l(c));F(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function ka(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&Hb(a);d?ya(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;ja(a);a._drawHold=!1}function Ib(a){var b=a.oClasses,c=l(a.nTable);c=l("
").insertBefore(c);var d=a.oFeatures,e=l("
",{id:a.sTableId+"_wrapper", +"class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var h=a.sDom.split(""),f,g,k,m,n,p,t=0;t")[0];m=h[t+1];if("'"==m||'"'==m){n="";for(p=2;h[t+p]!=m;)n+=h[t+p],p++;"H"==n?n=b.sJUIHeader:"F"==n&&(n=b.sJUIFooter);-1!=n.indexOf(".")?(m=n.split("."),k.id=m[0].substr(1,m[0].length-1),k.className=m[1]):"#"==n.charAt(0)?k.id=n.substr(1,n.length-1):k.className=n;t+=p}e.append(k); +e=l(k)}else if(">"==g)e=e.parent();else if("l"==g&&d.bPaginate&&d.bLengthChange)f=Jb(a);else if("f"==g&&d.bFilter)f=Kb(a);else if("r"==g&&d.bProcessing)f=Lb(a);else if("t"==g)f=Mb(a);else if("i"==g&&d.bInfo)f=Nb(a);else if("p"==g&&d.bPaginate)f=Ob(a);else if(0!==u.ext.feature.length)for(k=u.ext.feature,p=0,m=k.length;p',g=d.sSearch;g=g.match(/_INPUT_/)?g.replace("_INPUT_",f):g+f;b=l("
",{id:h.f?null:c+"_filter","class":b.sFilter}).append(l("
").addClass(b.sLength);a.aanFeatures.l||(k[0].id=c+"_length");k.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));l("select",k).val(a._iDisplayLength).on("change.DT",function(m){kb(a,l(this).val());ja(a)});l(a.nTable).on("length.dt.DT",function(m,n,p){a===n&&l("select",k).val(p)});return k[0]}function Ob(a){var b=a.sPaginationType,c=u.ext.pager[b],d="function"===typeof c,e=function(f){ja(f)};b=l("
").addClass(a.oClasses.sPaging+b)[0]; +var h=a.aanFeatures;d||c.fnInit(a,b,e);h.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(f){if(d){var g=f._iDisplayStart,k=f._iDisplayLength,m=f.fnRecordsDisplay(),n=-1===k;g=n?0:Math.ceil(g/k);k=n?1:Math.ceil(m/k);m=c(g,k);var p;n=0;for(p=h.p.length;nh&& +(d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e",{id:a.aanFeatures.r?null:a.sTableId+"_processing","class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function V(a,b){a.oFeatures.bProcessing&&l(a.aanFeatures.r).css("display",b?"block":"none"); +F(a,null,"processing",[a,b])}function Mb(a){var b=l(a.nTable),c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,h=a.oClasses,f=b.children("caption"),g=f.length?f[0]._captionSide:null,k=l(b[0].cloneNode(!1)),m=l(b[0].cloneNode(!1)),n=b.children("tfoot");n.length||(n=null);k=l("
",{"class":h.sScrollWrapper}).append(l("
",{"class":h.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?d?K(d):null:"100%"}).append(l("
",{"class":h.sScrollHeadInner}).css({"box-sizing":"content-box", +width:c.sXInner||"100%"}).append(k.removeAttr("id").css("margin-left",0).append("top"===g?f:null).append(b.children("thead"))))).append(l("
",{"class":h.sScrollBody}).css({position:"relative",overflow:"auto",width:d?K(d):null}).append(b));n&&k.append(l("
",{"class":h.sScrollFoot}).css({overflow:"hidden",border:0,width:d?d?K(d):null:"100%"}).append(l("
",{"class":h.sScrollFootInner}).append(m.removeAttr("id").css("margin-left",0).append("bottom"===g?f:null).append(b.children("tfoot"))))); +b=k.children();var p=b[0];h=b[1];var t=n?b[2]:null;if(d)l(h).on("scroll.DT",function(v){v=this.scrollLeft;p.scrollLeft=v;n&&(t.scrollLeft=v)});l(h).css("max-height",e);c.bCollapse||l(h).css("height",e);a.nScrollHead=p;a.nScrollBody=h;a.nScrollFoot=t;a.aoDrawCallback.push({fn:Ha,sName:"scrolling"});return k[0]}function Ha(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY;b=b.iBarWidth;var h=l(a.nScrollHead),f=h[0].style,g=h.children("div"),k=g[0].style,m=g.children("table");g=a.nScrollBody;var n=l(g),p= +g.style,t=l(a.nScrollFoot).children("div"),v=t.children("table"),x=l(a.nTHead),w=l(a.nTable),r=w[0],C=r.style,G=a.nTFoot?l(a.nTFoot):null,aa=a.oBrowser,L=aa.bScrollOversize;U(a.aoColumns,"nTh");var O=[],I=[],H=[],ea=[],Y,Ba=function(D){D=D.style;D.paddingTop="0";D.paddingBottom="0";D.borderTopWidth="0";D.borderBottomWidth="0";D.height=0};var fa=g.scrollHeight>g.clientHeight;if(a.scrollBarVis!==fa&&a.scrollBarVis!==q)a.scrollBarVis=fa,sa(a);else{a.scrollBarVis=fa;w.children("thead, tfoot").remove(); +if(G){var ba=G.clone().prependTo(w);var la=G.find("tr");ba=ba.find("tr")}var mb=x.clone().prependTo(w);x=x.find("tr");fa=mb.find("tr");mb.find("th, td").removeAttr("tabindex");c||(p.width="100%",h[0].style.width="100%");l.each(Na(a,mb),function(D,W){Y=ta(a,D);W.style.width=a.aoColumns[Y].sWidth});G&&ca(function(D){D.style.width=""},ba);h=w.outerWidth();""===c?(C.width="100%",L&&(w.find("tbody").height()>g.offsetHeight||"scroll"==n.css("overflow-y"))&&(C.width=K(w.outerWidth()-b)),h=w.outerWidth()): +""!==d&&(C.width=K(d),h=w.outerWidth());ca(Ba,fa);ca(function(D){var W=z.getComputedStyle?z.getComputedStyle(D).width:K(l(D).width());H.push(D.innerHTML);O.push(W)},fa);ca(function(D,W){D.style.width=O[W]},x);l(fa).css("height",0);G&&(ca(Ba,ba),ca(function(D){ea.push(D.innerHTML);I.push(K(l(D).css("width")))},ba),ca(function(D,W){D.style.width=I[W]},la),l(ba).height(0));ca(function(D,W){D.innerHTML='
'+H[W]+"
";D.childNodes[0].style.height="0";D.childNodes[0].style.overflow= +"hidden";D.style.width=O[W]},fa);G&&ca(function(D,W){D.innerHTML='
'+ea[W]+"
";D.childNodes[0].style.height="0";D.childNodes[0].style.overflow="hidden";D.style.width=I[W]},ba);Math.round(w.outerWidth())g.offsetHeight||"scroll"==n.css("overflow-y")?h+b:h,L&&(g.scrollHeight>g.offsetHeight||"scroll"==n.css("overflow-y"))&&(C.width=K(la-b)),""!==c&&""===d||da(a,1,"Possible column misalignment",6)):la="100%";p.width=K(la);f.width=K(la); +G&&(a.nScrollFoot.style.width=K(la));!e&&L&&(p.height=K(r.offsetHeight+b));c=w.outerWidth();m[0].style.width=K(c);k.width=K(c);d=w.height()>g.clientHeight||"scroll"==n.css("overflow-y");e="padding"+(aa.bScrollbarLeft?"Left":"Right");k[e]=d?b+"px":"0px";G&&(v[0].style.width=K(c),t[0].style.width=K(c),t[0].style[e]=d?b+"px":"0px");w.children("colgroup").insertBefore(w.children("thead"));n.trigger("scroll");!a.bSorted&&!a.bFiltered||a._drawHold||(g.scrollTop=0)}}function ca(a,b,c){for(var d=0,e=0,h= +b.length,f,g;e").appendTo(g.find("tbody"));g.find("thead, tfoot").remove();g.append(l(a.nTHead).clone()).append(l(a.nTFoot).clone());g.find("tfoot th, tfoot td").css("width","");m=Na(a,g.find("thead")[0]);for(v=0;v").css({width:w.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(v=0;v").css(h||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(g).appendTo(p);h&&f?g.width(f):h?(g.css("width","auto"),g.removeAttr("width"),g.width()").css("width",K(a)).appendTo(b||A.body);b=a[0].offsetWidth;a.remove();return b}function $b(a,b){var c= +ac(a,b);if(0>c)return null;var d=a.aoData[c];return d.nTr?d.anCells[b]:l("
").html(T(a,c,b,"display"))[0]}function ac(a,b){for(var c,d=-1,e=-1,h=0,f=a.aoData.length;hd&&(d=c.length,e=h);return e}function K(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function pa(a){var b=[],c=a.aoColumns;var d=a.aaSortingFixed;var e=l.isPlainObject(d);var h=[];var f=function(n){n.length&& +!Array.isArray(n[0])?h.push(n):l.merge(h,n)};Array.isArray(d)&&f(d);e&&d.pre&&f(d.pre);f(a.aaSorting);e&&d.post&&f(d.post);for(a=0;aG?1:0;if(0!==C)return"asc"===r.dir?C:-C}C=c[n];G=c[p];return CG?1:0}):f.sort(function(n,p){var t,v=g.length,x=e[n]._aSortData,w=e[p]._aSortData;for(t=0;tG?1:0})}a.bSorted=!0}function cc(a){var b=a.aoColumns,c=pa(a);a=a.oLanguage.oAria;for(var d=0,e=b.length;d/g,"");var k=h.nTh;k.removeAttribute("aria-sort");h.bSortable&&(0e?e+1:3))}e= +0;for(h=d.length;ee?e+1:3))}a.aLastSort=d}function bc(a,b){var c=a.aoColumns[b],d=u.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,ua(a,b)));for(var h,f=u.ext.type.order[c.sType+"-pre"],g=0,k=a.aoData.length;g=e.length?[0,m[1]]:m)}));b.search!==q&&l.extend(a.oPreviousSearch,Wb(b.search));if(b.columns){f=0;for(d=b.columns.length;f=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function gb(a,b){a=a.renderer;var c=u.ext.renderer[b];return l.isPlainObject(a)&&a[b]?c[a[b]]||c._:"string"===typeof a?c[a]||c._:c._}function Q(a){return a.oFeatures.bServerSide? +"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function Da(a,b){var c=ec.numbers_length,d=Math.floor(c/2);b<=c?a=qa(0,b):a<=d?(a=qa(0,c-2),a.push("ellipsis"),a.push(b-1)):(a>=b-1-d?a=qa(b-(c-2),b):(a=qa(a-d+2,a+d-1),a.push("ellipsis"),a.push(b-1)),a.splice(0,0,"ellipsis"),a.splice(0,0,0));a.DT_el="span";return a}function Xa(a){l.each({num:function(b){return Ua(b,a)},"num-fmt":function(b){return Ua(b,a,rb)},"html-num":function(b){return Ua(b,a,Va)},"html-num-fmt":function(b){return Ua(b,a,Va,rb)}},function(b, +c){M.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(M.type.search[b+a]=M.type.search.html)})}function fc(a){return function(){var b=[Ta(this[u.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return u.ext.internal[a].apply(this,b)}}var u=function(a,b){if(this instanceof u)return l(a).DataTable(b);b=a;this.$=function(f,g){return this.api(!0).$(f,g)};this._=function(f,g){return this.api(!0).rows(f,g).data()};this.api=function(f){return f?new B(Ta(this[M.iApiIndex])):new B(this)};this.fnAddData= +function(f,g){var k=this.api(!0);f=Array.isArray(f)&&(Array.isArray(f[0])||l.isPlainObject(f[0]))?k.rows.add(f):k.row.add(f);(g===q||g)&&k.draw();return f.flatten().toArray()};this.fnAdjustColumnSizing=function(f){var g=this.api(!0).columns.adjust(),k=g.settings()[0],m=k.oScroll;f===q||f?g.draw(!1):(""!==m.sX||""!==m.sY)&&Ha(k)};this.fnClearTable=function(f){var g=this.api(!0).clear();(f===q||f)&&g.draw()};this.fnClose=function(f){this.api(!0).row(f).child.hide()};this.fnDeleteRow=function(f,g,k){var m= +this.api(!0);f=m.rows(f);var n=f.settings()[0],p=n.aoData[f[0][0]];f.remove();g&&g.call(this,n,p);(k===q||k)&&m.draw();return p};this.fnDestroy=function(f){this.api(!0).destroy(f)};this.fnDraw=function(f){this.api(!0).draw(f)};this.fnFilter=function(f,g,k,m,n,p){n=this.api(!0);null===g||g===q?n.search(f,k,m,p):n.column(g).search(f,k,m,p);n.draw()};this.fnGetData=function(f,g){var k=this.api(!0);if(f!==q){var m=f.nodeName?f.nodeName.toLowerCase():"";return g!==q||"td"==m||"th"==m?k.cell(f,g).data(): +k.row(f).data()||null}return k.data().toArray()};this.fnGetNodes=function(f){var g=this.api(!0);return f!==q?g.row(f).node():g.rows().nodes().flatten().toArray()};this.fnGetPosition=function(f){var g=this.api(!0),k=f.nodeName.toUpperCase();return"TR"==k?g.row(f).index():"TD"==k||"TH"==k?(f=g.cell(f).index(),[f.row,f.columnVisible,f.column]):null};this.fnIsOpen=function(f){return this.api(!0).row(f).child.isShown()};this.fnOpen=function(f,g,k){return this.api(!0).row(f).child(g,k).show().child()[0]}; +this.fnPageChange=function(f,g){f=this.api(!0).page(f);(g===q||g)&&f.draw(!1)};this.fnSetColumnVis=function(f,g,k){f=this.api(!0).column(f).visible(g);(k===q||k)&&f.columns.adjust().draw()};this.fnSettings=function(){return Ta(this[M.iApiIndex])};this.fnSort=function(f){this.api(!0).order(f).draw()};this.fnSortListener=function(f,g,k){this.api(!0).order.listener(f,g,k)};this.fnUpdate=function(f,g,k,m,n){var p=this.api(!0);k===q||null===k?p.row(g).data(f):p.cell(g,k).data(f);(n===q||n)&&p.columns.adjust(); +(m===q||m)&&p.draw();return 0};this.fnVersionCheck=M.fnVersionCheck;var c=this,d=b===q,e=this.length;d&&(b={});this.oApi=this.internal=M.internal;for(var h in u.ext.internal)h&&(this[h]=fc(h));this.each(function(){var f={},g=1").appendTo(t));r.nTHead=H[0];var ea=t.children("tbody");0===ea.length&&(ea=l("